[Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-530] RIC Subscription Modification Response
[o-du/l2.git] / src / du_app / du_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 #include "common_def.h"
19 #include "du_tmr.h"
20 #include "lrg.h"
21 #include "lkw.x"
22 #include "lrg.x"
23 #include "legtp.h"
24 #include "du_app_mac_inf.h"
25 #include "du_app_rlc_inf.h"
26 #include "du_e2ap_mgr.h"
27 #include "du_e2ap_msg_hdl.h"
28 #include "du_cfg.h"
29 #include "du_sctp.h"
30 #include "du_mgr.h"
31 #include "du_mgr_main.h"
32 #include "du_msg_hdl.h"
33 #include "du_utils.h"
34 #include "GlobalE2node-gNB-ID.h"
35 #include "ProtocolIE-FieldE2.h"
36 #include "E2setupRequest.h"
37 #include "InitiatingMessageE2.h"
38 #include "SuccessfulOutcomeE2.h"
39 #include "UnsuccessfulOutcomeE2.h"
40 #include "E2AP-PDU.h"
41 #include "odu_common_codec.h"
42 #include "E2nodeComponentInterfaceF1.h"
43 #include "E2setupRequest.h"
44 #include "du_e2_conversions.h"
45 #include "E2SM-KPM-RANfunction-Description.h"
46 #include "RANfunction-Name.h"
47 #include "RIC-EventTriggerStyle-Item.h"
48 #include "RIC-ReportStyle-Item.h"
49 #include "MeasurementInfo-Action-Item.h"
50 #include "E2SM-KPM-EventTriggerDefinition.h"
51 #include "E2SM-KPM-EventTriggerDefinition-Format1.h"
52 #include "E2SM-KPM-ActionDefinition.h"
53 #include "E2SM-KPM-ActionDefinition-Format1.h"
54 #include "MeasurementInfoItem.h"
55 #include "RANfunctionsIDcause-List.h"
56 #include "MeasurementRecord.h"
57 #include "MeasurementData.h"
58 #include "MeasurementRecordItem.h"
59 #include "MeasurementDataItem.h"
60 #include "E2SM-KPM-IndicationMessage-Format1.h"
61 #include "E2SM-KPM-IndicationMessage.h"
62 #include "E2SM-KPM-IndicationHeader.h"
63 #include "E2SM-KPM-IndicationHeader-Format1.h"
64 #include "LabelInfoItem.h"
65
66 /*******************************************************************
67  *
68  * @brief Fill E2 Failure Cause
69  *
70  * @details
71  *
72  *    Function : fillE2Cause
73  *
74  *    Functionality: Fill E2 Failure Cause
75  *
76  * @params[in] E2 Cause pointer to be filled in
77  *             E2 Cause to be filled from 
78  * @return void
79  *
80  ******************************************************************/
81 void fillE2Cause(CauseE2_t *e2Cause, E2FailureCause failureCause)
82 {
83    e2Cause->present = failureCause.causeType;
84    switch(e2Cause->present)
85    {
86       case CauseE2_PR_ricRequest:
87          {
88             e2Cause->choice.ricRequest = failureCause.cause;
89             break;
90          }
91       case CauseE2_PR_ricService:
92          {
93             e2Cause->choice.ricService = failureCause.cause;
94             break;
95          }
96       case CauseE2_PR_e2Node:
97          {
98             e2Cause->choice.e2Node = failureCause.cause;
99             break;
100          }
101       case CauseE2_PR_transport:
102          {
103             e2Cause->choice.transport = failureCause.cause;
104             break;
105          }
106       case CauseE2_PR_protocol:
107          {
108             e2Cause->choice.protocol = failureCause.cause;
109             break;
110          }
111       case CauseE2_PR_misc:
112          {
113             e2Cause->choice.misc = failureCause.cause;
114             break;
115          }
116       case CauseE2_PR_NOTHING:
117       default:
118          break;
119    }
120 }
121
122 /*******************************************************************
123  *
124  * @brief Printing Type and Cause of failure
125  *
126  * @details
127  *
128  *    Function : printE2ErrorCause
129  *
130  *    Functionality: Printing Type and Cause of failure
131  *
132  * @params[in] E2 Cause
133  * @return void
134  *
135  ******************************************************************/
136 void printE2ErrorCause(CauseE2_t *cause)
137 {
138    switch(cause->present)
139    {
140       case CauseE2_PR_ricRequest:
141          {
142             DU_LOG("Failure_Type [%s] Cause [%ld]", "RIC_Request", cause->choice.ricRequest);
143             break;
144          }
145       case CauseE2_PR_ricService:
146          {
147             DU_LOG("Failure_Type [%s] Cause [%ld]", "RIC_Service", cause->choice.ricService);
148             break;
149          }
150       case CauseE2_PR_e2Node:
151          {
152             DU_LOG("Failure_Type [%s] Cause [%ld]", "E2_Node", cause->choice.e2Node);
153             break;
154          }
155       case CauseE2_PR_transport:
156          {
157             DU_LOG("Failure_Type [%s] Cause [%ld]", "Transport", cause->choice.transport);
158             break;
159          }
160       case CauseE2_PR_protocol:
161          {
162             DU_LOG("Failure_Type [%s] Cause [%ld]", "Protocol", cause->choice.protocol);
163             break;
164          }
165       case CauseE2_PR_misc:
166          {
167             DU_LOG("Failure_Type [%s] Cause [%ld]", "Miscellaneous", cause->choice.misc);
168             break;
169          }
170       default:
171          {
172             DU_LOG("Failure_Type and Cause unknown");
173             break;
174          }
175    }
176 }
177
178 /*******************************************************************
179  *
180  * @brief Deallocate the memory allocated for E2 Removal Failure
181  *
182  * @details
183  *
184  *    Function : FreeE2RemovalFailure
185  *
186  *    Functionality:
187  *       - freeing the memory allocated for E2RemovalFailure
188  *
189  * @params[in] E2AP_PDU_t *e2apMsg
190  * @return ROK     - success
191  *         RFAILED - failure
192  *
193  * ****************************************************************/
194 void FreeE2RemovalFailure(E2AP_PDU_t *e2apMsg)
195 {
196    uint8_t ieIdx =0;
197    E2RemovalFailure_t *e2RemovalFailure=NULLP;
198
199    if(e2apMsg != NULLP)
200    {
201       if(e2apMsg->choice.unsuccessfulOutcome != NULLP)
202       {
203          e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure;
204          if(e2RemovalFailure->protocolIEs.list.array)
205          {
206             for(ieIdx=0; ieIdx < e2RemovalFailure->protocolIEs.list.count; ieIdx++)
207             {
208                if(e2RemovalFailure->protocolIEs.list.array[ieIdx])
209                {
210                   DU_FREE(e2RemovalFailure->protocolIEs.list.array[ieIdx], sizeof(E2RemovalFailureIEs_t));
211                }
212             }
213             DU_FREE(e2RemovalFailure->protocolIEs.list.array, e2RemovalFailure->protocolIEs.list.size);
214          }
215          DU_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
216       }
217       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
218    }
219 }
220
221 /*******************************************************************
222  *
223  * @brief Buld and send the E2 Removal Failure msg
224  *
225  * @details
226  *
227  *    Function : BuildAndSendE2RemovalFailure
228  *
229  *    Functionality:
230  *         - Buld and send the E2 Removal Failure Message
231  * @params[in] Trans Id 
232  * @return ROK     - success
233  *         RFAILED - failure
234  *
235  * ****************************************************************/
236
237 uint8_t BuildAndSendRemovalFailure(uint16_t transId, E2FailureCause failureCause)
238 {
239    uint8_t           ieIdx = 0, elementCnt = 0;
240    uint8_t           ret = RFAILED;
241    E2AP_PDU_t        *e2apMsg = NULLP;
242    E2RemovalFailure_t *e2RemovalFailure=NULLP;
243    asn_enc_rval_t    encRetVal;       /* Encoder return value */
244
245    DU_LOG("\nINFO   -->  E2AP : Building E2 Removal Failure Message\n");
246    do
247    {
248       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
249       if(e2apMsg == NULLP)
250       {
251          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
252          break;
253       }
254       e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome;
255
256       DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
257       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
258       {
259          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
260          break;
261       }
262
263       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2removal;
264       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
265       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2RemovalFailure;
266       e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure;
267
268       elementCnt = 2;
269       e2RemovalFailure->protocolIEs.list.count = elementCnt;
270       e2RemovalFailure->protocolIEs.list.size = elementCnt * sizeof(E2RemovalFailureIEs_t *);
271       DU_ALLOC(e2RemovalFailure->protocolIEs.list.array, e2RemovalFailure->protocolIEs.list.size);
272       if(!e2RemovalFailure->protocolIEs.list.array)
273       {
274          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
275          break;
276       }
277
278       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
279       {
280          DU_ALLOC(e2RemovalFailure->protocolIEs.list.array[ieIdx], sizeof(E2RemovalFailureIEs_t));
281          if(!e2RemovalFailure->protocolIEs.list.array[ieIdx])
282          {
283             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
284             break;
285          }
286       }
287       if(ieIdx < elementCnt)
288          break;
289
290       ieIdx = 0;
291       e2RemovalFailure->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
292       e2RemovalFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
293       e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.present = E2RemovalFailureIEs__value_PR_TransactionID;
294       e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
295
296       /* Cause */
297       ieIdx++;
298       e2RemovalFailure->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
299       e2RemovalFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
300       e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2;
301       fillE2Cause(&e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, failureCause);
302       
303       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
304
305       memset(encBuf, 0, ENC_BUF_MAX_LEN);
306       encBufSize = 0;
307       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
308       if(encRetVal.encoded == ENCODE_FAIL)
309       {
310          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 removal failure structure (at %s)\n",\
311                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
312          break;
313       }
314       else
315       {
316          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Removal Failure \n");
317          for(int i=0; i< encBufSize; i++)
318          {
319             DU_LOG("%x",encBuf[i]);
320          }
321       }
322
323       /* Sending msg */
324       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
325       {
326          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Removal Failure");
327          break;
328       }
329
330       ret = ROK;
331       break;
332    }while(true);
333
334    FreeE2RemovalFailure(e2apMsg);
335    return ret;
336 }
337
338 /*******************************************************************
339  *
340  * @brief Deallocate the memory allocated for E2 Removal Response
341  *
342  * @details
343  *
344  *    Function : FreeE2RemovalResponse
345  *
346  *    Functionality:
347  *       - freeing the memory allocated for E2RemovalResponse
348  *
349  * @params[in] E2AP_PDU_t *e2apMsg
350  * @return ROK     - success
351  *         RFAILED - failure
352  *
353  * ****************************************************************/
354 void FreeE2RemovalResponse(E2AP_PDU_t *e2apMsg)
355 {
356    uint8_t ieIdx =0;
357    E2RemovalResponse_t *e2RemovalResponse=NULLP;
358
359    if(e2apMsg != NULLP)
360    {
361       if(e2apMsg->choice.successfulOutcome != NULLP)
362       {
363          e2RemovalResponse = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse;
364          if(e2RemovalResponse->protocolIEs.list.array)
365          {
366             for(ieIdx=0; ieIdx < e2RemovalResponse->protocolIEs.list.count; ieIdx++)
367             {
368                if(e2RemovalResponse->protocolIEs.list.array[ieIdx])
369                {
370                   DU_FREE(e2RemovalResponse->protocolIEs.list.array[ieIdx], sizeof(E2RemovalResponseIEs_t));
371                }
372             }
373             DU_FREE(e2RemovalResponse->protocolIEs.list.array, e2RemovalResponse->protocolIEs.list.size);
374          }
375          DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
376       }
377       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
378    }
379 }
380
381 /*******************************************************************
382  *
383  * @brief Buld and send the E2 Removal Response msg
384  *
385  * @details
386  *
387  *    Function : BuildAndSendE2RemovalResponse
388  *
389  *    Functionality:
390  *         - Buld and send the E2 Removal Response Message
391  * @params[in] Trans Id 
392  * @return ROK     - success
393  *         RFAILED - failure
394  *
395  * ****************************************************************/
396 uint8_t BuildAndSendRemovalResponse(uint16_t transId)
397 {
398    uint8_t           ieIdx = 0, elementCnt = 0;
399    uint8_t           ret = RFAILED;
400    E2AP_PDU_t        *e2apMsg = NULLP;
401    E2RemovalResponse_t *e2RemovalResponse=NULLP;
402    asn_enc_rval_t    encRetVal;       /* Encoder return value */
403
404    DU_LOG("\nINFO   -->  E2AP : Building E2 Removal Response Message\n");
405    do
406    {
407       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
408       if(e2apMsg == NULLP)
409       {
410          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
411          break;
412       }
413       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
414
415       DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
416       if(e2apMsg->choice.successfulOutcome == NULLP)
417       {
418          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
419          break;
420       }
421
422       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2removal;
423       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
424       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2RemovalResponse;
425       e2RemovalResponse = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse;
426
427       elementCnt = 1;
428       e2RemovalResponse->protocolIEs.list.count = elementCnt;
429       e2RemovalResponse->protocolIEs.list.size = elementCnt * sizeof(E2RemovalResponseIEs_t *);
430       DU_ALLOC(e2RemovalResponse->protocolIEs.list.array, e2RemovalResponse->protocolIEs.list.size);
431       if(!e2RemovalResponse->protocolIEs.list.array)
432       {
433          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
434          break;
435       }
436
437       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
438       {
439          DU_ALLOC(e2RemovalResponse->protocolIEs.list.array[ieIdx], sizeof(E2RemovalResponseIEs_t));
440          if(!e2RemovalResponse->protocolIEs.list.array[ieIdx])
441          {
442             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
443             break;
444          }
445       }
446       if(ieIdx < elementCnt)
447          break;
448
449       ieIdx = 0;
450       e2RemovalResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
451       e2RemovalResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
452       e2RemovalResponse->protocolIEs.list.array[ieIdx]->value.present = E2RemovalResponseIEs__value_PR_TransactionID;
453       e2RemovalResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
454
455       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
456
457       memset(encBuf, 0, ENC_BUF_MAX_LEN);
458       encBufSize = 0;
459       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
460       if(encRetVal.encoded == ENCODE_FAIL)
461       {
462          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 removal response structure (at %s)\n",\
463                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
464          break;
465       }
466       else
467       {
468          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Removal Response \n");
469          for(int i=0; i< encBufSize; i++)
470          {
471             DU_LOG("%x",encBuf[i]);
472          }
473       }
474
475       /* Sending msg */
476       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
477       {
478          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Removal Response");
479          break;
480       }
481
482       ret = ROK;
483       break;
484    }while(true);
485
486    FreeE2RemovalResponse(e2apMsg);
487    return ret;
488 }
489
490 /******************************************************************
491  *
492  * @brief Deallocation of memory allocated by aper decoder for Removal req
493  *
494  * @details
495  *
496  *    Function : freeAperDecodingOfE2RemovalReq
497  *
498  *    Functionality: Deallocation of memory allocated by aper decoder for
499  *    Removal req
500  *
501  * @params[in] Pointer to removalReq
502  * @return void
503  *
504  * ****************************************************************/
505 void freeAperDecodingOfE2RemovalReq(E2RemovalRequest_t *removalReq)
506 {
507    uint8_t arrIdx=0;
508
509    if(removalReq)
510    {
511       if(removalReq->protocolIEs.list.array)
512       {
513          for(arrIdx=0; arrIdx<removalReq->protocolIEs.list.count; arrIdx++)
514          {
515             if(removalReq->protocolIEs.list.array[arrIdx])
516             {
517                free(removalReq->protocolIEs.list.array[arrIdx]);
518             }
519          }
520          free(removalReq->protocolIEs.list.array);
521       }
522    }
523 }
524
525 /*******************************************************************
526  *
527  * @brief Process Removal req received from RIC
528  *
529  * @details
530  *
531  *    Function : procE2RemovalRequest
532  *
533  * Functionality: Process Removal req received from RIC
534  *
535  * @param  E2AP_PDU_t  *e2apMsg
536  * @return void
537  *
538  ******************************************************************/
539
540 void procE2RemovalRequest(E2AP_PDU_t  *e2apMsg)
541 {
542    uint8_t arrIdx =0;
543    uint16_t transId =0;
544    E2FailureCause failureCause;
545    E2RemovalRequest_t *removalReq=NULLP;
546
547    DU_LOG("\nINFO   -->  E2AP : E2 Removal request received");
548    removalReq = &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest;
549    
550    for(arrIdx=0; arrIdx<removalReq->protocolIEs.list.count; arrIdx++)
551    {
552       switch(removalReq->protocolIEs.list.array[arrIdx]->id)
553       {
554          case ProtocolIE_IDE2_id_TransactionID:
555             {
556                transId = removalReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
557                break;
558             }
559          default:
560             {
561                DU_LOG("\nERROR  -->  E2AP : Invalid IE recevied [%d]", transId);
562                break;
563             }
564       }
565    }
566    
567    if(transId>=0 && transId<=255)
568    {
569       if(BuildAndSendRemovalResponse(transId) != ROK)
570       {
571          DU_LOG("\nERROR  -->  E2AP : Failed to build and send Removal response");
572       }
573    }
574    else
575    {
576       failureCause.causeType = E2_PROTOCOL;
577       failureCause.cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE;
578
579       if(BuildAndSendRemovalFailure(transId, failureCause) != ROK)
580       {
581          DU_LOG("\nERROR  -->  E2AP : Failed to build and send Removal response");
582       }
583    }
584    freeAperDecodingOfE2RemovalReq(removalReq);
585 }
586
587 /*******************************************************************
588  *
589  * @brief Free the ErrorIndication Message
590  *
591  * @details
592  *
593  *    Function : FreeRicIndication
594  *
595  * Functionality: Free the ErrorIndication Message
596  *
597  * @params[in] 
598  *    E2AP_PDU is to freed
599  * @return void
600  *
601  ******************************************************************/
602 void FreeErrorIndication(E2AP_PDU_t  *e2apMsg) 
603 {
604    uint8_t arrIdx = 0;
605    ErrorIndicationE2_t *errorIndicationMsg= NULLP;
606
607    if(e2apMsg != NULLP)
608    {
609       if(e2apMsg->choice.initiatingMessage != NULLP)
610       {
611          errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
612          if(errorIndicationMsg!= NULLP)
613          {
614             if(errorIndicationMsg->protocolIEs.list.array != NULLP)
615             {
616                for(arrIdx=0; arrIdx<errorIndicationMsg->protocolIEs.list.count; arrIdx++)
617                {
618                   DU_FREE(errorIndicationMsg->protocolIEs.list.array[arrIdx],sizeof(ErrorIndicationE2_t));
619                }
620                DU_FREE(errorIndicationMsg->protocolIEs.list.array,errorIndicationMsg->protocolIEs.list.size);
621             }
622          }
623          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
624       }
625       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
626    }
627 }
628
629 /*******************************************************************
630  *
631  * @brief Builds and Send the ErrorIndication Message
632  *
633  * @details
634  *
635  *    Function : BuildAndSendErrorIndication
636  *
637  * Functionality:Fills the ErrorIndication Message
638  *
639  * @params[in] 
640  *    Trans id
641  *    Ric req id
642  *    Ran function id
643  *    Cause of failure
644  * @return ROK     - success
645  *         RFAILED - failure
646  *
647  ******************************************************************/
648
649 uint8_t BuildAndSendErrorIndication(int8_t transId, RicRequestId requestId, uint16_t ranFuncId,  E2FailureCause failureCause)
650 {
651    uint8_t elementCnt =0, arrIdx=0, ret = RFAILED;
652    E2AP_PDU_t         *e2apMsg = NULLP;
653    ErrorIndicationE2_t *errorIndicationMsg=NULLP;
654    asn_enc_rval_t     encRetVal;        /* Encoder return value */
655
656    while(true)
657    {
658       DU_LOG("\nINFO   -->  E2AP : Building Error Indication Message\n");
659
660       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
661       if(e2apMsg == NULLP)
662       {
663          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
664          break;
665       }
666
667       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
668       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
669       if(e2apMsg->choice.initiatingMessage == NULLP)
670       {
671          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
672          break;
673       }
674       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_ErrorIndicationE2;
675       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
676       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ErrorIndicationE2;
677
678       errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
679       
680       /* Element count is 2 for TransactionID/RICrequestID and Cause.
681        * If the RAN function id is present, the count will be increased.*/
682       elementCnt = 2;
683       if(ranFuncId>0)
684       {
685          elementCnt++;
686       }
687       
688       errorIndicationMsg->protocolIEs.list.count = elementCnt;
689       errorIndicationMsg->protocolIEs.list.size = elementCnt * sizeof(ErrorIndicationE2_IEs_t*);
690
691       /* Initialize the E2Setup members */
692       DU_ALLOC(errorIndicationMsg->protocolIEs.list.array, errorIndicationMsg->protocolIEs.list.size);
693       if(errorIndicationMsg->protocolIEs.list.array == NULLP)
694       {
695          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements in %s at line %d",__func__, __LINE__);
696          break;
697       }
698       
699       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
700       {
701          DU_ALLOC(errorIndicationMsg->protocolIEs.list.array[arrIdx], sizeof(ErrorIndicationE2_IEs_t));
702          if(errorIndicationMsg->protocolIEs.list.array[arrIdx] == NULLP)
703          {
704             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array [%d] elements in %s at line %d", arrIdx, __func__, __LINE__);
705             break;
706          }
707       }
708       if(arrIdx < elementCnt)
709          break;
710
711       arrIdx = 0;
712
713       if(transId >=0 && transId<=255)
714       {
715          /* TransactionID */
716          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
717          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
718          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_TransactionID;
719          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
720       }
721       else
722       {
723          /* RICrequestID */
724          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RICrequestID;
725          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
726          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RICrequestID;
727          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricRequestorID = requestId.requestorId;
728          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricInstanceID = requestId.instanceId;
729       }
730       
731       if(ranFuncId>0)
732       {
733          /* RAN Function ID */
734          arrIdx++;
735          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionID;
736          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
737          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RANfunctionID;
738          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionID = ranFuncId;
739       }
740
741       /* Cause */
742       arrIdx++;
743       errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
744       errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
745       errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2;
746       fillE2Cause(&errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, failureCause);
747
748       /* Prints the Msg formed */
749       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
750       memset(encBuf, 0, ENC_BUF_MAX_LEN);
751       encBufSize = 0;
752       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
753             encBuf);
754       if(encRetVal.encoded == ENCODE_FAIL)
755       {
756          DU_LOG("\nERROR  -->  E2AP : Could not encode Error Indication Message (at %s)\n",\
757                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
758          break;
759       }
760       else
761       {
762          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for Error Indication Message \n");
763 #ifdef DEBUG_ASN_PRINT
764          for(int i=0; i< encBufSize; i++)
765          {
766             printf("%x",encBuf[i]);
767          } 
768 #endif
769       }
770
771       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
772       {
773          DU_LOG("\nINFO   -->  E2AP : Sending Error Indication Message");      
774
775       }
776       ret = ROK;
777       break;
778    }
779    FreeErrorIndication(e2apMsg);        
780    return ret;
781 }
782
783 /******************************************************************
784  *
785  * @brief Deallocation of memory allocated by aper decoder for e2 
786  * Config Update Failure
787  *
788  * @details
789  *
790  *    Function : freeAperDecodingOfE2Node Config UpdateFailure
791  *
792  *    Functionality: Deallocation of memory allocated by  aper decoder 
793  *    for e2 Config Update Failure
794  *
795  * @params[in] E2nodeConfigurationUpdateFailure_t to be deallocated 
796  * @return void
797  *
798  * ****************************************************************/
799
800 void freeAperDecodingOfE2NodeConfigUpdateFailure(E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdFail)
801 {
802    uint8_t arrIdx =0;
803
804    if(e2NodeCfgUpdFail)
805    {
806       if(e2NodeCfgUpdFail->protocolIEs.list.array)
807       {
808          for(arrIdx=0; arrIdx<e2NodeCfgUpdFail->protocolIEs.list.count; arrIdx++)
809          {
810             if(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx])
811             {
812                free(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]);
813             }
814          }
815          free(e2NodeCfgUpdFail->protocolIEs.list.array);
816       }
817    }
818 }
819
820 /******************************************************************
821  *
822  * @brief Processes E2 Node Config Update Failure sent by RIC
823  *
824  * @details
825  *
826  *    Function : procE2NodeConfigUpdateFailure
827  *
828  *    Functionality: Processes E2 Node Config Update failure sent by RIC
829  *
830  * @params[in] E2AP_PDU_t ASN decoded E2AP message
831  * @return ROK     - success
832  *         RFAILED - failure
833  *
834  * ****************************************************************/
835
836 void procE2NodeConfigUpdateFailure(E2AP_PDU_t *e2apMsg)
837 {
838    uint8_t arrIdx =0, transId =0, timerValue=0;
839    E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdFail=NULL;
840
841    DU_LOG("\nINFO   -->  E2AP : E2 Node Config Update failure received");
842    e2NodeCfgUpdFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2nodeConfigurationUpdateFailure;
843
844    for(arrIdx=0; arrIdx<e2NodeCfgUpdFail->protocolIEs.list.count; arrIdx++)
845    {
846       switch(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]->id)
847       {
848          case ProtocolIE_IDE2_id_TransactionID:
849             {
850                transId = e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
851                if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
852                      (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
853                {
854                   memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
855                }
856                else
857                {
858                   DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
859                }
860                break;
861          }
862          case ProtocolIE_IDE2_id_TimeToWaitE2:
863             {
864                timerValue = convertE2WaitTimerEnumToValue(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
865                if((duChkTmr((PTR)&(duCb.e2apDb), EVENT_E2_NODE_CONFIG_UPDATE_TMR)) == FALSE)
866                {
867                   duStartTmr((PTR)&(duCb.e2apDb), EVENT_E2_NODE_CONFIG_UPDATE_TMR, timerValue);
868                }
869                else
870                {
871                   DU_LOG("\nERROR   -->  E2AP : EVENT_E2_NODE_CONFIG_UPDATE_TMR timer is already running");
872                }
873                break;
874             }
875       }
876    }
877
878    freeAperDecodingOfE2NodeConfigUpdateFailure(e2NodeCfgUpdFail);
879 }
880
881 /*******************************************************************
882  *
883  * @brief Builds Global gNodeB Params
884  *
885  * @details
886  *
887  *    Function : BuildGlobalgNBId
888  *
889  *    Functionality: Building the Plmn and gNB id
890  *
891  * @params[in] GlobalE2node_gNB_ID_t *gNbId
892  * @return ROK     - success
893  *         RFAILED - failure
894  *
895  ******************************************************************/
896
897 uint8_t BuildGlobalgNBId(GlobalE2node_gNB_ID_t *gNbId)
898 {
899    uint8_t unused = 0;
900    uint8_t byteSize = 4;
901    uint8_t gnbId = duCb.gnbId;
902    uint8_t ret = ROK;
903
904    /* fill Global gNB ID Id */
905    gNbId->global_gNB_ID.plmn_id.size = 3 * sizeof(uint8_t);
906    gNbId->global_gNB_ID.plmn_id.buf = NULLP;
907    DU_ALLOC(gNbId->global_gNB_ID.plmn_id.buf , gNbId->global_gNB_ID.plmn_id.size);
908    if(gNbId->global_gNB_ID.plmn_id.buf == NULLP)
909    {
910       DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for Plmn buffer");
911       ret = RFAILED;
912    }
913    else
914    {
915       buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
916             gNbId->global_gNB_ID.plmn_id.buf);
917       gNbId->global_gNB_ID.gnb_id.present = GNB_ID_Choice_PR_gnb_ID;
918       /* Allocate Buffer size */
919       gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size = byteSize * sizeof(uint8_t);
920       gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf = NULLP;
921       DU_ALLOC(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf, \
922             gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size);
923       if(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf == NULLP)
924       {
925          DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for gnb buffer");
926          ret = RFAILED;
927       }
928       else
929       {
930          fillBitString(&gNbId->global_gNB_ID.gnb_id.choice.gnb_ID, unused, byteSize, gnbId);
931       }
932    }
933
934    /* fill gNB-DU ID */ 
935    DU_ALLOC( gNbId->gNB_DU_ID, sizeof(GNB_DU_ID_t));
936    if(gNbId->gNB_DU_ID == NULLP)
937    {
938       DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for gNB_DU_ID ");
939       ret = RFAILED;
940    }
941    else
942    {
943       gNbId->gNB_DU_ID->size = sizeof(uint8_t);
944       DU_ALLOC( gNbId->gNB_DU_ID->buf, sizeof(uint8_t));
945       if(gNbId->gNB_DU_ID->buf)
946       {
947          gNbId->gNB_DU_ID->buf[0] =duCb.e2apDb.e2NodeId;
948       }
949       else
950       {
951          DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for gNB_DU_ID buffer");
952          ret = RFAILED;
953       }
954    }
955
956    return ret;
957 }
958
959 /*******************************************************************
960  *
961  * @brief fill the E2 node config information
962  *
963  * @details
964  *
965  *    Function : fillE2NodeConfig
966  *
967  *    Functionality: fill E2 node config information
968  *
969  * @params[in]  
970  *       Pointer to e2NodeCfg to be filled
971  *       E2 Node Component information
972  *       Type of configuration 
973  * @return ROK     - success
974  *         RFAILED - failure
975  *
976  ******************************************************************/
977
978 uint8_t fillE2NodeConfig(PTR e2NodeCfg, E2NodeComponent *e2NodeComponentInfo, ConfigType configType)
979 {
980    E2NodeConfig *e2NodeConfig=NULLP;
981    E2nodeComponentInterfaceType_t *interfaceType=NULLP;
982    E2nodeComponentID_t *componentID =NULLP;
983    E2nodeComponentConfiguration_t *configuration=NULLP;
984    E2nodeComponentConfigAddition_Item_t *e2NodeAddItem=NULL;
985    E2nodeComponentConfigUpdate_Item_t *e2NodeUpdateItem =NULL;
986    E2nodeComponentConfigRemoval_Item_t *e2NodeRemovalItem=NULL;
987    
988    switch(configType)
989    {
990       case CONFIG_ADD:
991       {
992          e2NodeAddItem = (E2nodeComponentConfigAddition_Item_t*)e2NodeCfg;
993          interfaceType = &e2NodeAddItem->e2nodeComponentInterfaceType;
994          componentID   = &e2NodeAddItem->e2nodeComponentID;
995          configuration = &e2NodeAddItem->e2nodeComponentConfiguration; 
996          e2NodeConfig = e2NodeComponentInfo->addConfiguration;
997          break;
998       }
999       case CONFIG_MOD:
1000       {
1001          e2NodeUpdateItem = (E2nodeComponentConfigUpdate_Item_t *) e2NodeCfg;
1002          interfaceType = &e2NodeUpdateItem->e2nodeComponentInterfaceType;
1003          componentID   = &e2NodeUpdateItem->e2nodeComponentID;
1004          configuration = &e2NodeUpdateItem->e2nodeComponentConfiguration; 
1005          e2NodeConfig = e2NodeComponentInfo->updateConfiguration;
1006          break;
1007       }
1008       case CONFIG_DEL:
1009       {
1010          e2NodeRemovalItem = (E2nodeComponentConfigRemoval_Item_t*) e2NodeCfg;
1011          interfaceType = &e2NodeRemovalItem->e2nodeComponentInterfaceType;
1012          componentID  = &e2NodeRemovalItem->e2nodeComponentID;
1013          break;
1014       }
1015       default:
1016       {
1017          DU_LOG("\nERROR  --> E2AP : Configuration type %d does not supported ", configType);
1018          return RFAILED;
1019       }
1020    }
1021    /* E2nodeComponentInterfaceType */
1022    *interfaceType = convertInterfaceToE2ComponentInterfaceType(e2NodeComponentInfo->interfaceType);
1023    
1024    /*  We now only support the F1 interface out of these interfaces
1025     * (NG,XN,E1,F1,W1,S1,X2), therefore only the F1 component identifier was filled in. */
1026    
1027    if(*interfaceType == F1)
1028    {
1029       /* E2 Node Component ID */
1030       componentID->present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1;
1031       DU_ALLOC(componentID->choice.e2nodeComponentInterfaceTypeF1,sizeof(E2nodeComponentInterfaceF1_t));
1032       if(componentID->choice.e2nodeComponentInterfaceTypeF1 == NULLP)
1033       {
1034          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__);
1035          return RFAILED;
1036       }
1037       componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t);
1038       DU_ALLOC(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
1039             componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
1040
1041       if(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP)
1042       {
1043          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__);
1044          return RFAILED;
1045       }
1046       memcpy(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf, &e2NodeComponentInfo->componentId,\
1047             componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
1048    }
1049   
1050    if(configType == CONFIG_DEL)
1051    {
1052       /* We don't need to fill out the E2 Node Component Request and Response
1053        * information in the case of CONFIG_DEL, therefore returning ROK from here. */
1054       return ROK;
1055    }
1056
1057    /* E2 Node Component Request Part */
1058    if(e2NodeConfig->componentRequestPart)
1059    {
1060       configuration->e2nodeComponentRequestPart.size = e2NodeConfig->reqBufSize ;
1061       DU_ALLOC(configuration->e2nodeComponentRequestPart.buf,\
1062             configuration->e2nodeComponentRequestPart.size);
1063       if(configuration->e2nodeComponentRequestPart.buf == NULLP)
1064       {
1065          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__);
1066          return RFAILED;
1067       }
1068
1069       memcpy(configuration->e2nodeComponentRequestPart.buf,\
1070             e2NodeConfig->componentRequestPart, configuration->\
1071             e2nodeComponentRequestPart.size);
1072    }
1073    else
1074    {
1075       DU_LOG("\nERROR  --> E2AP: componentRequestPart is null ");
1076       return RFAILED;
1077    }
1078
1079    /* E2 Node Component Response Part */
1080    if(e2NodeConfig->componentResponsePart)
1081    {
1082       configuration->e2nodeComponentResponsePart.size = e2NodeConfig->rspBufSize; 
1083       DU_ALLOC(configuration->e2nodeComponentResponsePart.buf, configuration->e2nodeComponentResponsePart.size);
1084       if(configuration->e2nodeComponentResponsePart.buf == NULLP)
1085       {
1086          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__);
1087          return RFAILED;
1088       }
1089       memcpy(configuration->e2nodeComponentResponsePart.buf,  e2NodeConfig->componentResponsePart, configuration->\
1090             e2nodeComponentResponsePart.size);
1091    }
1092    else
1093    {
1094       DU_LOG("\nERROR  --> E2AP: componentResponsePart is null");
1095       return RFAILED;
1096    }
1097    
1098    return ROK;
1099 }
1100
1101 /*******************************************************************
1102  *
1103  * @brief Builds E2 node config addition list 
1104  *
1105  * @details
1106  *
1107  *    Function : BuildE2NodeConfigAddList
1108  *
1109  *    Functionality: Building E2 node config addition list
1110  *
1111  * @params[in] 
1112  *    E2nodeComponentConfigAddition_List_t to be filled
1113  *    Procedure Code
1114  *    Count of E2 node to be added in the list    
1115  *    Received list of E2 node configuration
1116  *
1117  * @return ROK     - success
1118  *         RFAILED - failure
1119  *
1120  ******************************************************************/
1121
1122 uint8_t BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAddList, uint8_t procedureCode, uint16_t count, E2NodeConfigItem *e2NodeList)
1123 {
1124    uint8_t arrIdx = 0;
1125    CmLList         *node =NULL;
1126    E2NodeComponent *e2NodeComponentInfo=NULL;
1127    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItemIe=NULL;
1128    E2nodeComponentConfigAddition_Item_t *e2NodeAddItem=NULL;
1129    
1130
1131    /* For ProcedureCodeE2_id_E2setup, the number of E2 node configuration list items is
1132     * equal to the number of E2 node configuration entries stored in the database.
1133     * For any other procedure, the E2 node configuration list count is equal
1134     * to the count of E2 node configuration obtained from the function's caller */
1135
1136    if(procedureCode == ProcedureCodeE2_id_E2setup)
1137       e2NodeAddList->list.count = duCb.e2apDb.e2NodeComponentList.count;
1138    else
1139       e2NodeAddList->list.count = count;
1140
1141    e2NodeAddList->list.size = e2NodeAddList->list.count * sizeof(E2nodeComponentConfigAddition_ItemIEs_t *);
1142    DU_ALLOC(e2NodeAddList->list.array, e2NodeAddList->list.size);
1143    if(e2NodeAddList->list.array == NULLP)
1144    {
1145        DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
1146        return RFAILED;
1147    }
1148
1149    for(arrIdx = 0; arrIdx< e2NodeAddList->list.count; arrIdx++)
1150    {
1151       DU_ALLOC(e2NodeAddList->list.array[arrIdx], sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
1152       if(e2NodeAddList->list.array[arrIdx] == NULLP)
1153       {
1154          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
1155          return RFAILED;
1156       }
1157       
1158       if(procedureCode == ProcedureCodeE2_id_E2setup)
1159       {
1160          /* Getting all of the E2 node configuration's information from DuCb one by one*/
1161          if(arrIdx == 0)
1162          {
1163             CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node); 
1164          }
1165          else
1166          {
1167             node = node->next;
1168          }
1169          if(!node)
1170          {
1171             DU_LOG("\nERROR  --> E2AP : E2 node component list node is null");
1172             return RFAILED;
1173          }
1174          e2NodeComponentInfo = (E2NodeComponent*)node->node;
1175       }
1176       else
1177       {
1178          /* Getting only those E2 node configuration from DuCb whose interface
1179           * and action type is present in the received array */
1180          e2NodeComponentInfo = fetchE2NodeComponentInfo(e2NodeList[arrIdx].interface, e2NodeList[arrIdx].componentId, &node);
1181       }
1182       
1183       if(!e2NodeComponentInfo)
1184       {
1185          DU_LOG("\nERROR  --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__);
1186          return RFAILED;
1187       }
1188
1189       e2NodeAddItemIe = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[arrIdx];
1190       e2NodeAddItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition_Item;
1191       e2NodeAddItemIe->criticality = CriticalityE2_reject;
1192       e2NodeAddItemIe->value.present = E2nodeComponentConfigAddition_ItemIEs__value_PR_E2nodeComponentConfigAddition_Item;
1193       e2NodeAddItem = &e2NodeAddItemIe->value.choice.E2nodeComponentConfigAddition_Item;
1194       if(fillE2NodeConfig((PTR)e2NodeAddItem, e2NodeComponentInfo, CONFIG_ADD) != ROK)
1195       {
1196          DU_LOG("\nERROR  --> E2AP : Failed to fill the E2 node configuration");
1197          return RFAILED;
1198       }
1199    }
1200    return ROK;
1201 }
1202
1203 /*******************************************************************
1204  *
1205  * @brief Builds E2 node config update list 
1206  *
1207  * @details
1208  *
1209  *    Function : BuildE2NodeConfigUpdateList
1210  *
1211  *    Functionality: Building E2 node config update list
1212  *
1213  * @params[in] 
1214  *    E2nodeComponentConfigUpdate_List_t to be filled
1215  *    Count of E2 node to be update in the list    
1216  *    Received list of E2 node configuration
1217  *
1218  * @return ROK     - success
1219  *         RFAILED - failure
1220  *
1221  ******************************************************************/
1222
1223 uint8_t BuildE2NodeConfigUpdateList(E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList, uint16_t count,  E2NodeConfigItem *updateE2Node)
1224 {
1225    uint8_t arrIdx = 0;
1226    CmLList         *node =NULL;
1227    E2NodeComponent *e2NodeComponentInfo =NULL;
1228    E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItemIe =NULL;
1229    E2nodeComponentConfigUpdate_Item_t *e2NodeUpdateItem =NULL;
1230
1231    e2NodeUpdateList->list.count = count;
1232    e2NodeUpdateList->list.size = e2NodeUpdateList->list.count * sizeof(E2nodeComponentConfigUpdate_ItemIEs_t *);
1233    DU_ALLOC(e2NodeUpdateList->list.array, e2NodeUpdateList->list.size);
1234    if(e2NodeUpdateList->list.array == NULLP)
1235    {
1236       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigUpdateList %d",__LINE__);
1237       return RFAILED;
1238    }
1239
1240    for(arrIdx = 0; arrIdx< e2NodeUpdateList->list.count; arrIdx++)
1241    {
1242       DU_ALLOC(e2NodeUpdateList->list.array[arrIdx], sizeof(E2nodeComponentConfigUpdate_ItemIEs_t));
1243       if(e2NodeUpdateList->list.array[arrIdx] == NULLP)
1244       {
1245          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigUpdateList %d",__LINE__);
1246          return RFAILED;
1247       }
1248
1249       e2NodeComponentInfo= fetchE2NodeComponentInfo(updateE2Node[arrIdx].interface, updateE2Node[arrIdx].componentId, &node);
1250       if(!e2NodeComponentInfo)
1251       {
1252          DU_LOG("\nERROR  --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__);
1253          return RFAILED;
1254       }
1255
1256       e2NodeUpdateItemIe = (E2nodeComponentConfigUpdate_ItemIEs_t *) e2NodeUpdateList->list.array[arrIdx];
1257       e2NodeUpdateItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate_Item;
1258       e2NodeUpdateItemIe->criticality = CriticalityE2_reject;
1259       e2NodeUpdateItemIe->value.present = E2nodeComponentConfigUpdate_ItemIEs__value_PR_E2nodeComponentConfigUpdate_Item;
1260       e2NodeUpdateItem = &e2NodeUpdateItemIe->value.choice.E2nodeComponentConfigUpdate_Item;
1261
1262       if(fillE2NodeConfig((PTR)e2NodeUpdateItem, e2NodeComponentInfo, CONFIG_MOD) != ROK)
1263       {
1264          DU_LOG("\nERROR  --> E2AP : Failed to fill the E2 node configuration");
1265          return RFAILED;
1266       }
1267
1268    }
1269    return ROK;
1270
1271 }
1272
1273
1274 /*******************************************************************
1275  *
1276  * @brief Builds E2 node config remove list 
1277  *
1278  * @details
1279  *
1280  *    Function :BuildE2NodeConfigRemoveList 
1281  *
1282  *    Functionality: Building E2 node config remove list
1283  *
1284  * @params[in] 
1285  *    E2nodeComponentConfigRemoval_List_t to be filled
1286  *    Count of E2 node to be remove in the list    
1287  *    Received list of E2 node configuration
1288  * @return ROK     - success
1289  *         RFAILED - failure
1290  *
1291  ******************************************************************/
1292
1293 uint8_t BuildE2NodeConfigRemoveList(E2nodeComponentConfigRemoval_List_t *e2NodeRemoveList, uint16_t count,  E2NodeConfigItem *updateE2Node)
1294 {
1295    uint8_t arrIdx = 0;
1296    CmLList         *node=NULL;
1297    E2NodeComponent *e2NodeComponentInfo=NULL;
1298    E2nodeComponentConfigRemoval_ItemIEs_t *e2NodeRemovalItemIe=NULL;
1299    E2nodeComponentConfigRemoval_Item_t *e2NodeRemovalItem=NULL;
1300
1301    e2NodeRemoveList->list.count = count;
1302    e2NodeRemoveList->list.size = e2NodeRemoveList->list.count * sizeof(E2nodeComponentConfigRemoval_ItemIEs_t *);
1303    DU_ALLOC(e2NodeRemoveList->list.array, e2NodeRemoveList->list.size);
1304    if(e2NodeRemoveList->list.array == NULLP)
1305    {
1306       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigRemoveList %d",__LINE__);
1307       return RFAILED;
1308    }
1309
1310    for(arrIdx = 0; arrIdx< e2NodeRemoveList->list.count; arrIdx++)
1311    {
1312       DU_ALLOC(e2NodeRemoveList->list.array[arrIdx], sizeof(E2nodeComponentConfigRemoval_ItemIEs_t));
1313       if(e2NodeRemoveList->list.array[arrIdx] == NULLP)
1314       {
1315          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigRemoveList %d",__LINE__);
1316          return RFAILED;
1317       }
1318
1319       e2NodeComponentInfo= fetchE2NodeComponentInfo(updateE2Node[arrIdx].interface,updateE2Node[arrIdx].componentId, &node);
1320       if(!e2NodeComponentInfo)
1321       {
1322          DU_LOG("\nERROR  --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__);
1323          return RFAILED;
1324       }
1325
1326       e2NodeRemovalItemIe = (E2nodeComponentConfigRemoval_ItemIEs_t *) e2NodeRemoveList->list.array[arrIdx];
1327       e2NodeRemovalItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval_Item;
1328       e2NodeRemovalItemIe->criticality = CriticalityE2_reject;
1329       e2NodeRemovalItemIe->value.present = E2nodeComponentConfigRemoval_ItemIEs__value_PR_E2nodeComponentConfigRemoval_Item;
1330       e2NodeRemovalItem = &e2NodeRemovalItemIe->value.choice.E2nodeComponentConfigRemoval_Item;
1331
1332       if(fillE2NodeConfig((PTR)e2NodeRemovalItem, e2NodeComponentInfo, CONFIG_DEL) != ROK)
1333       {
1334          DU_LOG("\nERROR  --> E2AP : Failed to fill the E2 node configuration");
1335          return RFAILED;
1336       }
1337
1338    }
1339    return ROK;
1340 }
1341 /*******************************************************************
1342  *
1343  * @brief deallocation of E2SM_KPM_RANfunction_Description_t
1344  *
1345  * @details
1346  *
1347  *    Function : freeE2smKpmRanFunctionDefinition
1348  *
1349  *    Functionality: deallocation of E2SM_KPM_RANfunction_Description_t
1350  *
1351  * @params[in]  E2SM_KPM_RANfunction_Description_t *ranFunctionDefinition
1352  * @return void
1353  *
1354  ******************************************************************/
1355
1356 void freeE2smKpmRanFunctionDefinition(E2SM_KPM_RANfunction_Description_t *ranFunctionDefinition)
1357 {
1358    MeasurementInfo_Action_Item_t *measInfoList;
1359    uint8_t eventTriggerIdx, reportStyleIdx, measInfoIdx;
1360    RANfunction_Name_t *ranFuncName;
1361    struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle;
1362    struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List *eventTriggerStyle;
1363    if(ranFunctionDefinition)
1364    {
1365       ranFuncName = &ranFunctionDefinition->ranFunction_Name;
1366       /* Free RAN function Name */     
1367       DU_FREE(ranFuncName->ranFunction_ShortName.buf,  ranFuncName->ranFunction_ShortName.size);
1368       DU_FREE(ranFuncName->ranFunction_E2SM_OID.buf, ranFuncName->ranFunction_E2SM_OID.size);
1369       DU_FREE(ranFuncName->ranFunction_Description.buf, ranFuncName->ranFunction_Description.size);
1370
1371       /* Sequence of Event Trigger styles */
1372       eventTriggerStyle = ranFunctionDefinition->ric_EventTriggerStyle_List;
1373       if(eventTriggerStyle)
1374       {
1375          if(eventTriggerStyle->list.array)
1376          {
1377             for(eventTriggerIdx =0;eventTriggerIdx<eventTriggerStyle->list.count; eventTriggerIdx++)
1378             {
1379                if(eventTriggerStyle->list.array[eventTriggerIdx])
1380                {
1381                   DU_FREE(eventTriggerStyle->list.array[eventTriggerIdx]->ric_EventTriggerStyle_Name.buf,\
1382                         eventTriggerStyle->list.array[eventTriggerIdx]->ric_EventTriggerStyle_Name.size);
1383                   DU_FREE(eventTriggerStyle->list.array[eventTriggerIdx], sizeof(RIC_EventTriggerStyle_Item_t ));
1384                }
1385             }
1386             DU_FREE(eventTriggerStyle->list.array, eventTriggerStyle->list.size)
1387          }
1388          DU_FREE(eventTriggerStyle, sizeof(struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List));
1389       }
1390       
1391       /* Sequence of Report styles */
1392       ricReportStyle = ranFunctionDefinition->ric_ReportStyle_List;
1393       if(ricReportStyle)
1394       {
1395          if(ricReportStyle->list.array)
1396          {
1397             for(reportStyleIdx =0;reportStyleIdx<ricReportStyle->list.count; reportStyleIdx++)
1398             {
1399                if(ricReportStyle->list.array[reportStyleIdx])
1400                {
1401                   if(ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.buf)
1402                   {
1403                      DU_FREE(ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.buf,\
1404                            ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.size);
1405                   }
1406                   if(ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.array)
1407                   {
1408                      for(measInfoIdx=0; measInfoIdx<ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.count; \
1409                            measInfoIdx++)
1410                      {
1411                         measInfoList = ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.array[measInfoIdx];
1412                         if(measInfoList)
1413                         {
1414                            DU_FREE(measInfoList->measID, sizeof(long));
1415                            DU_FREE(measInfoList->measName.buf, measInfoList->measName.size);
1416                            DU_FREE(measInfoList,sizeof(MeasurementInfo_Action_Item_t)); 
1417                         }
1418                      }
1419                      DU_FREE(measInfoList,ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.size);
1420                   }
1421                   DU_FREE(ricReportStyle->list.array[reportStyleIdx], sizeof(RIC_ReportStyle_Item_t));
1422                }
1423             }
1424             DU_FREE(ricReportStyle->list.array, ricReportStyle->list.size);
1425          }
1426          DU_FREE(ricReportStyle, sizeof(struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List));
1427       }
1428       DU_FREE(ranFunctionDefinition, sizeof(E2SM_KPM_RANfunction_Description_t)); 
1429    }
1430 }
1431
1432 /*******************************************************************
1433  *
1434  * @brief fill the e2sm ric report style
1435  *
1436  * @details
1437  *
1438  *    Function : fillRicReportStyle
1439  *
1440  *    Functionality: fill the report style
1441  *
1442  * @params[in]   RanFunction *ranFuncDb, struct
1443  * E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle
1444  * @return ROK     - success
1445  *         RFAILED - failure
1446  *
1447  ******************************************************************/
1448 uint8_t fillRicReportStyle(RanFunction *ranFuncDb, struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle)
1449 {
1450    uint8_t styleIdx, measInfoIdx;
1451    MeasurementInfo_Action_List_t *measInfo;
1452    CmLList  *node;
1453    
1454    ricReportStyle->list.count = ranFuncDb->numOfReportStyleSupported;
1455    ricReportStyle->list.size = ricReportStyle->list.count * sizeof(RIC_ReportStyle_Item_t*);
1456    DU_ALLOC(ricReportStyle->list.array, ricReportStyle->list.size);
1457    if(!ricReportStyle->list.array)
1458    {
1459       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for ranFuncDefinition %d",__LINE__);
1460       return RFAILED;
1461    }
1462
1463    for(styleIdx =0;styleIdx<ricReportStyle->list.count; styleIdx++)
1464    {
1465       DU_ALLOC(ricReportStyle->list.array[styleIdx], sizeof(RIC_ReportStyle_Item_t));
1466       if(!ricReportStyle->list.array[styleIdx])
1467       {
1468          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1469          return RFAILED;
1470       }
1471       
1472       /* RIC Report Style Type */
1473       ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Type = ranFuncDb->reportStyleList[styleIdx].reportStyle.styleType;
1474       
1475       /* RIC Report Style Format Type */
1476       ricReportStyle->list.array[styleIdx]->ric_ActionFormat_Type = ranFuncDb->reportStyleList[styleIdx].reportStyle.formatType;
1477       
1478       /* RIC Report Style Name */
1479       ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size = strlen(ranFuncDb->reportStyleList[styleIdx].reportStyle.name);
1480       DU_ALLOC(ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf,\
1481             ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size);
1482       if(!ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf)
1483       {
1484          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1485          return RFAILED;
1486       }
1487       memcpy(ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf, ranFuncDb->reportStyleList[styleIdx].reportStyle.name,\
1488             ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size);
1489
1490       /* RIC Indication Header Format Type*/
1491       ricReportStyle->list.array[styleIdx]->ric_IndicationHeaderFormat_Type = ranFuncDb->ricIndicationHeaderFormat;
1492
1493       /* RIC Indication Message Format Type*/
1494       ricReportStyle->list.array[styleIdx]->ric_IndicationMessageFormat_Type = ranFuncDb->ricIndicationMessageFormat;
1495       
1496       /* Measurement Info Action List */
1497       CmLListCp measInfoList =ranFuncDb->reportStyleList[styleIdx].measurementInfoList;
1498       if(!measInfoList.count)
1499       {
1500          continue;      
1501       }
1502
1503       CM_LLIST_FIRST_NODE(&ranFuncDb->reportStyleList[styleIdx].measurementInfoList, node);
1504       measInfo = &ricReportStyle->list.array[styleIdx]->measInfo_Action_List;
1505
1506       measInfo->list.count = measInfoList.count; 
1507       measInfo->list.size =  measInfoList.count*sizeof(MeasurementInfo_Action_Item_t*);
1508       DU_ALLOC(measInfo->list.array, measInfo->list.size);
1509       if(!measInfo->list.array)
1510       {
1511          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1512          return RFAILED;
1513       }
1514
1515       for(measInfoIdx=0; measInfoIdx<measInfo->list.count; measInfoIdx++)
1516       {
1517          if(!node)
1518          {
1519             DU_LOG("\nERROR  --> E2AP: Measurement info node is null");
1520             return RFAILED;
1521          }
1522
1523          DU_ALLOC(measInfo->list.array[measInfoIdx],sizeof(MeasurementInfo_Action_Item_t));  
1524          if(!measInfo->list.array[measInfoIdx])
1525          {
1526             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1527             return RFAILED;
1528          }
1529          MeasurementInfoForAction *measInfoForAction= (MeasurementInfoForAction*)node->node;
1530          DU_ALLOC(measInfo->list.array[measInfoIdx]->measID, sizeof(long));
1531          if(!measInfo->list.array[measInfoIdx]->measID)
1532          {
1533             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1534             return RFAILED;
1535          }
1536          
1537          memcpy(measInfo->list.array[measInfoIdx]->measID, &measInfoForAction->measurementTypeId,sizeof(long));
1538          measInfo->list.array[measInfoIdx]->measName.size= strlen(measInfoForAction->measurementTypeName);
1539          DU_ALLOC(measInfo->list.array[measInfoIdx]->measName.buf, measInfo->list.array[measInfoIdx]->measName.size);
1540          if(!measInfo->list.array[measInfoIdx]->measName.size)
1541          {
1542             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1543             return RFAILED;
1544          }
1545
1546          memcpy(measInfo->list.array[measInfoIdx]->measName.buf, \
1547                measInfoForAction->measurementTypeName,\
1548                measInfo->list.array[measInfoIdx]->measName.size);
1549          node = node->next;
1550       }
1551
1552    }
1553    return ROK;
1554 }
1555 /*******************************************************************
1556  *
1557  * @brief fill the ric event trigger style
1558  *
1559  * @details
1560  *
1561  *    Function : fillRicEventTriggerStyle
1562  *
1563  *    Functionality: fill the ric event trigger style
1564  *
1565  * @params[in]   
1566  * @return ROK     - success
1567  *         RFAILED - failure
1568  *
1569  ******************************************************************/
1570 uint8_t fillRicEventTriggerStyle(RanFunction *ranFuncDb, struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List *ricEventTriggerStyle)
1571 {
1572    uint8_t styleIdx;
1573
1574    ricEventTriggerStyle->list.count = ranFuncDb->numOfEventTriggerStyleSupported;
1575    ricEventTriggerStyle->list.size = ricEventTriggerStyle->list.count*  sizeof(RIC_EventTriggerStyle_Item_t *);
1576    DU_ALLOC(ricEventTriggerStyle->list.array, ricEventTriggerStyle->list.size);
1577    if(!ricEventTriggerStyle->list.array)
1578    {
1579       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for ric_EventTriggerStyle_List %d",__LINE__);
1580       return RFAILED;
1581    }
1582
1583    for(styleIdx =0;styleIdx<ricEventTriggerStyle->list.count; styleIdx++)
1584    {
1585       DU_ALLOC(ricEventTriggerStyle->list.array[styleIdx], sizeof(RIC_EventTriggerStyle_Item_t ));
1586       if(!ricEventTriggerStyle->list.array[styleIdx])
1587       {
1588          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1589          return RFAILED;
1590       }
1591       ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Type = ranFuncDb->eventTriggerStyleList[styleIdx].styleType;
1592
1593       ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerFormat_Type = ranFuncDb->eventTriggerStyleList[styleIdx].formatType;
1594
1595       ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.size = strlen(ranFuncDb->eventTriggerStyleList[styleIdx].name);
1596       DU_ALLOC(ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.buf,\
1597             ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.size);
1598       if(!ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.buf)
1599       {
1600          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1601          return RFAILED;
1602       }
1603       memcpy(ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.buf,ranFuncDb->eventTriggerStyleList[styleIdx].name,\
1604             ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.size);
1605    
1606    }
1607    return ROK;
1608 }
1609
1610 /*******************************************************************
1611  *
1612  * @brief Builds Ran function item
1613  *
1614  * @details
1615  *
1616  *    Function : BuildRanFunctionItem  
1617  *
1618  *    Functionality: Building RAN function item
1619  *
1620  * @params[in] 
1621  *             RAN function item that has to be filled 
1622  *             Stored RAN Function information
1623  * @return ROK     - success
1624  *         RFAILED - failure
1625  *
1626  ******************************************************************/
1627
1628 uint8_t BuildRanFunctionItem(RANfunction_Item_t *ranFuncItem, RanFunction *ranFuncDb)
1629 {
1630    uint8_t ret =RFAILED;
1631    RANfunctionDefinition_t  *ranFunctionDefinition;
1632    RANfunction_Name_t *ranFuncName;
1633    asn_enc_rval_t encRetVal;
1634    E2SM_KPM_RANfunction_Description_t *ranFuncDefinition;
1635    
1636    while(true)
1637    {
1638       /* RAN function Id*/
1639       ranFuncItem->ranFunctionID = ranFuncDb->id;
1640
1641       /* RAN Function Revision*/
1642       ranFuncItem->ranFunctionRevision = ranFuncDb->revisionCounter;
1643
1644       /* RAN function OID*/
1645       ranFuncItem->ranFunctionOID.size = strlen(ranFuncDb->name.serviceModelOID);
1646       DU_ALLOC(ranFuncItem->ranFunctionOID.buf, ranFuncItem->ranFunctionOID.size);
1647       if(!ranFuncItem->ranFunctionOID.buf)
1648       {
1649          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1650          break;
1651       }
1652       memcpy(ranFuncItem->ranFunctionOID.buf, ranFuncDb->name.serviceModelOID, ranFuncItem->ranFunctionOID.size);
1653
1654       /* RAN function Definition */
1655       DU_ALLOC(ranFuncDefinition, sizeof(E2SM_KPM_RANfunction_Description_t));
1656       if(!ranFuncDefinition)
1657       {
1658          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1659          break;
1660       }
1661
1662       /* RAN function Name */
1663       ranFuncName = &ranFuncDefinition->ranFunction_Name;
1664
1665       /* RAN function ShortName */
1666       ranFuncName->ranFunction_ShortName.size = strlen(ranFuncDb->name.shortName); 
1667       DU_ALLOC(ranFuncName->ranFunction_ShortName.buf,  ranFuncName->ranFunction_ShortName.size);
1668       if(!ranFuncName->ranFunction_ShortName.buf)
1669       {
1670          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1671          break;
1672       }
1673       memcpy(ranFuncName->ranFunction_ShortName.buf, ranFuncDb->name.shortName, strlen(ranFuncDb->name.shortName));
1674
1675       /* RAN function E2SM_OID */
1676       ranFuncName->ranFunction_E2SM_OID.size = strlen(ranFuncDb->name.serviceModelOID);
1677       DU_ALLOC(ranFuncName->ranFunction_E2SM_OID.buf, ranFuncName->ranFunction_E2SM_OID.size);
1678       if(!ranFuncName->ranFunction_E2SM_OID.buf)
1679       {
1680          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1681          break;
1682       }
1683       memcpy(ranFuncName->ranFunction_E2SM_OID.buf, ranFuncDb->name.serviceModelOID, ranFuncName->ranFunction_E2SM_OID.size);
1684
1685       /* RAN Function Name Description */
1686       ranFuncName->ranFunction_Description.size = strlen(ranFuncDb->name.description);
1687       DU_ALLOC(ranFuncName->ranFunction_Description.buf, ranFuncName->ranFunction_Description.size);
1688       if(!ranFuncName->ranFunction_Description.buf)
1689       {
1690          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1691          break;
1692       }
1693       memcpy(ranFuncName->ranFunction_Description.buf, ranFuncDb->name.description, ranFuncName->ranFunction_Description.size);
1694
1695       /* RIC Event Trigger Style List */
1696       DU_ALLOC(ranFuncDefinition->ric_EventTriggerStyle_List, sizeof(struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List));
1697       if(!ranFuncDefinition->ric_EventTriggerStyle_List)
1698       {
1699          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1700          break;
1701       }
1702
1703       if(fillRicEventTriggerStyle(ranFuncDb, ranFuncDefinition->ric_EventTriggerStyle_List)!=ROK)
1704       {
1705          DU_LOG("\nERROR  --> E2AP: failed to fill ric event trigger style");
1706          break;
1707       }
1708
1709       /* RIC Report Style List */
1710       DU_ALLOC(ranFuncDefinition->ric_ReportStyle_List, sizeof(struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List));
1711       if(!ranFuncDefinition->ric_ReportStyle_List)
1712       {
1713          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1714          break;
1715       }
1716       if(fillRicReportStyle(ranFuncDb, ranFuncDefinition->ric_ReportStyle_List) != ROK)
1717       {
1718          DU_LOG("\nERROR  --> E2AP: failed to fill ric report style");
1719          break;
1720       }
1721
1722       /* Encode the F1SetupRequest type as APER */
1723       xer_fprint(stdout, &asn_DEF_E2SM_KPM_RANfunction_Description, ranFuncDefinition);
1724
1725       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1726       encBufSize = 0;
1727       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_RANfunction_Description, 0, ranFuncDefinition, PrepFinalEncBuf, encBuf);
1728
1729       /* Encode results */
1730       if(encRetVal.encoded == ENCODE_FAIL)
1731       {
1732          DU_LOG("\nERROR  -->  F1AP : Could not encode RAN function definition  (at %s)\n",\
1733                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1734          break;
1735       }
1736       else
1737       {
1738          DU_LOG("\nDEBUG   -->  F1AP : Created APER encoded buffer for RAN function definition \n");
1739          for(uint8_t measIeIdx=0; measIeIdx< encBufSize; measIeIdx++)
1740          {
1741             printf("%x",encBuf[measIeIdx]);
1742          }
1743          ranFunctionDefinition = &ranFuncItem->ranFunctionDefinition; 
1744          ranFunctionDefinition->size = encBufSize;
1745          DU_ALLOC(ranFunctionDefinition->buf, encBufSize);
1746          if(ranFunctionDefinition->buf == NULLP)
1747          {
1748             DU_LOG("\nERROR  -->  F1AP : Memory allocation failed for RAN function definition buffer");
1749             break;
1750          }
1751          memcpy(ranFunctionDefinition->buf, &encBuf, encBufSize);
1752          ret = ROK;
1753          break;
1754       }
1755    }
1756    freeE2smKpmRanFunctionDefinition(ranFuncDefinition);
1757    return ret;
1758 }
1759
1760 /*******************************************************************
1761  *
1762  * @brief Builds Ran function add list based on the procedure code
1763  *
1764  * @details
1765  *
1766  *    Function : BuildRanFunctionAddList 
1767  *
1768  *    Functionality: Building RAN addition addition list
1769  *       In case of ProcedureCodeE2_id_E2setup we add all the RAN Function list
1770  *       which is present in E2 database.
1771  *       In the case of other procedures, we just fill the RAN functions whose ID 
1772  *       is contained in recvList
1773  *
1774  * @params[in] 
1775  *       RAN Function list
1776  *       Procedure code
1777  *       Count of ran functions to be added in the list
1778  *       Received list of RAN functions
1779  *
1780  * @return ROK     - success
1781  *         RFAILED - failure
1782  *
1783  ******************************************************************/
1784
1785 uint8_t BuildRanFunctionAddList(RANfunctions_List_t *ranFunctionsList, uint8_t procedureCode, uint8_t count, RanFuncInfo *recvList)
1786 {
1787    uint16_t id;
1788    RanFunction *ranFuncDb;
1789    uint8_t ranFuncIdx;
1790    RANfunction_ItemIEs_t *ranFuncItemIe;
1791    
1792    /* For ProcedureCodeE2_id_E2setup, the number of RAN function list items is
1793     * equal to the number of ran function entries stored in the database.
1794     * For any other procedure, the RAN function list count is equal
1795     * to the count of ran functions obtained from the function's caller */
1796
1797    if(procedureCode == ProcedureCodeE2_id_E2setup)
1798       ranFunctionsList->list.count = duCb.e2apDb.numOfRanFunction;
1799    else
1800       ranFunctionsList->list.count = count;
1801
1802    ranFunctionsList->list.size = ranFunctionsList->list.count * sizeof(RANfunction_ItemIEs_t*);
1803    DU_ALLOC(ranFunctionsList->list.array, ranFunctionsList->list.size);
1804    if(ranFunctionsList->list.array == NULLP)
1805    {
1806       DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
1807       return RFAILED;
1808    }
1809
1810    for(ranFuncIdx = 0; ranFuncIdx< ranFunctionsList->list.count; ranFuncIdx++)
1811    {
1812       DU_ALLOC(ranFunctionsList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
1813       if(ranFunctionsList->list.array[ranFuncIdx] == NULLP)
1814       {
1815          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
1816          return RFAILED;
1817       }
1818       if(procedureCode == ProcedureCodeE2_id_E2setup) 
1819       {
1820          /* Getting all of the RAN function's information from DuCb one by one*/
1821          ranFuncDb = &duCb.e2apDb.ranFunction[ranFuncIdx];
1822       }
1823       else
1824       {
1825          /* Getting only the RAN function information from DuCb whose Id is
1826           * present in the received array */
1827          id =recvList[ranFuncIdx].id;
1828          ranFuncDb = &duCb.e2apDb.ranFunction[id-1];
1829       }
1830       ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncIdx];
1831       ranFuncItemIe->id = ProtocolIE_IDE2_id_RANfunction_Item;
1832       ranFuncItemIe->criticality = CriticalityE2_ignore;
1833       ranFuncItemIe->value.present = RANfunction_ItemIEs__value_PR_RANfunction_Item;
1834       BuildRanFunctionItem(&ranFuncItemIe->value.choice.RANfunction_Item, ranFuncDb);
1835    }
1836    return ROK;
1837 }   
1838
1839 /*******************************************************************
1840  *
1841  * @brief De Allocate E2 Setup Request Message
1842  *
1843  * @details
1844  *
1845  *    Function : FreeE2SetupReq
1846  *
1847  *    Functionality: De-Allocating E2 Setup request Message
1848  *
1849  * @params[in] E2AP_PDU_t *e2apMsg
1850  
1851  * @return void
1852  *
1853  * ****************************************************************/
1854
1855 void FreeE2SetupReq(E2AP_PDU_t *e2apMsg)
1856 {
1857    uint8_t arrIdx = 0;
1858    uint8_t e2NodeAddListIdx =0, ranFuncAddListIdx;
1859    E2setupRequest_t *e2SetupReq;
1860    E2nodeComponentConfigAddition_List_t *e2NodeAddList;
1861    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
1862    RANfunctions_List_t *ranFunctionsList;
1863    RANfunction_ItemIEs_t *ranFuncItemIe;
1864    RANfunction_Item_t  *ranFunItem;
1865
1866    /* De-allocating Memory */
1867    if(e2apMsg != NULLP)
1868    {
1869       if(e2apMsg->choice.initiatingMessage != NULLP)
1870       {
1871          e2SetupReq = &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest; 
1872          if(e2SetupReq->protocolIEs.list.array != NULLP)
1873          {
1874             for(arrIdx = 0; arrIdx < e2SetupReq->protocolIEs.list.count; arrIdx++)
1875             {
1876                if(e2SetupReq->protocolIEs.list.array[arrIdx] != NULLP)
1877                {
1878                   switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
1879                   {
1880                      case ProtocolIE_IDE2_id_TransactionID:
1881                           break;
1882                      case ProtocolIE_IDE2_id_GlobalE2node_ID:
1883                         {
1884                            if(e2SetupReq->protocolIEs.list.array[arrIdx]->\
1885                                  value.choice.GlobalE2node_ID.choice.gNB != NULLP)
1886                            {
1887                               GlobalE2node_gNB_ID_t *gNbId = NULLP;
1888                               gNbId = e2SetupReq->protocolIEs.list.array[arrIdx]->\
1889                                       value.choice.GlobalE2node_ID.choice.gNB;
1890                               if(gNbId->global_gNB_ID.plmn_id.buf != NULLP)
1891                               {
1892                                  DU_FREE(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf,\
1893                                        gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size);
1894                                  DU_FREE(gNbId->global_gNB_ID.plmn_id.buf,\
1895                                        gNbId->global_gNB_ID.plmn_id.size);
1896                               }
1897
1898                               if(gNbId->gNB_DU_ID != NULLP)
1899                               {
1900                                  DU_FREE( gNbId->gNB_DU_ID->buf, gNbId->gNB_DU_ID->size);
1901                                  DU_FREE(gNbId->gNB_DU_ID, sizeof(GNB_DU_ID_t));
1902                               }
1903                               DU_FREE(e2SetupReq->protocolIEs.list.array[arrIdx]->value.\
1904                                     choice.GlobalE2node_ID.choice.gNB, sizeof(GlobalE2node_gNB_ID_t));
1905                            }
1906                            break;
1907                         }
1908                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
1909                      {
1910                          e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;
1911                          if(e2NodeAddList->list.array)
1912                          {
1913                              for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
1914                              {
1915                                 e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
1916                                 
1917                                 /* Free E2 Node Component Request Part */
1918                                 DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\
1919                                       e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentRequestPart.size);
1920                                 
1921                                 /* Free E2 Node Component Response Part */
1922                                 DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.\
1923                                       e2nodeComponentResponsePart.buf, \
1924                                       e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentResponsePart.size);
1925                                  
1926                                  /* Free E2 Node Component ID */
1927                                 if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1)
1928                                 {
1929                                     DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
1930                                     e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
1931                                     e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
1932                                     e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
1933                                     DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\
1934                                     sizeof(E2nodeComponentInterfaceF1_t));
1935                                 }
1936                                 DU_FREE(e2NodeAddList->list.array[e2NodeAddListIdx], sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
1937                              }
1938                              DU_FREE(e2NodeAddList->list.array, e2NodeAddList->list.size);
1939                          }
1940                          break;
1941                      }
1942                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
1943                      {
1944                         ranFunctionsList = &(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List);  
1945                         if(ranFunctionsList->list.array)
1946                         {  
1947                            for(ranFuncAddListIdx= 0; ranFuncAddListIdx< ranFunctionsList->list.count; ranFuncAddListIdx++)
1948                            {
1949                               if(ranFunctionsList->list.array[ranFuncAddListIdx])
1950                               {
1951                                  ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncAddListIdx];
1952                                  ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
1953                                  DU_FREE(ranFunItem->ranFunctionOID.buf, ranFunItem->ranFunctionOID.size);
1954                                  DU_FREE(ranFunItem->ranFunctionDefinition.buf, ranFunItem->ranFunctionDefinition.size);
1955                                  DU_FREE(ranFunctionsList->list.array[ranFuncAddListIdx], sizeof(RANfunction_ItemIEs_t));
1956                               }
1957                            }
1958                            DU_FREE(ranFunctionsList->list.array, ranFunctionsList->list.size);
1959                         }
1960                         break;
1961                      }
1962
1963                      default:
1964                         DU_LOG("\nERROR  --> E2AP: Invalid event at e2SetupRequet %ld ",\
1965                               (e2SetupReq->protocolIEs.list.array[arrIdx]->id));
1966                         break;
1967                   }
1968                   DU_FREE(e2SetupReq->protocolIEs.list.array[arrIdx], sizeof(E2setupRequestIEs_t));
1969                }
1970             }
1971             DU_FREE(e2SetupReq->protocolIEs.list.array, e2SetupReq->protocolIEs.list.size);
1972          }
1973          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1974       }
1975       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1976    }
1977 }
1978
1979 /*******************************************************************
1980  *
1981  * @brief Builds and Send the E2SetupRequest
1982  *
1983  * @details
1984  *
1985  *    Function : BuildAndSendE2SetupReq
1986  *
1987  * Functionality:Fills the E2SetupRequest
1988  *
1989  * @return ROK     - success
1990  *         RFAILED - failure
1991  *
1992  ******************************************************************/
1993
1994 uint8_t BuildAndSendE2SetupReq()
1995 {
1996    uint8_t arrIdx = 0, elementCnt=0;
1997    uint8_t transId = 0, ret = RFAILED;
1998    bool memAllocFailed = false;
1999    E2AP_PDU_t        *e2apMsg = NULLP;
2000    E2setupRequest_t  *e2SetupReq = NULLP;
2001    asn_enc_rval_t     encRetVal;       /* Encoder return value */
2002
2003    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup Request\n");
2004    do
2005    {
2006       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2007       if(e2apMsg == NULLP)
2008       {
2009          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2010          break;
2011       }
2012       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
2013       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2014       if(e2apMsg->choice.initiatingMessage == NULLP)
2015       {
2016          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2017          break;
2018       }
2019       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2020       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2setup;
2021       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2setupRequest;
2022       e2SetupReq = &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest;
2023
2024       elementCnt = 4;
2025       e2SetupReq->protocolIEs.list.count = elementCnt;
2026       e2SetupReq->protocolIEs.list.size = elementCnt * sizeof(E2setupRequestIEs_t*);
2027
2028       /* Initialize the E2Setup members */
2029       DU_ALLOC(e2SetupReq->protocolIEs.list.array, \
2030             e2SetupReq->protocolIEs.list.size);
2031       if(e2SetupReq->protocolIEs.list.array == NULLP)
2032       {
2033          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
2034          break;
2035       }
2036       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
2037       {
2038          DU_ALLOC(e2SetupReq->protocolIEs.list.array[arrIdx],\
2039                sizeof(E2setupRequestIEs_t));
2040          if(e2SetupReq->protocolIEs.list.array[arrIdx] == NULLP)
2041          {
2042             memAllocFailed = true;
2043             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayarrIdx [%d]", arrIdx);
2044             break;
2045          }
2046       }
2047       if(memAllocFailed == true)
2048          break;
2049
2050       arrIdx = 0;
2051
2052       /* TransactionID */
2053       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2054       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2055       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
2056       transId = assignTransactionId();
2057       e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
2058
2059       arrIdx++;
2060       /* GlobalE2node_gNB_ID */
2061       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_GlobalE2node_ID;
2062       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2063       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_GlobalE2node_ID;
2064       e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.present = GlobalE2node_ID_PR_gNB;
2065
2066       DU_ALLOC(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.\
2067             GlobalE2node_ID.choice.gNB, sizeof(GlobalE2node_gNB_ID_t));
2068       if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.\
2069             GlobalE2node_ID.choice.gNB == NULLP)
2070       {
2071          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for gNbId");
2072          break;
2073       }
2074       else
2075       {
2076          ret = BuildGlobalgNBId(e2SetupReq->protocolIEs.list.array[arrIdx]->value.\
2077                choice.GlobalE2node_ID.choice.gNB);
2078          if(ret != ROK)
2079          {
2080              DU_LOG("\nERROR  -->  E2AP : Failed to build Global Gnb Id");
2081              break;
2082          }
2083       }
2084       
2085       /* RAN Functions Added List */
2086       arrIdx++;
2087       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAdded;
2088       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2089       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_RANfunctions_List;
2090       if(BuildRanFunctionAddList(&(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List), ProcedureCodeE2_id_E2setup, 0, NULL)!=ROK)      
2091       {
2092          DU_LOG("\nERROR  -->  E2AP : Failed to create RAN Function");
2093          break;
2094       }
2095
2096       /* E2 Node Component Configuration Addition List */
2097       arrIdx++;
2098       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition;
2099       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2100       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_E2nodeComponentConfigAddition_List;
2101       if(BuildE2NodeConfigAddList(&(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List), ProcedureCodeE2_id_E2setup, 0, NULL)!=ROK)
2102       {
2103          DU_LOG("\nERROR  -->  E2AP : Failed to create E2 Node config list");
2104          break;
2105       }
2106
2107
2108
2109       /* Prints the Msg formed */
2110       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2111
2112       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2113       encBufSize = 0;
2114       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
2115             encBuf);
2116       if(encRetVal.encoded == ENCODE_FAIL)
2117       {
2118          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupRequest structure (at %s)\n",\
2119                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2120          break;
2121       }
2122       else
2123       {
2124          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2SetupRequest\n");
2125 #ifdef DEBUG_ASN_PRINT
2126          for(int i=0; i< encBufSize; i++)
2127          {
2128             printf("%x",encBuf[i]);
2129          }
2130 #endif
2131       }
2132       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
2133       {
2134          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
2135       }
2136       break;
2137    }while(true);
2138
2139    duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
2140    duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
2141    
2142    FreeE2SetupReq(e2apMsg);
2143    return ret;
2144 }/* End of BuildAndSendE2SetupReq */
2145
2146 /*******************************************************************
2147  *
2148  * @brief Builds RIC Action Admitted List
2149  *
2150  * @details
2151  *
2152  *    Function : BuildRicActionAdmitList
2153  *
2154  *    Functionality: Builds RIC Action Admitted List
2155  *
2156  * @params[in] Pointer to RIC Action Admitted List to be filled
2157  *             Subscription Response information
2158  * @return ROK     - success
2159  *         RFAILED - failure
2160  *
2161  * ****************************************************************/
2162 uint8_t BuildRicActionAdmitList(RICaction_Admitted_List_t *admitList, PendingSubsRspInfo *subsRspInfo)
2163 {
2164    uint8_t idx = 0;
2165    uint8_t elementCnt = 0;  
2166    RICaction_Admitted_ItemIEs_t *admitItem = NULLP;
2167
2168    elementCnt = subsRspInfo->numOfAcceptedActions;
2169
2170    admitList->list.count = elementCnt;
2171    admitList->list.size  = elementCnt * sizeof(RICaction_Admitted_ItemIEs_t *);
2172
2173    DU_ALLOC(admitList->list.array, admitList->list.size);
2174    if(admitList->list.array == NULLP)
2175    {
2176       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2177       return RFAILED;
2178    }
2179
2180    for(idx=0; idx<elementCnt; idx++)
2181    {
2182       DU_ALLOC(admitList->list.array[idx], sizeof(RICaction_Admitted_ItemIEs_t));
2183       if(admitList->list.array[idx] == NULLP)
2184       {
2185          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2186          return RFAILED;
2187       }
2188
2189       admitItem = (RICaction_Admitted_ItemIEs_t *)admitList->list.array[idx];
2190       admitItem->id = ProtocolIE_IDE2_id_RICaction_Admitted_Item;
2191       admitItem->criticality = CriticalityE2_reject;
2192       admitItem->value.present = RICaction_Admitted_ItemIEs__value_PR_RICaction_Admitted_Item;
2193       admitItem->value.choice.RICaction_Admitted_Item.ricActionID = subsRspInfo->acceptedActionList[idx]; 
2194    }
2195    return ROK;
2196 }
2197
2198 /*******************************************************************
2199  *
2200  * @brief Builds RIC Action Not Admitted List
2201  *
2202  * @details
2203  *
2204  *    Function : BuildRicActionNotAdmitList
2205  *
2206  *    Functionality: Builds RIC Action Not Admitted List
2207  *
2208  * @params[in] Pointer to RIC Action Not Admitted List to be filled
2209  *             Subscription Response information
2210  * @return ROK     - success
2211  *         RFAILED - failure
2212  *
2213  * ****************************************************************/
2214 uint8_t BuildRicActionNotAdmitList(RICaction_NotAdmitted_List_t *notAdmitList, PendingSubsRspInfo *subsRspInfo)
2215 {
2216    uint8_t idx = 0;
2217    uint8_t elementCnt = 0;  
2218    RICaction_NotAdmitted_ItemIEs_t *notAdmitItem = NULLP;
2219
2220    elementCnt = subsRspInfo->numOfRejectedActions;
2221
2222    notAdmitList->list.count = elementCnt;
2223    notAdmitList->list.size  = elementCnt * sizeof(RICaction_NotAdmitted_ItemIEs_t *);
2224
2225    DU_ALLOC(notAdmitList->list.array, notAdmitList->list.size);
2226    if(notAdmitList->list.array == NULLP)
2227    {
2228       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2229       return RFAILED;
2230    }
2231
2232    for(idx=0; idx<elementCnt; idx++)
2233    {
2234       DU_ALLOC(notAdmitList->list.array[idx], sizeof(RICaction_NotAdmitted_ItemIEs_t));
2235       if(notAdmitList->list.array[idx] == NULLP)
2236       {
2237          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2238          return RFAILED;
2239       }
2240
2241       notAdmitItem = (RICaction_NotAdmitted_ItemIEs_t *)notAdmitList->list.array[idx];
2242       notAdmitItem->id = ProtocolIE_IDE2_id_RICaction_NotAdmitted_Item;
2243       notAdmitItem->criticality = CriticalityE2_reject;
2244       notAdmitItem->value.present = RICaction_NotAdmitted_ItemIEs__value_PR_RICaction_NotAdmitted_Item;
2245       notAdmitItem->value.choice.RICaction_NotAdmitted_Item.ricActionID = \
2246          subsRspInfo->rejectedActionList[idx].id; 
2247       fillE2Cause(&notAdmitItem->value.choice.RICaction_NotAdmitted_Item.cause, \
2248          subsRspInfo->rejectedActionList[idx].failureCause);
2249    }
2250    return ROK;
2251 }
2252
2253 /*******************************************************************
2254  *
2255  * @breif Deallocation of BuildAndSendRicSubscriptionRsp memory
2256  *
2257  * @details
2258  *
2259  *    Function : FreeRicSubscriptionRsp
2260  *
2261  * Functionality:Free the RicSubscriptionRsp
2262  *
2263  * @param[in] E2AP_PDU_t *e2apRicMsg
2264  *
2265  * @return void
2266  *      
2267  ******************************************************************/
2268 void FreeRicSubscriptionRsp(E2AP_PDU_t  *e2apRicMsg)
2269 {
2270    RICsubscriptionResponse_t  *ricSubscriptionRsp= NULLP;
2271    uint8_t idx=0;
2272    uint8_t listIdx=0;
2273    RICaction_Admitted_List_t *admitList = NULLP;
2274    RICaction_NotAdmitted_List_t *notAdmitList = NULLP;
2275
2276    if(e2apRicMsg != NULLP)
2277    {
2278       if(e2apRicMsg->choice.successfulOutcome != NULLP)
2279       {
2280          ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
2281          if(ricSubscriptionRsp)
2282          {
2283             if(ricSubscriptionRsp->protocolIEs.list.array != NULLP)
2284             {
2285                for(idx=0; idx<ricSubscriptionRsp->protocolIEs.list.count; idx++)
2286                {
2287                   if(ricSubscriptionRsp->protocolIEs.list.array[idx] != NULLP)
2288                   {
2289                      switch(ricSubscriptionRsp->protocolIEs.list.array[idx]->id)
2290                      {
2291                         case ProtocolIE_IDE2_id_RICactions_Admitted:
2292                            {
2293                               admitList = &ricSubscriptionRsp->protocolIEs.list.\
2294                                              array[idx]->value.choice.RICaction_Admitted_List;
2295                               if(admitList->list.array != NULLP)
2296                               {
2297                                  for(listIdx=0 ; listIdx < admitList->list.count; listIdx++)
2298                                  {
2299                                     DU_FREE(admitList->list.array[listIdx], sizeof(RICaction_Admitted_ItemIEs_t));
2300                                  }
2301                                  DU_FREE(admitList->list.array, admitList->list.size);   
2302                               }
2303                               break;
2304                            }
2305                         case ProtocolIE_IDE2_id_RICactions_NotAdmitted:
2306                            {
2307                               notAdmitList = &ricSubscriptionRsp->protocolIEs.list.\
2308                                              array[idx]->value.choice.RICaction_NotAdmitted_List;
2309                               if(notAdmitList->list.array != NULLP)
2310                               {
2311                                  for(listIdx=0 ; listIdx < notAdmitList->list.count; listIdx++)
2312                                  {
2313                                     DU_FREE(notAdmitList->list.array[listIdx], sizeof(RICaction_NotAdmitted_ItemIEs_t));
2314                                  }
2315                                  DU_FREE(notAdmitList->list.array, notAdmitList->list.size);     
2316                               }
2317                               break;
2318                            }
2319                         default:
2320                            break;
2321                      }
2322                      DU_FREE(ricSubscriptionRsp->protocolIEs.list.array[idx], sizeof(RICsubscriptionResponse_IEs_t));
2323                   }
2324                }
2325                DU_FREE(ricSubscriptionRsp->protocolIEs.list.array, ricSubscriptionRsp->protocolIEs.list.size);
2326             }
2327          }   
2328          DU_FREE(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2329       }         
2330       DU_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));        
2331    }
2332 }
2333
2334 /*******************************************************************
2335  *
2336  * @brief Fill RIC Subscription Response IEs
2337  *
2338  * @details
2339  *
2340  *    Function : fillRicSubscriptionRsp
2341  *
2342  * functionality: Fill RIC Subscription Response IEs
2343  *
2344  * @param  Pointer to RIC subscription response
2345  *         Subscription response information
2346  * @return ROK     - success
2347  *         RFAILED - failure
2348  *
2349  ******************************************************************/
2350 uint8_t fillRicSubscriptionRsp(RICsubscriptionResponse_t *ricSubscriptionRsp, PendingSubsRspInfo *subsRspInfo)
2351 {
2352    uint8_t ieIdx = 0;
2353    uint8_t elementCnt = 0;
2354    RICsubscriptionResponse_IEs_t *subsRspIe = NULLP;
2355
2356    elementCnt = 3;
2357    if(subsRspInfo->numOfRejectedActions)
2358       elementCnt++;
2359
2360    ricSubscriptionRsp->protocolIEs.list.count = elementCnt;
2361    ricSubscriptionRsp->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionResponse_IEs_t);
2362    DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array, ricSubscriptionRsp->protocolIEs.list.size);
2363    if(ricSubscriptionRsp->protocolIEs.list.array == NULLP)
2364    {
2365       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at %s : line %d", __func__, __LINE__);
2366       return RFAILED;
2367    }
2368
2369    for(ieIdx=0; ieIdx<ricSubscriptionRsp->protocolIEs.list.count; ieIdx++)
2370    {
2371       DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionResponse_IEs_t));
2372       if(ricSubscriptionRsp->protocolIEs.list.array[ieIdx] == NULLP)
2373       {
2374          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d] : ieIdx [%d]", __func__, __LINE__,ieIdx);
2375          return RFAILED;
2376       }
2377    }
2378
2379    /* RIC Request ID */
2380    ieIdx=0;
2381    subsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
2382    subsRspIe->id = ProtocolIE_IDE2_id_RICrequestID;
2383    subsRspIe->criticality = CriticalityE2_reject;
2384    subsRspIe->value.present = RICsubscriptionRequest_IEs__value_PR_RICrequestID;
2385    subsRspIe->value.choice.RICrequestID.ricRequestorID = subsRspInfo->requestId.requestorId;
2386    subsRspIe->value.choice.RICrequestID.ricInstanceID = subsRspInfo->requestId.instanceId;
2387
2388    /* RAN Function ID */
2389    ieIdx++;
2390    subsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
2391    subsRspIe->id = ProtocolIE_IDE2_id_RANfunctionID;
2392    subsRspIe->criticality = CriticalityE2_reject;
2393    subsRspIe->value.present = RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
2394    subsRspIe->value.choice.RANfunctionID = subsRspInfo->ranFuncId;
2395
2396    /* RIC Action Admitted List */
2397    ieIdx++;
2398    subsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
2399    subsRspIe->id = ProtocolIE_IDE2_id_RICactions_Admitted;
2400    subsRspIe->criticality = CriticalityE2_reject;
2401    subsRspIe->value.present = RICsubscriptionResponse_IEs__value_PR_RICaction_Admitted_List;
2402    if(BuildRicActionAdmitList(&subsRspIe->value.choice.RICaction_Admitted_List, subsRspInfo) != ROK)
2403    {
2404       DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Action Admitted List in RIC Subscription Response");
2405       return RFAILED;
2406    }
2407
2408    /* RIC Action Not Admitted List */
2409    if(subsRspInfo->numOfRejectedActions)
2410    {
2411       ieIdx++;
2412       subsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
2413       subsRspIe->id = ProtocolIE_IDE2_id_RICactions_NotAdmitted;
2414       subsRspIe->criticality = CriticalityE2_reject;
2415       subsRspIe->criticality = CriticalityE2_reject;
2416       subsRspIe->value.present = RICsubscriptionResponse_IEs__value_PR_RICaction_NotAdmitted_List;
2417       if(BuildRicActionNotAdmitList(&subsRspIe->value.choice.RICaction_NotAdmitted_List, subsRspInfo) != ROK)
2418       {
2419          DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Action Not Admitted List in RIC Subscription Response");
2420          return RFAILED;
2421       }
2422    }
2423
2424    return ROK;
2425 }
2426
2427 /*******************************************************************
2428  *
2429  * @brief Builds and Send the RicSubscriptionRsp
2430  *
2431  * @details
2432  *
2433  *    Function : BuildAndSendRicSubscriptionRsp
2434  *
2435  * Functionality:Fills the RicSubscriptionRsp
2436  *
2437  * @return ROK     - success
2438  *         RFAILED - failure
2439  *
2440  ******************************************************************/
2441
2442 uint8_t BuildAndSendRicSubscriptionRsp(PendingSubsRspInfo *subsRspInfo)
2443 {
2444    uint8_t      ret = RFAILED;
2445    E2AP_PDU_t   *e2apRicMsg = NULLP;
2446    RICsubscriptionResponse_t  *ricSubscriptionRsp=NULLP;
2447    asn_enc_rval_t encRetVal; 
2448
2449    while(true)
2450    {
2451       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Response\n");
2452
2453       DU_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t)); 
2454       if(e2apRicMsg == NULLP)
2455       {
2456          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2457          break;
2458       }
2459
2460       e2apRicMsg->present =  E2AP_PDU_PR_successfulOutcome;
2461       DU_ALLOC(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2462       if(e2apRicMsg->choice.successfulOutcome == NULLP)
2463       {
2464          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC subscription Response failed");
2465          break;
2466       }
2467
2468       e2apRicMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
2469       e2apRicMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
2470       e2apRicMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse;
2471
2472       ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
2473
2474       if(fillRicSubscriptionRsp(ricSubscriptionRsp, subsRspInfo) != ROK)
2475       {
2476          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICsubscriptionResponseIE failed");
2477          break;
2478       }
2479
2480       /* Prints the Msg formed */
2481       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
2482
2483       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2484       encBufSize = 0;
2485       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf, encBuf);
2486       if(encRetVal.encoded == ENCODE_FAIL)
2487       {
2488          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Response structure (at %s)\n",\
2489                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2490          break;
2491       }
2492       else
2493       {
2494          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RIC subscription response \n");
2495 #ifdef DEBUG_ASN_PRINT
2496          for(int i=0; i< encBufSize; i++)
2497          {
2498             printf("%x",encBuf[i]);
2499          } 
2500 #endif
2501       } 
2502
2503       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
2504       {
2505          DU_LOG("\nERROR  -->  E2AP : Sending RIC Subscription Response failed");      
2506          break;
2507       }
2508
2509       ret = ROK;
2510       break;
2511
2512    }
2513
2514    FreeRicSubscriptionRsp(e2apRicMsg);
2515    return ret;
2516 }
2517
2518 /******************************************************************
2519  *
2520  * @brief Deallocation of memory allocated by aper decoder for e2 setup response
2521  *
2522  * @details
2523  *
2524  *    Function : freeAperDecodingOfE2SetupRsp
2525  *
2526  *    Functionality: Deallocation of memory allocated by aper decoder for e2
2527  *    setup response
2528  *
2529  * @params[in] E2setupResponse_t *e2SetRspMsg;
2530  * @return void
2531  *
2532  * ****************************************************************/
2533 void freeAperDecodingOfE2SetupRsp(E2setupResponse_t *e2SetRspMsg)
2534 {
2535    uint8_t arrIdx, e2NodeConfigAddAckListIdx;
2536    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem;
2537    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAddAckList;
2538
2539    if(e2SetRspMsg)
2540    {
2541       if(e2SetRspMsg->protocolIEs.list.array)
2542       {
2543          for(arrIdx=0; arrIdx<e2SetRspMsg->protocolIEs.list.count; arrIdx++)
2544          {
2545             if(e2SetRspMsg->protocolIEs.list.array[arrIdx])
2546             {
2547                switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
2548                {
2549                   case ProtocolIE_IDE2_id_TransactionID:
2550                      break;
2551
2552                   case ProtocolIE_IDE2_id_GlobalRIC_ID:
2553                      {
2554                         free(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.pLMN_Identity.buf);
2555                         free(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID.buf);
2556                         break;
2557                      }
2558
2559                   case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
2560                      {
2561                         e2NodeConfigAddAckList = &e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
2562                         if(e2NodeConfigAddAckList->list.array )
2563                         {
2564                            for(e2NodeConfigAddAckListIdx = 0; e2NodeConfigAddAckListIdx< e2NodeConfigAddAckList->list.count; e2NodeConfigAddAckListIdx++)
2565                            {
2566                               if(e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx])
2567                               {
2568                                  e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx];
2569                                  free(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.\
2570                                        e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf);
2571                                  free(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.\
2572                                        e2nodeComponentInterfaceTypeF1);
2573                                  free(e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx]);
2574                               }
2575                            }
2576                            free(e2NodeConfigAddAckList->list.array);
2577                         }
2578                         break;
2579                      }
2580                }
2581                free(e2SetRspMsg->protocolIEs.list.array[arrIdx]);  
2582             }
2583          }
2584          free(e2SetRspMsg->protocolIEs.list.array);
2585       }
2586    }
2587 }
2588
2589 /******************************************************************
2590  *
2591  * @brief handling of e2 noe config update ack ies
2592  *
2593  * @details
2594  *
2595  *    Function :handleE2NodeConfigUpdateAckIes 
2596  *
2597  *    Functionality: handling of e2 noe config update ack ies
2598  *
2599  * @params[in] 
2600  *    Pointer to the E2 Node cfg
2601  *    Procedure code
2602  * @return void
2603 ******************************************************************/
2604
2605 void handleE2NodeConfigUpdateAckIes(PTR e2NodeCfg, uint8_t procedureCode)
2606 {
2607    CmLList         *node=NULLP;
2608    E2NodeComponent *e2NodeComponentInfo=NULLP;
2609    E2nodeComponentID_t *e2nodeComponentID=NULLP;
2610    E2nodeComponentConfigRemovalAck_Item_t *removalAckItem=NULLP;
2611    E2nodeComponentConfigUpdateAck_Item_t *updateAckItem=NULLP;
2612    E2nodeComponentConfigAdditionAck_Item_t *additionAckItem=NULLP;
2613
2614    switch(procedureCode)
2615    {
2616       case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
2617          {
2618             additionAckItem = (E2nodeComponentConfigAdditionAck_Item_t *)e2NodeCfg;
2619             e2nodeComponentID = &additionAckItem->e2nodeComponentID;
2620             break;
2621          }
2622       case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
2623          {
2624             updateAckItem = (E2nodeComponentConfigUpdateAck_Item_t*) e2NodeCfg;
2625             e2nodeComponentID = &updateAckItem->e2nodeComponentID;
2626             break;
2627          }
2628       case  ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
2629          {
2630             removalAckItem= (E2nodeComponentConfigRemovalAck_Item_t*)e2NodeCfg;
2631             e2nodeComponentID = &removalAckItem->e2nodeComponentID;
2632             break;
2633          }
2634    }
2635
2636    switch(e2nodeComponentID->present)
2637    {
2638       case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
2639          {
2640             e2NodeComponentInfo = fetchE2NodeComponentInfo(F1, e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0], &node);
2641             if(!e2NodeComponentInfo)
2642             {
2643                DU_LOG("\nERROR  --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__);
2644                return;
2645             }
2646             break;
2647          }
2648       default:
2649          break;
2650    }
2651    
2652    switch(procedureCode)
2653    {
2654       case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
2655          {
2656             DU_FREE(e2NodeComponentInfo->addConfiguration->componentRequestPart, e2NodeComponentInfo->addConfiguration->reqBufSize);
2657             DU_FREE(e2NodeComponentInfo->addConfiguration->componentResponsePart, e2NodeComponentInfo->addConfiguration->rspBufSize);
2658             DU_FREE(e2NodeComponentInfo->addConfiguration, sizeof(E2NodeConfig));
2659             break;
2660          }
2661       case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
2662          {
2663             DU_FREE(e2NodeComponentInfo->updateConfiguration->componentRequestPart, e2NodeComponentInfo->updateConfiguration->reqBufSize);
2664             DU_FREE(e2NodeComponentInfo->updateConfiguration->componentResponsePart, e2NodeComponentInfo->updateConfiguration->rspBufSize);
2665             DU_FREE(e2NodeComponentInfo->updateConfiguration, sizeof(E2NodeConfig));
2666             break;
2667          }
2668       case  ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
2669          {
2670             cmLListDelFrm(&duCb.e2apDb.e2NodeComponentList, node);
2671             if(e2NodeComponentInfo->addConfiguration)
2672             {
2673                DU_FREE(e2NodeComponentInfo->addConfiguration->componentRequestPart, e2NodeComponentInfo->addConfiguration->reqBufSize);
2674                DU_FREE(e2NodeComponentInfo->addConfiguration->componentResponsePart, e2NodeComponentInfo->addConfiguration->rspBufSize);
2675                DU_FREE(e2NodeComponentInfo->addConfiguration, sizeof(E2NodeConfig));
2676             }
2677             if(e2NodeComponentInfo->updateConfiguration)
2678             {
2679                DU_FREE(e2NodeComponentInfo->updateConfiguration->componentRequestPart, e2NodeComponentInfo->updateConfiguration->reqBufSize);
2680                DU_FREE(e2NodeComponentInfo->updateConfiguration->componentResponsePart, e2NodeComponentInfo->updateConfiguration->rspBufSize);
2681                DU_FREE(e2NodeComponentInfo->updateConfiguration, sizeof(E2NodeConfig));
2682             }
2683             DU_FREE(node, sizeof(CmLList));
2684             break;
2685          }
2686    }
2687 }
2688
2689 /******************************************************************
2690  *
2691  * @brief Processes E2 Setup Response sent by RIC
2692  *
2693  * @details
2694  *
2695  *    Function : procE2SetupRsp
2696  *
2697  *    Functionality: Processes E2 Setup Response sent by RIC
2698  *
2699  * @params[in] E2AP_PDU_t ASN decoded E2AP message
2700  * @return void
2701  *
2702  * ****************************************************************/
2703
2704 void procE2SetupRsp(E2AP_PDU_t *e2apMsg)
2705 {
2706    bool invalidTransId = false;
2707    uint8_t arrIdx =0, transId=0, idx=0; 
2708    uint32_t recvBufLen;             
2709    E2setupResponse_t *e2SetRspMsg=NULL;
2710    E2nodeComponentConfigAdditionAck_List_t *e2NodeCfgAckList=NULL;
2711    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem=NULL;
2712
2713    DU_LOG("\nINFO   -->  E2AP : E2 Setup Response received"); 
2714    duCb.e2Status = TRUE; //Set E2 status as true
2715    e2SetRspMsg = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
2716
2717    for(arrIdx=0; arrIdx<e2SetRspMsg->protocolIEs.list.count; arrIdx++)
2718    {
2719       switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
2720       {
2721          case ProtocolIE_IDE2_id_TransactionID:
2722             {
2723                transId = e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
2724                if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
2725                      (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
2726                {
2727                   memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
2728                }
2729                else
2730                {
2731                   DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
2732                   invalidTransId = true;
2733                }
2734                break;
2735             }
2736
2737          case ProtocolIE_IDE2_id_GlobalRIC_ID:
2738             {
2739                /* To store the Ric Id Params */
2740                recvBufLen = sizeof(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value\
2741                      .choice.GlobalRIC_ID.pLMN_Identity.size);
2742                memcpy(&duCb.e2apDb.ricId.plmnId, e2SetRspMsg->protocolIEs.list.array[arrIdx]\
2743                      ->value.choice.GlobalRIC_ID.pLMN_Identity.buf, recvBufLen);
2744                bitStringToInt(&e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID, &duCb.e2apDb.ricId);
2745                /*TODO : duCb.e2apDb.ricId.plmnId memory to be deallocated after the usage */
2746                break;
2747             }
2748
2749          case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
2750             {
2751                e2NodeCfgAckList = &e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
2752                for(idx =0; idx <e2NodeCfgAckList->list.count; idx++)
2753                {
2754                   e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeCfgAckList->list.array[idx];
2755                   handleE2NodeConfigUpdateAckIes((PTR)&e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item,\
2756                   ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck);
2757                }
2758                break;
2759             }
2760
2761          default:
2762             {
2763                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2SetupRsp:%ld",
2764                      e2SetRspMsg->protocolIEs.list.array[arrIdx]->id);
2765                break;
2766             }
2767       }
2768
2769       if(invalidTransId == true)
2770       {
2771          break;
2772       }
2773    }
2774    freeAperDecodingOfE2SetupRsp(e2SetRspMsg);
2775
2776    if(invalidTransId == false)
2777    {
2778       if(duSendE2NodeConfigurationUpdate() != ROK)
2779       {
2780          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 node config update");
2781       }
2782    }
2783 }
2784
2785 /*******************************************************************
2786  *
2787  * @brief Free RIC Subscription Request
2788  *
2789  * @details
2790  *
2791  *    Function : freeAperDecodingOfRicSubsReq
2792  *
2793  * Functionality : Free RIC Subscription Request
2794  *
2795  * @return void
2796  *
2797  ******************************************************************/
2798 void freeAperDecodingOfRicSubsReq(RICsubscriptionRequest_t *ricSubscriptionReq)
2799 {
2800    uint8_t idx = 0;
2801    uint8_t elementIdx = 0;
2802    RICsubscriptionDetails_t *subsDetails = NULLP;
2803    RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
2804
2805    if(ricSubscriptionReq->protocolIEs.list.array)
2806    {
2807       for(idx=0; idx < ricSubscriptionReq->protocolIEs.list.count; idx++)
2808       {
2809          switch(ricSubscriptionReq->protocolIEs.list.array[idx]->id)
2810          {
2811             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
2812                {
2813                   subsDetails = &(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails);
2814                   free(subsDetails->ricEventTriggerDefinition.buf);
2815
2816                   if(subsDetails->ricAction_ToBeSetup_List.list.array)
2817                   {
2818                      for(elementIdx = 0; elementIdx < subsDetails->ricAction_ToBeSetup_List.list.count; elementIdx++)
2819                      {
2820                         if(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
2821                         {
2822                            actionItem = (RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx];
2823                            if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
2824                            {
2825                               free(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf);
2826                               free(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition);
2827                            }
2828                            free(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx]);
2829                         }
2830                      }
2831                      free(subsDetails->ricAction_ToBeSetup_List.list.array);
2832                   }
2833                   break;
2834                }
2835          }
2836          free(ricSubscriptionReq->protocolIEs.list.array[idx]);
2837       }
2838       free(ricSubscriptionReq->protocolIEs.list.array);
2839    }
2840 }
2841
2842 /*******************************************************************
2843  *
2844  * @brief Free Event Trigger Definition
2845  *
2846  * @details
2847  *
2848  *    Function : freeAperDecodingOfEventTriggerDef
2849  *
2850  *    Functionality: Free Event Trigger Definition
2851  *
2852  * @params[in] E2SM-KPM Event Trigger Definition
2853  * @return void
2854  *
2855  * ****************************************************************/
2856 void  freeAperDecodingOfEventTriggerDef(E2SM_KPM_EventTriggerDefinition_t *eventTiggerDef)
2857 {
2858    if(eventTiggerDef)
2859    {
2860       switch(eventTiggerDef->eventDefinition_formats.present)
2861       {
2862          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING:
2863             break;
2864
2865          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1:
2866             free(eventTiggerDef->eventDefinition_formats.choice.eventDefinition_Format1);
2867             break;
2868       }
2869    }
2870 }
2871
2872 /*******************************************************************
2873  *
2874  * @brief Extract E2SM-KPM Event trigger definition
2875  *
2876  * @details
2877  *
2878  *    Function : extractEventTriggerDef
2879  *
2880  * Functionality : This function :
2881  *     - Decodes E2SM-KPM Event Trigger Definition
2882  *     - Validates that even trigger style is supported by E2 node
2883  *     - Stores event trigger details in local DB
2884  *
2885  * @params[in] RAN Function Database structure
2886  *             RIC Subscription Info to be added to RAN function
2887  *             RIC Event Trigger Definition buffer received from RIC
2888  * @return ROK     - success
2889  *         RFAILED - failure
2890  *
2891  ******************************************************************/
2892 uint8_t extractEventTriggerDef(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \
2893    RICeventTriggerDefinition_t *ricEventTriggerDef, E2FailureCause *failureCause)
2894 {
2895    uint8_t ret = RFAILED;
2896    uint8_t eventIdx = 0;
2897    asn_dec_rval_t rval ={0};
2898    E2SM_KPM_EventTriggerDefinition_t eventTiggerDef, *eventTiggerDefPtr = NULLP;
2899
2900    /* Decoding E2SM-KPM Even Trigger Definition */
2901    eventTiggerDefPtr = &eventTiggerDef;
2902    memset(eventTiggerDefPtr, 0, sizeof(E2SM_KPM_EventTriggerDefinition_t));
2903
2904    rval = aper_decode(0, &asn_DEF_E2SM_KPM_EventTriggerDefinition, (void **)&eventTiggerDefPtr, ricEventTriggerDef->buf,\
2905          ricEventTriggerDef->size, 0, 0);
2906    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
2907    {
2908       DU_LOG("\nERROR  -->  E2AP : ASN decode failed for E2SM-KPM Event Trigger Definition");
2909       failureCause->causeType = E2_PROTOCOL; 
2910       failureCause->cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE;
2911       return RFAILED;
2912    }
2913    printf("\n");
2914    xer_fprint(stdout, &asn_DEF_E2SM_KPM_EventTriggerDefinition, eventTiggerDefPtr);
2915
2916    /* Validating the received event trigger definition format */
2917    for(eventIdx = 0; eventIdx < ranFuncDb->numOfEventTriggerStyleSupported; eventIdx++)
2918    {
2919       if((eventTiggerDefPtr->eventDefinition_formats.present != \
2920          E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING) && \
2921          (eventTiggerDefPtr->eventDefinition_formats.present == ranFuncDb->eventTriggerStyleList[eventIdx].formatType))
2922       {
2923          ricSubscriptionInfo->eventTriggerDefinition.formatType = ranFuncDb->eventTriggerStyleList[eventIdx].formatType;
2924          ricSubscriptionInfo->eventTriggerDefinition.choice.format1.reportingPeriod = \
2925             eventTiggerDefPtr->eventDefinition_formats.choice.eventDefinition_Format1->reportingPeriod;
2926
2927          ret = ROK;
2928          break;
2929       }
2930    }
2931
2932    if(ret == RFAILED)
2933    {
2934       failureCause->causeType = E2_RIC_REQUEST;
2935       failureCause->cause = E2_EVENT_TRIGGER_NOT_SUPPORTED;
2936    }
2937    /* Free E2SM_KPM_EventTriggerDefinition_t */
2938    freeAperDecodingOfEventTriggerDef(eventTiggerDefPtr);
2939    return ret;
2940 }
2941
2942 /*******************************************************************
2943  *
2944  * @brief Free RIC Action Definition
2945  *
2946  * @details
2947  *
2948  *    Function :  freeAperDecodingOfRicActionDefinition
2949  *
2950  *    Functionality: Free RIC Action Definition
2951  *
2952  * @params[in] E2SM-KPM Action definition
2953  * @return void
2954  *
2955  * ****************************************************************/
2956 void  freeAperDecodingOfRicActionDefinition(E2SM_KPM_ActionDefinition_t *actionDef)
2957 {
2958    uint8_t  elementIdx = 0;
2959    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
2960    MeasurementInfoItem_t *measItem = NULLP;
2961
2962    switch(actionDef->actionDefinition_formats.present)
2963    {
2964       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
2965          {
2966             if(actionDef->actionDefinition_formats.choice.actionDefinition_Format1)
2967             {
2968                actionFormat1 = actionDef->actionDefinition_formats.choice.actionDefinition_Format1;
2969                if(actionFormat1->measInfoList.list.array)
2970                {
2971                   for(elementIdx = 0; elementIdx < actionFormat1->measInfoList.list.count; elementIdx++)
2972                   {
2973                      if(actionFormat1->measInfoList.list.array[elementIdx])
2974                      {
2975                         measItem = actionFormat1->measInfoList.list.array[elementIdx];
2976                         switch(measItem->measType.present)
2977                         {
2978                            case MeasurementType_PR_NOTHING:
2979                               break;
2980
2981                            case MeasurementType_PR_measName:
2982                            {
2983                               free(measItem->measType.choice.measName.buf);
2984                               break;
2985                            }
2986
2987                            case MeasurementType_PR_measID:
2988                               break;
2989                         }
2990                         free(measItem);
2991                      }
2992                   }
2993                   free(actionFormat1->measInfoList.list.array);
2994                }
2995                free(actionFormat1);
2996             }
2997             break;
2998          }
2999       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format2:
3000       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format3:
3001       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format4:
3002       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format5:
3003       default:
3004          break;   
3005    }
3006 }
3007
3008 /*******************************************************************
3009  *
3010  * @brief Extract Measurement Info list from action definition
3011  *
3012  * @details
3013  *
3014  *    Function : extractMeasInfoList
3015  *
3016  * Functionality : This function :
3017  *     - Traverses Measurement-to-be-subscribed list
3018  *     - Validates that each measurement in Measurement-to-be-subscribed
3019  *       list is supported in RAN-Function->Measurement-supported list.
3020  *     - If all measurements in an action is supported by RAN function,
3021  *       it is added to measurement-subscribed list in local DB
3022  *
3023  * @params[in] Measurement Info supported list by RAN function
3024  *             Measurement Info to be subscribed as requested by RIC
3025  *             Measurement Info finally subscribed
3026  *             Memory failure indicator
3027  * @return ROK     - success
3028  *         RFAILED - failure
3029  *
3030  ******************************************************************/
3031 uint8_t extractMeasInfoList(CmLListCp *measInfoSupportedList, MeasurementInfoList_t *measInfoToBeSubscribedList, \
3032    CmLListCp *measInfoSubscribedList, bool *memFailure)
3033 {
3034    uint8_t elementIdx = 0;
3035    MeasurementInfoForAction *measInfoSupportedDb = NULLP;
3036    MeasurementInfo *measInfoSubscribedDb = NULLP;
3037    CmLList *supportedMeasNode = NULLP, *measToAddNode = NULLP;
3038    MeasurementInfoItem_t *measItem = NULLP;
3039
3040    /* Validate Measurement list is supported by E2 node. 
3041     *
3042     * Traverse and compare the Measurement-Supported List in E2
3043     * node with Measurement-to-be-subscribed list received from RIC.
3044     * If a match is found, add it to measurement-subscription list.
3045     */
3046    for(elementIdx = 0; elementIdx < measInfoToBeSubscribedList->list.count; elementIdx++)
3047    {
3048       measInfoSubscribedDb = NULLP;
3049       measToAddNode = NULLP;
3050       measItem = measInfoToBeSubscribedList->list.array[elementIdx];
3051
3052       CM_LLIST_FIRST_NODE(measInfoSupportedList, supportedMeasNode);
3053       while(supportedMeasNode)
3054       {
3055          measInfoSupportedDb = (MeasurementInfoForAction*)supportedMeasNode->node;
3056          switch(measItem->measType.present)
3057          {
3058             case MeasurementType_PR_measName:
3059                {
3060                   if(!strcmp(measInfoSupportedDb->measurementTypeName, (char *)measItem->measType.choice.measName.buf))
3061                   {
3062                      DU_ALLOC(measInfoSubscribedDb, sizeof(MeasurementInfo));
3063                   }
3064                   break;
3065                }
3066
3067             case MeasurementType_PR_measID:
3068                {
3069                   if(measInfoSupportedDb->measurementTypeId == measItem->measType.choice.measID)
3070                   {
3071                      DU_ALLOC(measInfoSubscribedDb, sizeof(MeasurementInfo));
3072                   }
3073                   break;
3074                }
3075
3076             default:
3077                {
3078                   DU_LOG("\nERROR  ->  DUAPP: Invalid Measurement-type identifier in \
3079                         E2SM-KPM Action Definition Format");
3080                   break;
3081                }
3082          } /* End of switch, for measurement type identifier */
3083
3084          /* If measurement type is supported, add to measurement-subscription list */
3085          if(measInfoSubscribedDb)
3086          {
3087             measInfoSubscribedDb->measurementTypeId = measInfoSupportedDb->measurementTypeId;
3088             memcpy(measInfoSubscribedDb->measurementTypeName, measInfoSupportedDb->measurementTypeName, \
3089                   strlen(measInfoSupportedDb->measurementTypeName));
3090
3091             DU_ALLOC(measToAddNode, sizeof(CmLList));
3092             if(measToAddNode)
3093             {
3094                measToAddNode->node = (PTR) measInfoSubscribedDb;
3095                cmLListAdd2Tail(measInfoSubscribedList, measToAddNode);
3096
3097                /* Break out of while loop if measurement info is found in measurement-supported list  */
3098                break;
3099             }
3100             else
3101             {
3102                DU_FREE(measInfoSubscribedDb, sizeof(MeasurementInfo));
3103                measInfoSubscribedDb = NULLP;
3104                *memFailure = true;
3105                break;
3106             }
3107          }
3108
3109          supportedMeasNode = supportedMeasNode->next;  
3110
3111       } /* End of while for traversing measurement-supported list in a report style */
3112
3113       /* If a measurement-to-be-subscribed is not found in measurement-supported list in this report style
3114        * Then :
3115        * Delete all entries from measurement-subscription list and
3116        * Break out of for loop to search in next report style */
3117       if(!measInfoSubscribedDb)
3118       {
3119          deleteMeasurementInfoList(measInfoSubscribedList);
3120          break;
3121       }
3122
3123    } /* End of for loop , traversing measurement-to-be-subscribed list */
3124
3125    /* If all measurement-to-be-subscribed was found in measurement-supported list and 
3126     * was added to measurement-subscription list successfully, return from here */
3127    if(measInfoToBeSubscribedList->list.count == measInfoSubscribedList->count)
3128       return ROK;
3129
3130    return RFAILED;
3131 }
3132
3133 /*******************************************************************
3134  *
3135  * @brief Extract E2SM-KPM Action definition
3136  *
3137  * @details
3138  *
3139  *    Function : extractRicActionDef
3140  *
3141  * Functionality : This function :
3142  *     - Decodes E2SM-KPM Action Definition
3143  *     - Validates that action is supported by E2 node
3144  *     - Stores action details in local DB
3145  *
3146  * @params[in] RAN Function Database structure
3147  *             RIC subscription's Action definition to be added to 
3148  *                RAN function
3149  *             RIC Action Definition buffer received from RIC
3150  * @return ROK     - success
3151  *         RFAILED - failure
3152  *
3153  ******************************************************************/
3154 uint8_t extractRicActionDef(RanFunction *ranFuncDb, ActionDefinition *actionDefDb, RICactionDefinition_t *ricActionDef,\
3155    E2FailureCause *failureCause)
3156 {
3157    bool memFailure = false;
3158    uint8_t styleIdx = 0;
3159    asn_dec_rval_t rval ={0};
3160
3161    E2SM_KPM_ActionDefinition_t actionDef, *actionDefPtr = NULLP;
3162    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
3163    CmLListCp *measInfoSupportedList = NULLP;
3164    CmLListCp *measInfoSubscribedList = NULLP;
3165
3166    /* Decoding E2SM-KPM Action Definition */
3167    actionDefPtr = &actionDef;
3168    memset(actionDefPtr, 0, sizeof(E2SM_KPM_EventTriggerDefinition_t));
3169
3170    rval = aper_decode(0, &asn_DEF_E2SM_KPM_ActionDefinition, (void **)&actionDefPtr, ricActionDef->buf,\
3171          ricActionDef->size, 0, 0);
3172    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
3173    {
3174       DU_LOG("\nERROR  -->  E2AP : ASN decode failed for E2SM-KPM Action Definition");
3175       failureCause->causeType = E2_PROTOCOL;
3176       failureCause->cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE;
3177       return RFAILED;
3178    }
3179    printf("\n");
3180    xer_fprint(stdout, &asn_DEF_E2SM_KPM_ActionDefinition, actionDefPtr);
3181
3182
3183    /* Validate if Report style to subscribe is supported by E2 Node */
3184    for(styleIdx= 0; styleIdx < ranFuncDb->numOfReportStyleSupported; styleIdx++)
3185    {
3186       /* Validate Report style type and report style format type is supported by E2 Node */
3187       if((ranFuncDb->reportStyleList[styleIdx].reportStyle.styleType == actionDefPtr->ric_Style_Type) &&
3188             (ranFuncDb->reportStyleList[styleIdx].reportStyle.formatType == actionDefPtr->actionDefinition_formats.present))
3189       {
3190          /* Fetch Report stype type and format type */
3191          actionDefDb->styleType = actionDefPtr->ric_Style_Type;
3192          actionDefDb->formatType = actionDefPtr->actionDefinition_formats.present;
3193
3194          switch(actionDefPtr->actionDefinition_formats.present)
3195          {
3196             case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
3197                {
3198                   actionFormat1 = actionDefPtr->actionDefinition_formats.choice.actionDefinition_Format1; 
3199
3200                   /* Fetch granularity period */
3201                   actionDefDb->choice.format1.granularityPeriod = actionFormat1->granulPeriod;
3202
3203                   /* Validate and add the Measurement to subscription list */
3204                   measInfoSupportedList = &ranFuncDb->reportStyleList[styleIdx].measurementInfoList;
3205                   measInfoSubscribedList = &actionDefDb->choice.format1.measurementInfoList;
3206                   if(extractMeasInfoList(measInfoSupportedList, &actionFormat1->measInfoList, \
3207                      measInfoSubscribedList, &memFailure) == ROK)
3208                   {
3209                      if(!memFailure)
3210                      {
3211                         /* Free E2SM_KPM_ActionDefinition_t */
3212                         freeAperDecodingOfRicActionDefinition(actionDefPtr);
3213                         return ROK;
3214                      }
3215                   }
3216
3217                   break;  /* End of E2SM-KPM Action definition format 1 case */
3218                }
3219
3220             default :
3221                {
3222                   DU_LOG("\nERROR  ->  DUAPP: Only E2SM-KPM Action Definition Format 1 is supported");
3223                   break;
3224                }
3225          } /* End of switch for E2SM-KPM Action definition formats */
3226       }
3227
3228       if(memFailure)
3229       {
3230          failureCause->causeType = E2_MISCELLANEOUS;
3231          failureCause->cause = E2_MISCELLANEOUS_CAUSE_UNSPECIFIED; 
3232          break;
3233       }
3234    } /* End of for loop, traversing Report-styles-supported list in E2 node */
3235
3236    /* Memset action Db and Free E2SM_KPM_ActionDefinition_t */
3237    memset(actionDefDb, 0, sizeof(ActionDefinition));
3238    freeAperDecodingOfRicActionDefinition(actionDefPtr);
3239
3240    if(failureCause->causeType == E2_NOTHING)
3241    {
3242       failureCause->causeType = E2_RIC_REQUEST;
3243       failureCause->cause = E2_ACTION_NOT_SUPPORTED;
3244    }
3245    return RFAILED;
3246 }
3247
3248 /*******************************************************************
3249  *
3250  * @brief add RIC Subs action info
3251  *
3252  * @details
3253  *
3254  *    Function : addRicSubsAction
3255  *
3256  * Functionality: add Ric Subs action info
3257  *
3258  * @parameter
3259  *    RAN function DB
3260  *    Pointer to Ric Subc info
3261  *    Action Sequence list
3262  *    Procedure Code
3263  *    E2 Failure Cause
3264  * @return ROK     - success
3265  *         RFAILED - failure
3266  *
3267  ******************************************************************/
3268
3269 CmLList *addRicSubsAction(RanFunction *ranFuncDb, PTR ricSubsInfo, CmLListCp *actionSequence, uint8_t procedureCode, E2FailureCause *failureCause)
3270 {
3271    CmLList *actionNode = NULLP;
3272    ActionInfo *actionDb = NULLP;
3273    RICactionID_t ricActionID;
3274    RICactionType_t ricActionType;
3275    RICactionDefinition_t *ricActionDefinition= NULLP;
3276    RICaction_ToBeSetup_Item_t *setupItem= NULLP;
3277    RICaction_ToBeAddedForModification_Item_t *addIem= NULLP;
3278    RICaction_ToBeModifiedForModification_Item_t *modifiedItem= NULLP;
3279
3280    switch(procedureCode)
3281    {
3282       case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item:
3283          {
3284             setupItem = (RICaction_ToBeSetup_Item_t *)ricSubsInfo;
3285             ricActionID= setupItem->ricActionID;
3286             ricActionType= setupItem->ricActionType;
3287             if(setupItem->ricActionDefinition)
3288             {
3289                ricActionDefinition = setupItem->ricActionDefinition;
3290             }
3291             break;
3292          }
3293       case ProtocolIE_IDE2_id_RICaction_ToBeAddedForModification_Item:
3294          {
3295             addIem = (RICaction_ToBeAddedForModification_Item_t*) ricSubsInfo;
3296             ricActionID= addIem->ricActionID;
3297             ricActionType= addIem->ricActionType;
3298             ricActionDefinition = &addIem->ricActionDefinition;
3299
3300             break;
3301          }
3302       case  ProtocolIE_IDE2_id_RICaction_ToBeModifiedForModification_Item:
3303          {
3304             modifiedItem= (RICaction_ToBeModifiedForModification_Item_t*)ricSubsInfo;
3305             ricActionID= modifiedItem->ricActionID;
3306             /* Added since ricActionType IE is not present in case of
3307              * modification */
3308             ricActionType = RICactionType_report;
3309             if(modifiedItem->ricActionDefinition)
3310             {
3311                ricActionDefinition = modifiedItem->ricActionDefinition;
3312             }
3313             break;
3314          }
3315    }
3316
3317
3318    DU_ALLOC(actionDb, sizeof(ActionInfo));   
3319    if(actionDb==NULLP)
3320    {
3321       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at %d",__func__,__LINE__);
3322       return NULLP;
3323    }
3324    if(ricActionType== RICactionType_report)
3325    {
3326       actionDb->actionId = ricActionID;
3327       actionDb->type = REPORT;
3328
3329       if(extractRicActionDef(ranFuncDb, &actionDb->definition, ricActionDefinition, failureCause) == ROK)
3330       {
3331          actionDb->action = CONFIG_ADD;
3332       }
3333
3334       DU_ALLOC(actionNode, sizeof(CmLList));
3335       if(actionNode)
3336       {
3337          actionNode->node = (PTR) actionDb;
3338          cmLListAdd2Tail(actionSequence, actionNode);
3339       }
3340       else
3341       {
3342          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at %d",__func__,__LINE__);
3343          DU_FREE(actionDb, sizeof(ActionInfo));
3344          return NULLP;
3345       }
3346    }
3347    return actionNode;
3348   
3349 }
3350 /*******************************************************************
3351  *
3352  * @brief Extract RIC Action to be setup
3353  *
3354  * @details
3355  *
3356  *    Function : extractRicActionToBeSetup
3357  *
3358  * Functionality : This function :
3359  *     - Validates that each action-to-be-setup is supported by E2 node
3360  *     - Stores event trigger details in local DB
3361  *
3362  * @params[in] RAN Function Database structure
3363  *             RIC Subscription Info to be added to RAN function
3364  *             RIC Action To Be Setup List received from RIC
3365  * @return ROK     - success
3366  *         RFAILED - failure
3367  *
3368  ******************************************************************/
3369 uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \
3370    RICactions_ToBeSetup_List_t *actionList, E2FailureCause *failureCause, PendingSubsRspInfo *subsRsp)
3371 {
3372    CmLList *actionNode = NULLP;
3373    uint8_t actionIdx = 0;
3374    uint8_t ricActionId = 0;
3375    RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
3376
3377    if(actionList->list.array)
3378    {
3379       for(actionIdx = 0; actionIdx < actionList->list.count; actionIdx++)
3380       {
3381          actionItem =(RICaction_ToBeSetup_ItemIEs_t *)actionList->list.array[actionIdx];
3382          switch(actionItem->id)
3383          {
3384             case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item:
3385                {
3386                   /* If Action type is REPORT and 
3387                    * If RIC action definition's extraction and validation passes, 
3388                    * Then : 
3389                    * This action is added to action sequence list of subscription info */
3390                   actionNode = addRicSubsAction(ranFuncDb, (PTR)&actionItem->value.choice.RICaction_ToBeSetup_Item,\
3391                   &ricSubscriptionInfo->actionSequence, ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item, failureCause);
3392                   
3393                   if(!actionNode)
3394                   {
3395                      /* In case of any failure, action is rejected
3396                       * Added to rejected-action-list in subscription response */
3397                      subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].id = ricActionId;
3398                      if(failureCause->causeType == E2_NOTHING)
3399                      {
3400                         failureCause->causeType = E2_RIC_REQUEST;
3401                         failureCause->cause = E2_CONTROL_FAILED_TO_EXECUTE;
3402                      }
3403                      memcpy(&subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].failureCause, \
3404                            failureCause, sizeof(E2FailureCause));
3405                      subsRsp->numOfRejectedActions++;
3406                   }
3407                   break;
3408                }
3409             default:
3410                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id);
3411                break;
3412          }
3413       }
3414    }
3415
3416    /* If there is even 1 action that can be added, return ROK */
3417    if(ricSubscriptionInfo->actionSequence.count)
3418       return ROK;
3419
3420    if(failureCause->causeType == E2_NOTHING)
3421    {
3422       failureCause->causeType = E2_RIC_REQUEST;
3423       failureCause->cause = E2_ACTION_NOT_SUPPORTED;
3424    }
3425    return RFAILED;
3426 }
3427
3428 /******************************************************************
3429  *
3430  * @brief Processes RIC Subscription Req sent by RIC
3431  *
3432  * @details
3433  *
3434  *    Function : procRicSubscriptionRequest
3435  *
3436  *    Functionality: Processes RIC Subscription Request from RIC
3437  *
3438  * @params[in] E2AP_PDU_t ASN decoded E2AP message
3439  * @return ROK     - success
3440  *         RFAILED - failure
3441  *
3442  * ****************************************************************/
3443 uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg)
3444 {
3445    uint8_t idx = 0; 
3446    uint8_t ret = ROK;
3447    uint16_t ranFuncId = 0;
3448    RicRequestId ricReqId;
3449    CmLList  *ricSubscriptionNode = NULLP;
3450    RanFunction *ranFuncDb = NULLP;
3451    RICsubscriptionRequest_t *ricSubsReq = NULLP;
3452    RICsubscriptionDetails_t *subsDetails = NULLP;
3453    RicSubscription *ricSubscriptionInfo = NULLP;
3454    E2FailureCause failureCause;
3455
3456    DU_LOG("\nINFO   -->  E2AP : RIC Subscription request received"); 
3457
3458    memset(&failureCause, 0, sizeof(E2FailureCause));
3459    memset(&ricReqId, 0, sizeof(RicRequestId));
3460
3461    ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
3462    for(idx=0; idx<ricSubsReq->protocolIEs.list.count; idx++)
3463    {
3464       if(ricSubsReq->protocolIEs.list.array[idx])
3465       {
3466          switch(ricSubsReq->protocolIEs.list.array[idx]->id)
3467          {
3468             case ProtocolIE_IDE2_id_RICrequestID:
3469                {
3470                   ricReqId.requestorId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID;
3471                   ricReqId.instanceId  = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID;
3472
3473                   break;
3474                }
3475
3476             case ProtocolIE_IDE2_id_RANfunctionID:
3477                {
3478                   ranFuncId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID; 
3479
3480                   /* Validating RAN Function id */
3481                   ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
3482
3483                   if(!ranFuncDb)
3484                   {
3485                      failureCause.causeType = E2_RIC_REQUEST;
3486                      failureCause.cause = E2_RAN_FUNCTION_ID_INVALID;
3487                      ret = RFAILED;
3488                      break;
3489                   }
3490
3491                   if(ranFuncDb->numPendingSubsRsp >= MAX_PENDING_SUBSCRIPTION_RSP)
3492                   {
3493                      failureCause.causeType = E2_RIC_REQUEST;
3494                      failureCause.cause = E2_FUNCTION_RESOURCE_LIMIT; 
3495                      ret = RFAILED;
3496                      break;
3497                   }
3498
3499                   DU_ALLOC(ricSubscriptionInfo, sizeof(RicSubscription));
3500                   if(!ricSubscriptionInfo)
3501                   {
3502                      DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for ricSubscriptionInfo");
3503                      failureCause.causeType = E2_MISCELLANEOUS;
3504                      failureCause.cause = E2_MISCELLANEOUS_CAUSE_UNSPECIFIED;
3505                      ret = RFAILED;
3506                      break;
3507                   }
3508                   ricSubscriptionInfo->requestId.requestorId = ricReqId.requestorId;
3509                   ricSubscriptionInfo->requestId.instanceId = ricReqId.instanceId;
3510                   ricSubscriptionInfo->ranFuncId = ranFuncId;
3511
3512                   memset(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp], 0, sizeof(PendingSubsRspInfo));
3513                   memcpy(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp].requestId, 
3514                         &ricReqId, sizeof(RicRequestId));
3515                   ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp].ranFuncId = ranFuncId;
3516                   break;
3517                }
3518
3519             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
3520                {
3521                   subsDetails = &ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails;
3522
3523                   /* Decode, Validate and record Event Trigger Definition */
3524                   if(extractEventTriggerDef(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricEventTriggerDefinition, \
3525                      &failureCause) != ROK)
3526                   {
3527                      ret = RFAILED;
3528                      break;
3529                   }
3530
3531                   /* Decode, Validate and record RIC actions */
3532                   if(extractRicActionToBeSetup(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricAction_ToBeSetup_List, \
3533                      &failureCause, &ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp]) != ROK)
3534                   {
3535                      ret = RFAILED;
3536                      break;
3537                   }
3538                }
3539                break;
3540
3541             default:
3542                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RIC SubsReq:%ld",
3543                      ricSubsReq->protocolIEs.list.array[idx]->id);
3544                break;
3545          }
3546
3547          if(ret == RFAILED)
3548             break;
3549       }
3550    }
3551
3552    freeAperDecodingOfRicSubsReq(ricSubsReq);
3553
3554    if(ret == ROK)
3555    {
3556       cmInitTimers(&(ricSubscriptionInfo->ricSubsReportTimer), 1);
3557       ricSubscriptionInfo->action = CONFIG_ADD;
3558
3559       /* Add RAN subcription detail to RAN function */
3560       DU_ALLOC(ricSubscriptionNode, sizeof(CmLList));
3561       if(ricSubscriptionNode)
3562       {
3563          ricSubscriptionNode->node = (PTR) ricSubscriptionInfo;
3564          cmLListAdd2Tail(&ranFuncDb->subscriptionList, ricSubscriptionNode);
3565       }
3566
3567       ranFuncDb->numPendingSubsRsp++;
3568
3569 #ifdef KPI_CALCULATION
3570       /* Send statistics request to other DU entities */
3571       BuildAndSendStatsReq(ricSubscriptionInfo);
3572 #endif      
3573    }
3574    else
3575    {
3576       DU_FREE(ricSubscriptionInfo, sizeof(RicSubscription));
3577
3578       if(ranFuncDb)
3579       {
3580          memset(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp], 0, sizeof(PendingSubsRspInfo));
3581       }
3582
3583       /* Send RIC Subcription Failure */
3584       BuildAndSendRicSubscriptionFailure(ricReqId, ranFuncId, failureCause);
3585    }
3586    return ret;
3587 }
3588
3589 /******************************************************************
3590  *
3591  * @brief Free RIC Subscription Failure
3592  *
3593  * @details
3594  *
3595  *    Function : FreeRicSubscriptionFailure
3596  *
3597  *    Functionality: Free RIC Subscription Failure
3598  *
3599  * @params[in] E2AP PDU
3600  * @return void
3601  *
3602  * ****************************************************************/
3603 void FreeRicSubscriptionFailure(E2AP_PDU_t *e2apMsg)
3604 {
3605    uint8_t elemIdx = 0;
3606    RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP;
3607
3608    if(e2apMsg)
3609    {
3610       if(e2apMsg->choice.unsuccessfulOutcome)
3611       {
3612          ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
3613          if(ricSubscriptionFailure->protocolIEs.list.array)
3614          {
3615             for(elemIdx = 0; elemIdx < ricSubscriptionFailure->protocolIEs.list.count; elemIdx++)
3616             {
3617                DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t));
3618             }
3619             DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size);
3620          }
3621          DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
3622       }
3623       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3624    }
3625 }
3626
3627 /******************************************************************
3628  *
3629  * @brief Fill and Send RIC Subscription Failure to RIC
3630  *
3631  * @details
3632  *
3633  *    Function : BuildAndSendRicSubscriptionFailure
3634  *
3635  *    Functionality: Fill and Send RIC Subscription Failure to RIC
3636  *
3637  * @params[in] RIC Request ID
3638  *             RAN Function ID
3639  *             Cause of Failure
3640  * @return ROK     - success
3641  *         RFAILED - failure
3642  *
3643  * ****************************************************************/
3644 uint8_t BuildAndSendRicSubscriptionFailure(RicRequestId ricReqId, uint16_t ranFuncId, E2FailureCause failureCause)
3645 {
3646    uint8_t          ret = RFAILED;
3647    uint8_t          elementCnt = 0, elemIdx = 0;
3648    E2AP_PDU_t       *e2apMsg = NULLP;
3649    asn_enc_rval_t   encRetVal;        /* Encoder return value */
3650    RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP;
3651    RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
3652
3653    while(true)
3654    {
3655       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Failure\n");
3656
3657       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3658       if(e2apMsg == NULLP)
3659       {
3660          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
3661          break;
3662       }
3663
3664       e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome;
3665       DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
3666       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
3667       {
3668          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
3669          break;
3670       }
3671       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
3672       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
3673       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure;
3674
3675       ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
3676
3677       elementCnt = 3;
3678       ricSubscriptionFailure->protocolIEs.list.count = elementCnt;
3679       ricSubscriptionFailure->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionFailure_IEs_t *);
3680       DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size);
3681       if(!ricSubscriptionFailure->protocolIEs.list.array)
3682       {
3683          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
3684          break;
3685       }
3686
3687       for(elemIdx = 0; elemIdx < elementCnt; elemIdx++)
3688       {
3689          DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t));
3690          if(!ricSubscriptionFailure->protocolIEs.list.array[elemIdx])
3691          {
3692             DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d] for IE at index [%d]", \
3693                __func__, __LINE__, elemIdx);
3694             break;
3695          }
3696       }
3697       if(elemIdx < elementCnt)
3698          break;
3699
3700       elemIdx = 0;
3701
3702       /* RIC Request ID */
3703       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
3704       ricSubsFailIe->id = ProtocolIE_IDE2_id_RICrequestID;
3705       ricSubsFailIe->criticality = CriticalityE2_reject;
3706       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RICrequestID;
3707       ricSubsFailIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
3708       ricSubsFailIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
3709
3710       /* RAN Function ID */
3711       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
3712       ricSubsFailIe->id = ProtocolIE_IDE2_id_RANfunctionID;
3713       ricSubsFailIe->criticality = CriticalityE2_reject;
3714       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RANfunctionID;
3715       ricSubsFailIe->value.choice.RANfunctionID = ranFuncId;
3716
3717       /* Cause */
3718       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
3719       ricSubsFailIe->id = ProtocolIE_IDE2_id_CauseE2;
3720       ricSubsFailIe->criticality = CriticalityE2_reject;
3721       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_CauseE2;
3722       fillE2Cause(&ricSubsFailIe->value.choice.CauseE2, failureCause);
3723
3724       /* Prints the Msg formed */
3725       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3726       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3727       encBufSize = 0;
3728       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3729       if(encRetVal.encoded == ENCODE_FAIL)
3730       {
3731          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Failure Message (at %s)\n",\
3732                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3733          break;
3734       }
3735       else
3736       {
3737          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Failure Message \n");
3738 #ifdef DEBUG_ASN_PRINT
3739          for(int i=0; i< encBufSize; i++)
3740          {
3741             printf("%x",encBuf[i]);
3742          }
3743 #endif
3744       }
3745
3746       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
3747       {
3748          DU_LOG("\nINFO   -->  E2AP : Sending RIC Subscription Failure");
3749
3750       }
3751       ret = ROK;
3752       break;
3753    }
3754    FreeRicSubscriptionFailure(e2apMsg);
3755    return ret;
3756 }
3757
3758 /*******************************************************************
3759  *
3760  * @brief Free the RicIndication Message
3761  *
3762  * @details
3763  *
3764  *    Function : FreeRicIndication
3765  *
3766  * Functionality: Free the RicIndication Message
3767  *
3768  * @return void
3769  *         
3770  *
3771  ******************************************************************/
3772 void FreeRicIndication(E2AP_PDU_t  *e2apMsg) 
3773 {
3774    uint8_t idx = 0;
3775    RICindication_t *ricIndicationMsg= NULLP;
3776
3777    if(e2apMsg != NULLP)
3778    {
3779       if(e2apMsg->choice.initiatingMessage != NULLP)
3780       {
3781          ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
3782          if(ricIndicationMsg!= NULLP)
3783          {
3784             if(ricIndicationMsg->protocolIEs.list.array != NULLP)
3785             {
3786                for(idx=0; idx<ricIndicationMsg->protocolIEs.list.count; idx++)
3787                {
3788                   if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP)
3789                   {
3790                      switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
3791                      {
3792                         case ProtocolIE_IDE2_id_RICrequestID:
3793                         case ProtocolIE_IDE2_id_RANfunctionID:
3794                         case ProtocolIE_IDE2_id_RICactionID:
3795                         case ProtocolIE_IDE2_id_RICindicationType:
3796                            break;
3797
3798                         case ProtocolIE_IDE2_id_RICindicationHeader:
3799                            {
3800                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\
3801                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
3802                               break;
3803                            }
3804                         case ProtocolIE_IDE2_id_RICindicationMessage:
3805                            {
3806                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\
3807                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
3808                               break;
3809                            }
3810                         default:
3811                            break;
3812                      }
3813                      DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t));
3814                   }
3815                }
3816                DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size);
3817             }
3818          }
3819          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3820       }
3821       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3822    }
3823 }
3824
3825 /*******************************************************************
3826  *
3827  * @brief Free measurement record
3828  *
3829  * @details
3830  *
3831  *    Function : freeMeasRecord
3832  *
3833  * Functionality: Free all measurement recorded for a measurement
3834  *    within an action in a RIC subscription
3835  *
3836  * @param  Measurement data to be freed
3837  * @return void
3838  *
3839  ******************************************************************/
3840 void freeMeasData(MeasurementData_t *measData)
3841 {
3842    uint8_t measIdx = 0, measRecIdx = 0;
3843    MeasurementRecord_t *measRecord = NULLP;
3844
3845    if(measData->list.array)
3846    {
3847       for(measIdx = 0; measIdx < measData->list.count; measIdx++)
3848       {
3849          if(measData->list.array[measIdx])
3850          {
3851             measRecord = &measData->list.array[measIdx]->measRecord;
3852             if(measRecord->list.array)
3853             {
3854                for(measRecIdx = 0; measRecIdx < measRecord->list.count; measRecIdx++)
3855                {
3856                   DU_FREE(measRecord->list.array[measRecIdx], sizeof(MeasurementRecordItem_t));
3857                }
3858                DU_FREE(measRecord->list.array, measRecord->list.size);
3859             }
3860             DU_FREE(measData->list.array[measIdx], sizeof(MeasurementDataItem_t));
3861          }
3862       }
3863       DU_FREE(measData->list.array, measData->list.size);
3864    }
3865 }
3866
3867 /*******************************************************************
3868  *
3869  * @brief Fill measurement info list
3870  *
3871  * @details
3872  *
3873  *    Function : freeMeasInfoList
3874  *
3875  * Functionality: Fills all measurement info within an action 
3876  *    in a RIC subscription
3877  *
3878  * @param  Measurement Info list to be freed
3879  * @return void
3880  *
3881  ******************************************************************/
3882 void freeMeasInfoList(MeasurementInfoList_t *measInfoList)
3883 {
3884    uint8_t measInfoIdx = 0;
3885
3886    if(measInfoList->list.array)
3887    {
3888       for(measInfoIdx = 0; measInfoIdx < measInfoList->list.count; measInfoIdx++)
3889       {
3890          if(measInfoList->list.array[measInfoIdx])
3891          {
3892             DU_FREE(measInfoList->list.array[measInfoIdx]->measType.choice.measName.buf, \
3893                   measInfoList->list.array[measInfoIdx]->measType.choice.measName.size);
3894
3895             DU_FREE(measInfoList->list.array[measInfoIdx], measInfoList->list.size);
3896          }
3897       }
3898       DU_FREE(measInfoList->list.array, measInfoList->list.size);
3899    }
3900 }
3901
3902 /*******************************************************************
3903  *
3904  * @brief Free E2SM-KPM Indication Message
3905  *
3906  * @details
3907  *
3908  *    Function : FreeE2smKpmIndicationMessage
3909  *
3910  * Functionality: Free E2SM-KPM Indication Message
3911  *
3912  * @param  E2SM-KPM Indication message to be freed
3913  * @return void
3914  *
3915  ******************************************************************/
3916 void FreeE2smKpmIndicationMessage(E2SM_KPM_IndicationMessage_t *e2smKpmIndMsg)
3917 {
3918    E2SM_KPM_IndicationMessage_Format1_t *format1Msg = NULLP;
3919
3920    switch(e2smKpmIndMsg->indicationMessage_formats.present)
3921    {
3922       case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format1:
3923          {
3924             if(e2smKpmIndMsg->indicationMessage_formats.choice.indicationMessage_Format1)
3925             {
3926                format1Msg = e2smKpmIndMsg->indicationMessage_formats.choice.indicationMessage_Format1;
3927                
3928                /* Measurement Data */
3929                freeMeasData(&format1Msg->measData);
3930
3931                /* Measurement Info List */
3932                if(format1Msg->measInfoList)
3933                {
3934                   freeMeasInfoList(format1Msg->measInfoList);
3935                   DU_FREE(format1Msg->measInfoList, sizeof(MeasurementInfoList_t));
3936                }
3937
3938                /* Granularity Period */
3939                DU_FREE(format1Msg->granulPeriod, sizeof(GranularityPeriod_t));
3940
3941                DU_FREE(format1Msg, sizeof(E2SM_KPM_IndicationMessage_Format1_t));
3942             }
3943             break;
3944          }
3945
3946       case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_NOTHING:
3947       case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format2:
3948       default:
3949          break;
3950    }
3951 }
3952
3953 /*******************************************************************
3954  *
3955  * @brief Fill measurement record
3956  *
3957  * @details
3958  *
3959  *    Function : fillMeasRecord
3960  *
3961  * Functionality: Fills all measurement value for a measurement
3962  *    within an action in a RIC subscription
3963  *
3964  * @param  Measurement record to be filled
3965  *         Measurement database with measurement records
3966  * @return ROK     - success
3967  *         RFAILED - failure
3968  *
3969  ******************************************************************/
3970 uint8_t fillMeasRecord(MeasurementRecord_t *measRecord, MeasurementInfo *measInfoDb)
3971 {
3972    uint8_t measRecIdx = 0;
3973    CmLList *measValNode = NULLP;
3974    double  measVal = 0;
3975
3976    measRecord->list.count = measInfoDb->measuredValue.count;
3977    measRecord->list.size = measRecord->list.count * sizeof(MeasurementRecordItem_t *);
3978
3979    DU_ALLOC(measRecord->list.array, measRecord->list.size);
3980    if(!measRecord->list.array)
3981    {
3982       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3983       return RFAILED;
3984    }
3985
3986    for(measRecIdx = 0; measRecIdx < measRecord->list.count; measRecIdx++)
3987    {
3988       DU_ALLOC(measRecord->list.array[measRecIdx], sizeof(MeasurementRecordItem_t));
3989       if(!measRecord->list.array[measRecIdx])
3990       {
3991          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3992          return RFAILED;
3993       }
3994    }
3995
3996    measRecIdx = 0;
3997    CM_LLIST_FIRST_NODE(&measInfoDb->measuredValue, measValNode);
3998    while(measValNode)
3999    {
4000      measVal = *(double *)measValNode->node;
4001      if(measVal == (int)measVal)
4002      {
4003         measRecord->list.array[measRecIdx]->present = MeasurementRecordItem_PR_integer;
4004         measRecord->list.array[measRecIdx]->choice.integer = (int)measVal;
4005      }
4006      else
4007      {
4008          measRecord->list.array[measRecIdx]->present = MeasurementRecordItem_PR_real;
4009          measRecord->list.array[measRecIdx]->choice.real = measVal;
4010      }
4011      measRecIdx++;
4012      measValNode= measValNode->next;  
4013      /* Once the measurement record is added to the message, delete it from DB */
4014      measVal = 0;
4015    }
4016    deleteMeasuredValueList(&measInfoDb->measuredValue);
4017    return ROK;
4018 }
4019
4020 /*******************************************************************
4021  *
4022  * @brief Fills measuerement data
4023  *
4024  * @details
4025  *
4026  *    Function : fillMeasData
4027  *
4028  * Functionality: Fill all measurement recorded for all measurements
4029  *    in an action in a RIC subscription
4030  *
4031  * @param  Measurement data to be filled
4032  *         Measurement info list from an action DB
4033  * @return ROK     - success
4034  *         RFAILED - failure
4035  *
4036  ******************************************************************/
4037 uint8_t fillMeasData(MeasurementData_t *measData, CmLListCp *measInfoListDb)
4038 {
4039   uint8_t measIdx = 0;
4040   CmLList *measInfoNode = NULLP;
4041   MeasurementInfo *measInfoDb = NULLP;
4042   MeasurementRecord_t *measRecord = NULLP;
4043
4044   measData->list.count = measInfoListDb->count;
4045   measData->list.size = measData->list.count * sizeof(MeasurementDataItem_t *);
4046
4047   DU_ALLOC(measData->list.array, measData->list.size);
4048   if(!measData->list.array)
4049   {
4050      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4051      return RFAILED;
4052   }
4053
4054   measIdx = 0;
4055   CM_LLIST_FIRST_NODE(measInfoListDb, measInfoNode);
4056   while(measInfoNode)
4057   {
4058      measInfoDb = (MeasurementInfo *)measInfoNode->node;
4059      if(measInfoDb)
4060      {
4061         DU_ALLOC(measData->list.array[measIdx], sizeof(MeasurementDataItem_t));
4062         if(!measData->list.array[measIdx])
4063         {
4064            DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4065            return RFAILED;
4066         }
4067
4068         measRecord = &measData->list.array[measIdx]->measRecord;
4069         if(fillMeasRecord(measRecord, measInfoDb) != ROK)
4070         {
4071            DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement record");
4072            return RFAILED;
4073         }
4074         measIdx++;
4075      }
4076      measInfoNode = measInfoNode->next;
4077   }
4078
4079   return ROK;
4080 }
4081
4082 /*******************************************************************
4083  *
4084  * @brief Fill all measurement info
4085  *
4086  * @details
4087  *
4088  *    Function : fillMeasInfoList
4089  *
4090  * Functionality: Fills all measurement info belonging to an action
4091  *  in a RIC subscription
4092  *
4093  * @param   Measurement Info list to be filled
4094  *          Measurement Info list from E2AP DB
4095  * @return ROK     - success
4096  *         RFAILED - failure
4097  *
4098  ******************************************************************/
4099 uint8_t fillMeasInfoList(MeasurementInfoList_t *measInfoList, CmLListCp *measInfoListDb)
4100 {
4101    uint8_t measInfoIdx = 0;
4102    CmLList *measInfoNode = NULLP;
4103    MeasurementInfo *measInfoDb = NULLP;
4104    MeasurementInfoItem_t *measInfoItem = NULLP;
4105
4106    measInfoList->list.count = measInfoListDb->count;
4107    measInfoList->list.size = measInfoList->list.count * sizeof(MeasurementInfoItem_t *);
4108
4109    DU_ALLOC(measInfoList->list.array, measInfoList->list.size);
4110    if(!measInfoList->list.array)
4111    {
4112       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4113       return RFAILED;
4114    }
4115
4116    measInfoIdx = 0;
4117    CM_LLIST_FIRST_NODE(measInfoListDb, measInfoNode);
4118    while(measInfoNode)
4119    {
4120       DU_ALLOC(measInfoList->list.array[measInfoIdx], sizeof(MeasurementInfoItem_t));
4121       if(!measInfoList->list.array[measInfoIdx])
4122       {
4123          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4124          return RFAILED;
4125       }
4126
4127       measInfoItem = measInfoList->list.array[measInfoIdx];
4128       measInfoDb = (MeasurementInfo *)measInfoNode->node;
4129       if(measInfoDb)
4130       {
4131          /* Measurement Type */
4132          measInfoItem->measType.present = MeasurementType_PR_measName;
4133          measInfoItem->measType.choice.measName.size = strlen(measInfoDb->measurementTypeName);
4134
4135          DU_ALLOC(measInfoItem->measType.choice.measName.buf, measInfoItem->measType.choice.measName.size);
4136          if(!measInfoItem->measType.choice.measName.buf)
4137          {
4138             DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4139             return RFAILED;
4140          }
4141
4142          memcpy(measInfoItem->measType.choice.measName.buf, measInfoDb->measurementTypeName,\
4143             measInfoItem->measType.choice.measName.size);
4144
4145          measInfoIdx++;
4146       }
4147       measInfoNode = measInfoNode->next;
4148       measInfoDb = NULLP;
4149    }
4150
4151    return ROK;
4152 }
4153
4154  /*******************************************************************
4155  *
4156  * @brief Fill E2SM-KPM Indication Message Format 1
4157  *
4158  * @details
4159  *
4160  *    Function : fillE2smKpmIndMsgFormat1
4161  *
4162  * Functionality: Fill E2SM-KPM Indication Message Format 1
4163  *
4164  * @param  Format 1 Message to be filled
4165  *         Action Definition format 1 from E2AP DB
4166  * @return ROK     - success
4167  *         RFAILED - failure
4168  *
4169  ******************************************************************/
4170 uint8_t fillE2smKpmIndMsgFormat1(E2SM_KPM_IndicationMessage_Format1_t *format1Msg, ActionDefFormat1 *format1)
4171 {
4172   /* Measurement Data */
4173   if(fillMeasData(&format1Msg->measData, &format1->measurementInfoList) != ROK)
4174   {
4175      DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement data");
4176      return RFAILED;
4177   }
4178
4179   /* Measurement Information */
4180   DU_ALLOC(format1Msg->measInfoList, sizeof(MeasurementInfoList_t));
4181   if(!format1Msg->measInfoList)
4182   {
4183      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4184      return RFAILED;
4185   }
4186
4187   if(fillMeasInfoList(format1Msg->measInfoList, &format1->measurementInfoList) != ROK)
4188   {
4189      DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement information list");
4190      return RFAILED;
4191   }
4192
4193   /* Granularity Period */
4194   DU_ALLOC(format1Msg->granulPeriod, sizeof(GranularityPeriod_t));
4195   if(!format1Msg->granulPeriod)
4196   {
4197      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4198      return RFAILED;
4199   }
4200   *(format1Msg->granulPeriod) = format1->granularityPeriod;
4201
4202   return ROK;
4203 }
4204
4205 /*******************************************************************
4206  *
4207  * @brief Fill RIC Indication Message buffer
4208  *
4209  * @details
4210  *
4211  *    Function : fillRicIndMsgBuf
4212  *
4213  * Functionality: Fill E2SM-KPM Indication Message
4214  *    Encode this message and copy to RIC Indication Message buffer
4215  * 
4216  * @param  RIC Indication Message buffer to be filled
4217  *         Source action info from E2AP DB
4218  * @return ROK     - success
4219  *         RFAILED - failure
4220  *
4221  ******************************************************************/
4222 uint8_t fillRicIndMsgBuf(RICindicationMessage_t *ricIndMsgBuf, ActionInfo *actionInfo)
4223 {
4224    uint8_t ret = RFAILED;
4225    bool failedInFormat = false;
4226    E2SM_KPM_IndicationMessage_t e2smKpmIndMsg;
4227    asn_enc_rval_t   encRetVal;        /* Encoder return value */
4228
4229    memset(&e2smKpmIndMsg, 0, sizeof(E2SM_KPM_IndicationMessage_t));
4230
4231    while(true)
4232    {
4233       /* E2SM-KPM Indication message format type */
4234       e2smKpmIndMsg.indicationMessage_formats.present = actionInfo->definition.formatType;
4235       switch(e2smKpmIndMsg.indicationMessage_formats.present)
4236       {
4237          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format1:
4238             {
4239                /* E2SM-KPM Indication message format 1 */
4240                DU_ALLOC(e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1, \
4241                      sizeof(E2SM_KPM_IndicationMessage_Format1_t));
4242                if(!e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1)
4243                {
4244                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4245                   failedInFormat = true;
4246                   break;
4247                }
4248
4249                if(fillE2smKpmIndMsgFormat1(e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1, \
4250                   &actionInfo->definition.choice.format1) != ROK)
4251                {
4252                   DU_LOG("\nERROR  -->  E2AP : Failed to fill E2SM-KPM Indication message format 1");
4253                   failedInFormat = true;
4254                   break;
4255                }
4256                break;
4257             }
4258
4259          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_NOTHING:
4260          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format2:
4261          default:
4262             {
4263                DU_LOG("\nERROR  -->  E2AP : fillRicIndMsgBuf: Only Format 1 supported");
4264                failedInFormat = true;
4265                break;
4266             }
4267       }
4268
4269       if(failedInFormat)
4270          break;
4271
4272       /* Encode E2SM-KPM Indication Message */
4273       xer_fprint(stdout, &asn_DEF_E2SM_KPM_IndicationMessage, &e2smKpmIndMsg);
4274       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4275       encBufSize = 0;
4276       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_IndicationMessage, 0, &e2smKpmIndMsg, PrepFinalEncBuf, encBuf);
4277       if(encRetVal.encoded == ENCODE_FAIL)
4278       {
4279          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM Indication Message (at %s)\n",\
4280                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4281          break;
4282       }
4283       else
4284       {
4285          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SM-KPM Indication Message \n");
4286 #ifdef DEBUG_ASN_PRINT
4287          for(int i=0; i< encBufSize; i++)
4288          {
4289             printf("%x",encBuf[i]);
4290          } 
4291 #endif
4292       }
4293
4294       /* Copy encoded string to RIC Indication Message buffer */
4295       ricIndMsgBuf->size = encBufSize;
4296       DU_ALLOC(ricIndMsgBuf->buf, ricIndMsgBuf->size);
4297       if(!ricIndMsgBuf->buf)
4298       {
4299          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4300          break;
4301       }
4302       memset(ricIndMsgBuf->buf, 0, ricIndMsgBuf->size);
4303       memcpy(ricIndMsgBuf->buf, encBuf, encBufSize);
4304
4305       ret = ROK;
4306       break;
4307    }
4308
4309    /* Free E2SM-KPM Indication Message */
4310    FreeE2smKpmIndicationMessage(&e2smKpmIndMsg);
4311
4312    return ret;
4313 }
4314
4315 /*******************************************************************
4316  *
4317  * @brief Free E2SM-KPM Indication Header
4318  *
4319  * @details
4320  *
4321  *    Function : FreeE2smKpmIndicationHeader
4322  *
4323  * Functionality: Free E2SM-KPM Indication Header
4324  * 
4325  * @param  E2SM-KPM Indication Header to be free
4326  * @return void
4327  *
4328  ******************************************************************/
4329 void FreeE2smKpmIndicationHeader(E2SM_KPM_IndicationHeader_t *e2smKpmIndHdr)
4330 {
4331    E2SM_KPM_IndicationHeader_Format1_t *format1 = NULLP;
4332
4333    if(e2smKpmIndHdr)
4334    {
4335       switch(e2smKpmIndHdr->indicationHeader_formats.present)
4336       {
4337          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_indicationHeader_Format1:
4338             {
4339                if(e2smKpmIndHdr->indicationHeader_formats.choice.indicationHeader_Format1)
4340                {
4341                   format1 = e2smKpmIndHdr->indicationHeader_formats.choice.indicationHeader_Format1;
4342
4343                   DU_FREE(format1->colletStartTime.buf, format1->colletStartTime.size);
4344                   DU_FREE(format1, sizeof(E2SM_KPM_IndicationHeader_Format1_t));
4345                }
4346                break;
4347             }
4348          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_NOTHING:
4349          default:
4350             break;
4351       }
4352    }
4353 }
4354
4355 /*******************************************************************
4356  *
4357  * @brief Fill RIC Indication Header buffer
4358  *
4359  * @details
4360  *
4361  *    Function : fillRicIndHeader
4362  *
4363  * Functionality: Fill E2SM-KPM Indication Header
4364  *    Encode this message and copy to RIC Indication Header buffer
4365  * 
4366  * @param  RIC Indication Header buffer to be filled
4367  *         Source RIC subscription info from E2AP DB
4368  * @return ROK     - success
4369  *         RFAILED - failure
4370  *
4371  ******************************************************************/
4372 uint8_t fillRicIndHeader(RICindicationHeader_t *ricIndHdr, RicSubscription *ricSubsInfo)
4373 {
4374    uint8_t ret = RFAILED;
4375    uint8_t secBufIdx = 0, milliSecBufIdx = 0;
4376    int8_t byteIdx = 0;
4377    bool formatFailure = false;
4378    RanFunction *ranFunc = NULLP;
4379    ReportStartTime *startTime = NULLP;
4380    E2SM_KPM_IndicationHeader_t e2smKpmIndHdr;
4381    E2SM_KPM_IndicationHeader_Format1_t *format1 = NULLP;
4382    asn_enc_rval_t   encRetVal;        /* Encoder return value */
4383
4384    while(true)
4385    {
4386       ranFunc = fetchRanFuncFromRanFuncId(ricSubsInfo->ranFuncId);
4387       if(ranFunc == NULLP)
4388       {
4389          DU_LOG("\nERROR  -->  E2AP : RAN Function ID [%d] not found", ricSubsInfo->ranFuncId);
4390          break;
4391       }
4392
4393       memset(&e2smKpmIndHdr, 0, sizeof(E2SM_KPM_IndicationHeader_t));
4394
4395       e2smKpmIndHdr.indicationHeader_formats.present = ranFunc->ricIndicationHeaderFormat;
4396       switch(e2smKpmIndHdr.indicationHeader_formats.present)
4397       {
4398          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_indicationHeader_Format1:
4399             {
4400                DU_ALLOC(e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1, \
4401                      sizeof(E2SM_KPM_IndicationHeader_Format1_t));
4402                if(!e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1)
4403                {
4404                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4405                   formatFailure = true;
4406                   break;
4407                }
4408                format1 = e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1;
4409
4410                /* Fetch reporting period start time from DB */
4411                switch(ricSubsInfo->eventTriggerDefinition.formatType)
4412                {
4413                   case 1:
4414                   {
4415                      startTime = &ricSubsInfo->eventTriggerDefinition.choice.format1.startTime;
4416                   }
4417                }
4418
4419                format1->colletStartTime.size = 8 * sizeof(uint8_t);
4420                DU_ALLOC(format1->colletStartTime.buf, format1->colletStartTime.size);
4421                if(!format1->colletStartTime.buf)
4422                {
4423                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4424                   formatFailure = true;
4425                   break;
4426                }
4427
4428                /* As per O-RAN.WG3.E2SM-KPM-R003-v03.00, section 8.3.12 and
4429                 * RFC 5905, section 6 :
4430                 * Time stamp has a 64-bit format where first 32-bit is seconds
4431                 * and next 32-bit is fraction in picosecond-level.
4432                 * This fraction has been rounded in microseconds.
4433                 *
4434                 * Hence,
4435                 * Storing 32-bit seconds at MSB 0-3 and
4436                 * 32-bit milliseconds at next 4 bytes i.e. bytes 4-7
4437                 */
4438                secBufIdx = 0;
4439                milliSecBufIdx = 4;
4440                for(byteIdx = 3; byteIdx >= 0; byteIdx--)
4441                {
4442                   format1->colletStartTime.buf[secBufIdx++] = startTime->timeInSec >> (8*byteIdx);
4443                   format1->colletStartTime.buf[milliSecBufIdx++] = startTime->timeInMilliSec >> (8*byteIdx);
4444                }
4445                break;
4446             }
4447
4448          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_NOTHING:
4449          default:
4450          {
4451              DU_LOG("\nERROR  -->  E2AP : Only E2SM-KPM Indication Header Format 1 supported");
4452              formatFailure = true;
4453              break;
4454          }
4455       }
4456
4457       if(formatFailure)
4458          break;
4459
4460       /* Encode E2SM-KPM Indication Header */
4461       xer_fprint(stdout, &asn_DEF_E2SM_KPM_IndicationHeader, &e2smKpmIndHdr);
4462       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4463       encBufSize = 0;
4464       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_IndicationHeader, 0, &e2smKpmIndHdr, PrepFinalEncBuf, encBuf);
4465       if(encRetVal.encoded == ENCODE_FAIL)
4466       {
4467          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM Indication Header (at %s)\n",\
4468                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4469          break;
4470       }
4471       else
4472       {
4473          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SM-KPM Indication Header \n");
4474 #ifdef DEBUG_ASN_PRINT
4475          for(int i=0; i< encBufSize; i++)
4476          {
4477             printf("%x",encBuf[i]);
4478          } 
4479 #endif
4480       }
4481
4482       /* Copy encoded string to RIC Indication Header buffer */
4483       ricIndHdr->size = encBufSize;
4484       DU_ALLOC(ricIndHdr->buf, ricIndHdr->size);
4485       if(!ricIndHdr->buf)
4486       {
4487          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4488          break;
4489       }
4490       memset(ricIndHdr->buf, 0, ricIndHdr->size);
4491       memcpy(ricIndHdr->buf, encBuf, encBufSize);
4492       ret = ROK;
4493       break;
4494    }
4495
4496    /* Free E2SM-KPM Indication Header */
4497    FreeE2smKpmIndicationHeader(&e2smKpmIndHdr);
4498
4499    return ret;
4500 }
4501
4502 /*******************************************************************
4503  *
4504  * brief Fill the RIC Indication Message
4505  *
4506  * @details
4507  *
4508  *    Function : fillRicIndication
4509  *
4510  * Functionality: Fills the RIC Indication Message
4511  *
4512  * @param  RIC Indication Message to be filled
4513  *         RIC Subscription DB
4514  *         Action DB
4515  * @return ROK     - success
4516  *         RFAILED - failure
4517  *
4518  ******************************************************************/
4519 uint8_t fillRicIndication(RICindication_t *ricIndicationMsg, RicSubscription *ricSubscriptionInfo, ActionInfo *actionInfo)
4520 {
4521    uint8_t elementCnt = 0, idx = 0;
4522    uint8_t ret = ROK;
4523
4524    elementCnt = 6;
4525
4526    ricIndicationMsg->protocolIEs.list.count = elementCnt;
4527    ricIndicationMsg->protocolIEs.list.size  = elementCnt * sizeof(RICindication_IEs_t *);
4528
4529    /* Initialize the Ric Indication members */
4530    DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, ricIndicationMsg->protocolIEs.list.size);
4531    if(ricIndicationMsg->protocolIEs.list.array == NULLP)
4532    {
4533       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4534       return RFAILED;
4535    }
4536
4537    for(idx=0; idx<elementCnt; idx++)
4538    {
4539       DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx], sizeof(RICindication_IEs_t));
4540       if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
4541       {
4542          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4543          return RFAILED;
4544       }
4545    }
4546
4547    /* RIC Request ID */
4548    idx = 0;
4549    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
4550    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4551    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICrequestID;
4552    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID = \
4553       ricSubscriptionInfo->requestId.requestorId;
4554    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID = \
4555       ricSubscriptionInfo->requestId.instanceId;
4556
4557    /* RAN Function ID */
4558    idx++;
4559    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
4560    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4561    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RANfunctionID;
4562    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ricSubscriptionInfo->ranFuncId;
4563
4564    /* RIC Action ID */
4565    idx++;
4566    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
4567    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4568    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICactionID;
4569    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = actionInfo->actionId;
4570
4571    /* RIC Indication Type */
4572    idx++;
4573    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
4574    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4575    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationType;
4576    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = actionInfo->type;
4577
4578    /* RIC Indication Header */
4579    idx++;
4580    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
4581    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4582    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationHeader;
4583    if(fillRicIndHeader(&ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader, \
4584       ricSubscriptionInfo) != ROK)
4585    {
4586       DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication header");
4587       return RFAILED;
4588    }
4589
4590    /* RIC Indication Message */
4591    idx++;
4592    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
4593    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4594    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationMessage;
4595    if(fillRicIndMsgBuf(&ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage, \
4596       actionInfo) != ROK)
4597    {
4598       DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication Message");
4599       return RFAILED;
4600    }
4601
4602    return ret;
4603 }
4604
4605 /*******************************************************************
4606  *
4607  * @brief Builds and Send the RicIndication Message
4608  *
4609  * @details
4610  *
4611  *    Function : BuildAndSendRicIndication
4612  *
4613  * Functionality:Fills the RicIndication Message
4614  *
4615  * @return ROK     - success
4616  *         RFAILED - failure
4617  *
4618  ******************************************************************/
4619
4620 uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo, ActionInfo *actionInfo)
4621 {
4622    uint8_t          ret = RFAILED; 
4623    E2AP_PDU_t       *e2apMsg = NULLP;
4624    RICindication_t  *ricIndicationMsg = NULLP;
4625    asn_enc_rval_t   encRetVal;        /* Encoder return value */
4626
4627    while(true)
4628    {
4629       DU_LOG("\nINFO   -->  E2AP : Building RIC Indication Message\n");
4630
4631       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4632       if(e2apMsg == NULLP)
4633       {
4634          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4635          break;
4636       }
4637
4638       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4639       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4640       if(e2apMsg->choice.initiatingMessage == NULLP)
4641       {
4642          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4643          break;
4644       }
4645       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
4646       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4647       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication;
4648
4649       ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
4650
4651       if(fillRicIndication(ricIndicationMsg, ricSubscriptionInfo, actionInfo) != ROK)
4652       {
4653          DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication message");
4654          break;
4655       }
4656
4657       /* Prints the Msg formed */
4658       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4659       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4660       encBufSize = 0;
4661       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4662             encBuf);
4663       if(encRetVal.encoded == ENCODE_FAIL)
4664       {
4665          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Indication Message (at %s)\n",\
4666                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4667          break;
4668       }
4669       else
4670       {
4671          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Indication Message \n");
4672 #ifdef DEBUG_ASN_PRINT
4673          for(int i=0; i< encBufSize; i++)
4674          {
4675             printf("%x",encBuf[i]);
4676          } 
4677 #endif
4678       }
4679
4680       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
4681       {
4682          DU_LOG("\nINFO   -->  E2AP : Sending RIC Indication Message");      
4683
4684       }
4685       ret = ROK;
4686       break;
4687    }
4688    FreeRicIndication(e2apMsg);  
4689    return ret;
4690 }
4691
4692 /*******************************************************************
4693  *
4694  * @brief free e2 node component configuration req and rsp
4695  *
4696  * @details
4697  *
4698  *    Function : freeE2NodeComponentConfiguration 
4699  *
4700  *    Functionality:
4701  *       - free e2 node component configuration req and rsp
4702  *
4703  * @params[in] E2nodeComponentConfiguration_t *e2nodeComponentConfiguration
4704  * @return ROK     - success
4705  *         RFAILED - failure
4706  *
4707  * ****************************************************************/
4708
4709 void freeE2NodeComponentConfiguration(E2nodeComponentConfiguration_t *e2nodeComponentConfiguration)
4710 {
4711    /* Free E2 Node Component Request Part */
4712    DU_FREE(e2nodeComponentConfiguration->e2nodeComponentRequestPart.buf, e2nodeComponentConfiguration->e2nodeComponentRequestPart.size);
4713
4714    /* Free E2 Node Component Response Part */
4715    DU_FREE(e2nodeComponentConfiguration->e2nodeComponentResponsePart.buf, e2nodeComponentConfiguration->e2nodeComponentResponsePart.size);
4716                                  
4717 }
4718
4719 /*******************************************************************
4720  *
4721  * @brief free e2 node component component identifier
4722  *
4723  * @details
4724  *
4725  *    Function : freeE2NodeComponentIdentifier
4726  *
4727  *    Functionality:
4728  *       - free e2 node component component identifier
4729  *
4730  * @params[in] E2nodeComponentID_t  *componentID 
4731  * @return ROK     - success
4732  *         RFAILED - failure
4733  *
4734  * ****************************************************************/
4735
4736 void freeE2NodeComponentIdentifier(E2nodeComponentID_t *componentID)
4737 {
4738    if(componentID->choice.e2nodeComponentInterfaceTypeF1)
4739    {
4740       DU_FREE(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf, componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
4741       DU_FREE(componentID->choice.e2nodeComponentInterfaceTypeF1, sizeof(E2nodeComponentInterfaceF1_t));
4742    }
4743                                  
4744 }
4745
4746 /*******************************************************************
4747  *
4748  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
4749  *
4750  * @details
4751  *
4752  *    Function : FreeE2NodeConfigUpdate 
4753  *
4754  *    Functionality:
4755  *       - freeing the memory allocated for E2nodeConfigurationUpdate
4756  *
4757  * @params[in] E2AP_PDU_t *e2apMsg 
4758  * @return ROK     - success
4759  *         RFAILED - failure
4760  *
4761  * ****************************************************************/
4762
4763 void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg)
4764 {
4765    uint8_t arrIdx =0, e2NodeUpdateListIdx=0, e2NodeRemovalListIdx=0, e2NodeAddListIdx=0;
4766    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate =NULL;
4767    E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList  =NULL;
4768    E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItem =NULL;
4769    E2nodeComponentConfigRemoval_List_t *e2NodeRemovalList =NULL;
4770    E2nodeComponentConfigRemoval_ItemIEs_t *e2NodeRemovalItem =NULL;
4771    E2nodeComponentConfigAddition_List_t *e2NodeAddList =NULL;
4772    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem =NULL;
4773
4774    if(e2apMsg != NULLP)
4775    {
4776       if(e2apMsg->choice.initiatingMessage != NULLP)
4777       {
4778          e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
4779          if(e2NodeConfigUpdate->protocolIEs.list.array != NULLP)
4780          {
4781             for(arrIdx = 0; arrIdx < e2NodeConfigUpdate->protocolIEs.list.count; arrIdx++)
4782             {
4783                if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx])
4784                {
4785
4786                   switch(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id)
4787                   {
4788                      case ProtocolIE_IDE2_id_TransactionID:
4789                         break;
4790
4791                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
4792                      {
4793                          e2NodeAddList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;
4794                          if(e2NodeAddList->list.array)
4795                          {
4796                              for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
4797                              {
4798                                 e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
4799                                  
4800                                 freeE2NodeComponentConfiguration(&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration);
4801                                 freeE2NodeComponentIdentifier(&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID);
4802                                 DU_FREE(e2NodeAddItem, sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
4803                              }
4804                              DU_FREE(e2NodeAddList->list.array, e2NodeAddList->list.size);
4805                          }
4806                          break;
4807                      }
4808                      case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate:
4809                         {
4810                            e2NodeUpdateList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdate_List;
4811                            if(e2NodeUpdateList->list.array)
4812                            {
4813                               for(e2NodeUpdateListIdx = 0; e2NodeUpdateListIdx< e2NodeUpdateList->list.count; e2NodeUpdateListIdx++)
4814                               {
4815                                  e2NodeUpdateItem = (E2nodeComponentConfigUpdate_ItemIEs_t *) e2NodeUpdateList->list.array[e2NodeUpdateListIdx];
4816                                  
4817                                  freeE2NodeComponentConfiguration(&e2NodeUpdateItem->value.choice.E2nodeComponentConfigUpdate_Item.e2nodeComponentConfiguration);
4818                                  freeE2NodeComponentIdentifier(&e2NodeUpdateItem->value.choice.E2nodeComponentConfigUpdate_Item.e2nodeComponentID);
4819                                  DU_FREE(e2NodeUpdateItem, sizeof(E2nodeComponentConfigUpdate_ItemIEs_t));
4820                               }
4821                               DU_FREE(e2NodeUpdateList->list.array, e2NodeUpdateList->list.size);
4822                            }
4823                            break;
4824                         }
4825                      case ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval:
4826                         {
4827                            e2NodeRemovalList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemoval_List;
4828                            if(e2NodeRemovalList->list.array)
4829                            {
4830                               for(e2NodeRemovalListIdx = 0; e2NodeRemovalListIdx< e2NodeRemovalList->list.count; e2NodeRemovalListIdx++)
4831                               {
4832                                  e2NodeRemovalItem = (E2nodeComponentConfigRemoval_ItemIEs_t *) e2NodeRemovalList->list.array[e2NodeRemovalListIdx];
4833
4834                                  freeE2NodeComponentIdentifier(&e2NodeRemovalItem->value.choice.E2nodeComponentConfigRemoval_Item.e2nodeComponentID);
4835                                  DU_FREE(e2NodeRemovalItem, sizeof(E2nodeComponentConfigRemoval_ItemIEs_t));
4836                               }
4837                               DU_FREE(e2NodeRemovalList->list.array, e2NodeRemovalList->list.size);
4838                            }
4839                            break;
4840                         }
4841                            
4842                      default:
4843                         break;
4844                   }
4845                   DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
4846                }
4847             }
4848             DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
4849          }
4850          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4851       }
4852       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4853    }
4854 }
4855
4856 /*******************************************************************
4857  *
4858  * @brief Buld and send the E2 node config update msg 
4859  *
4860  * @details
4861  *
4862  *    Function : BuildAndSendE2NodeConfigUpdate
4863  *
4864  *    Functionality:
4865  *         - Buld and send the E2 node config update msg
4866  *
4867  * @params[in] 
4868  * @return ROK     - success
4869  *         RFAILED - failure
4870  *
4871  * ****************************************************************/
4872
4873 uint8_t BuildAndSendE2NodeConfigUpdate(E2NodeConfigList *e2NodeList)
4874 {
4875    uint8_t ret = RFAILED;
4876    uint8_t arrIdx = 0,elementCnt = 0, transId=0;
4877    E2AP_PDU_t  *e2apMsg = NULLP;
4878    asn_enc_rval_t     encRetVal;       /* Encoder return value */
4879    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate = NULLP;
4880
4881    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update\n");
4882    do
4883    {
4884       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4885       if(e2apMsg == NULLP)
4886       {
4887          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4888          break;
4889       }
4890
4891       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4892       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4893       if(e2apMsg->choice.initiatingMessage == NULLP)
4894       {
4895          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4896          break;
4897       }
4898       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4899       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
4900       e2apMsg->choice.initiatingMessage->value.present = \
4901       InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate;
4902       e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
4903       
4904       elementCnt =1;
4905       if(e2NodeList->addE2NodeCount)
4906          elementCnt++;
4907       if(e2NodeList->updateE2NodeCount)
4908          elementCnt++;
4909       if(e2NodeList->removeE2NodeCount)
4910          elementCnt++;
4911
4912       e2NodeConfigUpdate->protocolIEs.list.count = elementCnt;
4913       e2NodeConfigUpdate->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdate_IEs_t*);
4914       DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
4915       if(e2NodeConfigUpdate->protocolIEs.list.array == NULLP)
4916       {
4917          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
4918          break;
4919       }
4920       
4921       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
4922       {
4923          DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
4924          if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx] == NULLP)
4925          {
4926             
4927             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
4928             break;
4929          }
4930       }
4931       
4932       if(arrIdx<elementCnt)
4933          break;
4934
4935       arrIdx = 0;
4936       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4937       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4938       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_TransactionID;
4939       transId = assignTransactionId();
4940       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
4941
4942       if(e2NodeList->addE2NodeCount)
4943       {
4944          arrIdx++;
4945          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition;
4946          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4947          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigAddition_List;
4948          if(BuildE2NodeConfigAddList(&(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List),\
4949          ProcedureCodeE2_id_E2nodeConfigurationUpdate, e2NodeList->addE2NodeCount, e2NodeList->addE2Node)!=ROK)
4950          {
4951             DU_LOG("\nERROR  -->  E2AP : Failed to create E2 Node config list");
4952             break;
4953          }
4954       }
4955       
4956       if(e2NodeList->updateE2NodeCount)
4957       {
4958          arrIdx++;
4959          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate;
4960          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4961          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigUpdate_List;
4962          if(BuildE2NodeConfigUpdateList(&e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdate_List,\
4963          e2NodeList->updateE2NodeCount, e2NodeList->updateE2Node) != ROK)
4964          {
4965
4966             DU_LOG("\nERROR  -->  E2AP : Failed to update the E2 node configuration");
4967             break;
4968          }
4969       }
4970       
4971       if(e2NodeList->removeE2NodeCount)
4972       {
4973          arrIdx++;
4974          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval;
4975          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4976          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigRemoval_List;
4977          if(BuildE2NodeConfigRemoveList(&e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemoval_List,\
4978          e2NodeList->removeE2NodeCount, e2NodeList->removeE2Node) != ROK)
4979          {
4980
4981             DU_LOG("\nERROR  -->  E2AP : Failed to remove the E2 node configuration");
4982             break;
4983          }
4984       }
4985
4986       /* Prints the Msg formed */
4987       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4988
4989       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4990       encBufSize = 0;
4991       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
4992       if(encRetVal.encoded == ENCODE_FAIL)
4993       {
4994          DU_LOG("\nERROR  -->  E2AP : Could not encode E2nodeConfigurationUpdate structure (at %s)\n",\
4995                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4996          break;
4997       }
4998       else
4999       {
5000          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2nodeConfigurationUpdate\n");
5001 #ifdef DEBUG_ASN_PRINT
5002          for(int i=0; i< encBufSize; i++)
5003          {
5004             printf("%x",encBuf[i]);
5005          }
5006 #endif
5007       }
5008       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize))
5009       {
5010          DU_LOG("\nERROR  -->  E2AP : Sending E2 node config update failed");
5011          break;
5012       }
5013
5014       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
5015       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5016       memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.e2NodeConfigUpdate.configList, e2NodeList, sizeof(E2NodeConfigList));
5017       ret = ROK;
5018       break;
5019    }while(true);
5020    
5021    FreeE2NodeConfigUpdate(e2apMsg);
5022    return ret;
5023 }
5024
5025 /*******************************************************************
5026  *
5027  * @brief Deallocate the memory allocated for E2ResetRequest msg
5028  *
5029  * @details
5030  *
5031  *    Function : FreeE2ResetRequest
5032  *
5033  *    Functionality:
5034  *       - freeing the memory allocated for E2ResetRequest
5035  *
5036  * @params[in] E2AP_PDU_t *e2apMsg
5037  * @return ROK     - success
5038  *         RFAILED - failure
5039  *
5040  * ****************************************************************/
5041 void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg)
5042 {
5043    uint8_t ieIdx =0;
5044    ResetRequestE2_t  *resetReq = NULLP;
5045
5046    if(e2apMsg != NULLP)
5047    {
5048       if(e2apMsg->choice.initiatingMessage != NULLP)
5049       {
5050          resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
5051          if(resetReq->protocolIEs.list.array)
5052          {
5053             for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
5054             {
5055                DU_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
5056             }
5057             DU_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
5058          }
5059          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5060       }
5061       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
5062    }
5063 }
5064
5065 /*******************************************************************
5066  *
5067  * @brief Build and send the E2 reset request msg
5068  *
5069  * @details
5070  *
5071  *    Function : BuildAndSendE2ResetRequest
5072  *
5073  *    Functionality:
5074  *         - Buld and send the E2 reset request msg to RIC
5075  *
5076  * @params[in]
5077  *    Reset cause
5078  * @return ROK     - success
5079  *         RFAILED - failure
5080  *
5081  * ****************************************************************/
5082 uint8_t BuildAndSendE2ResetRequest(E2FailureCause resetCause)
5083 {
5084    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
5085    uint8_t ret = RFAILED;
5086    E2AP_PDU_t        *e2apMsg = NULLP;
5087    ResetRequestE2_t  *resetReq = NULLP;
5088    asn_enc_rval_t     encRetVal;       /* Encoder return value */
5089
5090    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Request\n");
5091
5092    do
5093    {
5094       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
5095       if(e2apMsg == NULLP)
5096       {
5097          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for E2AP-PDU failed");
5098          break;
5099       }
5100
5101       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
5102       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5103       if(e2apMsg->choice.initiatingMessage == NULLP)
5104       {
5105          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for initiatingMessage");
5106          break;
5107       }
5108
5109       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
5110       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
5111       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
5112       resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
5113
5114       elementCnt = 2;
5115       resetReq->protocolIEs.list.count = elementCnt;
5116       resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
5117
5118       DU_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
5119       if(!resetReq->protocolIEs.list.array)
5120       {
5121          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
5122             Reset Request IE array");
5123          break;
5124       }
5125
5126       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
5127       {
5128          DU_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
5129          if(!resetReq->protocolIEs.list.array[ieIdx])
5130          {
5131             DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
5132             Reset Request IE array element");
5133             break;
5134          }
5135       }
5136
5137       /* In case of failure */
5138       if(ieIdx < elementCnt)
5139          break;
5140
5141       ieIdx = 0;
5142       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
5143       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
5144       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
5145       transId = assignTransactionId();
5146       resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
5147
5148       ieIdx++;
5149       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
5150       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
5151       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
5152       fillE2Cause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, resetCause);
5153
5154       /* Prints the Msg formed */
5155       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5156
5157       memset(encBuf, 0, ENC_BUF_MAX_LEN);
5158       encBufSize = 0;
5159       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
5160             encBuf);
5161       if(encRetVal.encoded == ENCODE_FAIL)
5162       {
5163          DU_LOG("\nERROR  -->  E2AP : Could not encode reset request structure (at %s)\n",\
5164                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
5165          break;
5166       }
5167       else
5168       {
5169          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for reset request\n");
5170 #ifdef DEBUG_ASN_PRINT
5171          for(int i=0; i< encBufSize; i++)
5172          {
5173             printf("%x",encBuf[i]);
5174          }
5175 #endif
5176       }
5177       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
5178       {
5179          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
5180          break;
5181       }
5182
5183       /* In case the message is sent successfully, store the transaction info to
5184        * be used when response is received */
5185       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
5186       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5187
5188       ret = ROK;
5189       break;
5190    }while(true);
5191
5192    /* Free all memory */
5193    FreeE2ResetRequest(e2apMsg);
5194    return ret;
5195 }
5196
5197 /*******************************************************************
5198  *
5199  * @brief Deallocate the memory allocated for Reset Response msg
5200  *
5201  * @details
5202  *
5203  *    Function : freeAperDecodingOfE2ResetRsp
5204  *
5205  *    Functionality:
5206  *       - freeing the memory allocated for Reset response
5207  *
5208  * @params[in] ResetResponseE2_t *resetResponse
5209  * @return void
5210  *
5211  * ****************************************************************/
5212 void freeAperDecodingOfE2ResetRsp(ResetResponseE2_t *resetResponse)
5213 {
5214    uint8_t ieIdx;
5215
5216    if(resetResponse)
5217    {
5218       if(resetResponse->protocolIEs.list.array)
5219       {
5220          for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
5221          {
5222             if(resetResponse->protocolIEs.list.array[ieIdx])
5223             {
5224                switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
5225                {
5226                   case ProtocolIE_IDE2_id_TransactionID:
5227                      break;
5228
5229                   case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
5230                      break;
5231                }
5232                free(resetResponse->protocolIEs.list.array[ieIdx]);
5233             }
5234          }
5235          free(resetResponse->protocolIEs.list.array);
5236       }
5237    }
5238 }
5239
5240 /******************************************************************
5241  *
5242  * @brief Processes E2 Reset Response sent by RIC
5243  *
5244  * @details
5245  *
5246  *    Function : procResetResponse
5247  *
5248  *    Functionality: Processes E2 Reset Response sent by RIC
5249  *
5250  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5251  * @return void
5252  *
5253  * ****************************************************************/
5254 void procResetResponse(E2AP_PDU_t *e2apMsg)
5255 {
5256    bool invalidTransId=false;
5257    uint8_t ieIdx =0, transId =0;
5258    uint16_t ranFuncIdx=0;
5259    ResetResponseE2_t *resetResponse =NULLP;
5260
5261    DU_LOG("\nINFO   -->  E2AP : E2 Reset Response received");
5262    resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;;
5263
5264    for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
5265    {
5266       switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
5267       {
5268          case ProtocolIE_IDE2_id_TransactionID:
5269             {
5270                transId = resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
5271                if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) && \
5272                      (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
5273                {
5274                   memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
5275                }
5276                else
5277                {
5278                   DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
5279                   invalidTransId = true;
5280                }
5281                break;
5282             }
5283          case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
5284             {
5285                for(ranFuncIdx=0; ranFuncIdx<MAX_RAN_FUNCTION; ranFuncIdx++)
5286                {
5287                   if(duCb.e2apDb.ranFunction[ranFuncIdx].id >0)
5288                   {
5289                      deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList));
5290                      memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo));
5291                   }
5292                }
5293                break;
5294             }
5295          default:
5296             {
5297                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2 Reset Response : %ld",
5298                      resetResponse->protocolIEs.list.array[ieIdx]->id);
5299                break;
5300             }
5301       }
5302
5303       if(invalidTransId == true)
5304       {
5305          break;
5306       }
5307    }
5308
5309    freeAperDecodingOfE2ResetRsp(resetResponse);
5310 }
5311
5312 /******************************************************************
5313  *
5314  * @brief Deallocation of memory allocated by aper decoder for e2 setup Failure
5315  *
5316  * @details
5317  *
5318  *    Function : freeAperDecodingOfE2SetupFailure
5319  *
5320  *    Functionality: Deallocation of memory allocated by aper decoder for e2
5321  *    setup Failure
5322  *
5323  * @params[in] E2setupFailure_t *e2SetupFailure;
5324  * @return void
5325  *
5326  * ****************************************************************/
5327 void freeAperDecodingOfE2SetupFailure(E2setupFailure_t *e2SetupFailure)
5328 {
5329    uint8_t arrIdx;
5330
5331    if(e2SetupFailure)
5332    {
5333       if(e2SetupFailure->protocolIEs.list.array)
5334       {
5335          for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
5336          {
5337             if(e2SetupFailure->protocolIEs.list.array[arrIdx])
5338             {
5339                free(e2SetupFailure->protocolIEs.list.array[arrIdx]);  
5340             }
5341          }
5342          free(e2SetupFailure->protocolIEs.list.array);
5343       }
5344    }
5345 }
5346 /******************************************************************
5347  *
5348  * @brief Processes E2 Setup Failure sent by RIC
5349  *
5350  * @details
5351  *
5352  *    Function : procE2SetupFailure
5353  *
5354  *    Functionality: Processes E2 Setup failure sent by RIC
5355  *
5356  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5357  * @return ROK     - success
5358  *         RFAILED - failure
5359  *
5360  * ****************************************************************/
5361 void procE2SetupFailure(E2AP_PDU_t *e2apMsg)
5362 {
5363    uint8_t arrIdx =0, transId =0, timerValue=0; 
5364    E2setupFailure_t *e2SetupFailure;
5365
5366    DU_LOG("\nINFO   -->  E2AP : E2 Setup failure received"); 
5367    e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
5368
5369    for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
5370    {
5371       switch(e2SetupFailure->protocolIEs.list.array[arrIdx]->id)
5372       {
5373          case ProtocolIE_IDE2_id_TransactionID:
5374          {
5375             transId = e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
5376             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
5377                   (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
5378             {
5379                memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
5380             }
5381             else
5382             {
5383                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
5384                return ;
5385             }
5386             break;
5387          }
5388          case ProtocolIE_IDE2_id_TimeToWaitE2:
5389             {
5390                timerValue = convertE2WaitTimerEnumToValue(e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
5391                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR)) == FALSE)
5392                {
5393                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR, timerValue);
5394                }
5395                else
5396                {
5397                   DU_LOG("\nERROR   -->  E2AP : EVENT_E2_SETUP_TMR timer is already running");
5398                   return;
5399                }
5400                break; 
5401             }
5402       }
5403    }
5404
5405    freeAperDecodingOfE2SetupFailure(e2SetupFailure);
5406 }
5407 /******************************************************************
5408  *
5409  * @brief Deallocation of memory allocated by aper decoder for RIC service Query
5410  *
5411  * @details
5412  *
5413  *    Function : freeAperDecodingOfRicServiceQuery
5414  *
5415  *    Functionality: Deallocation of memory allocated by aper decoder for RIC
5416  *    service Query
5417  *
5418  * @params[in] RICserviceQuery_t *ricServiceQuery;
5419  * @return void
5420  *
5421  * ****************************************************************/
5422
5423 void freeAperDecodingOfRicServiceQuery(RICserviceQuery_t *ricServiceQuery)
5424 {
5425    uint8_t arrIdx,ranFuncIdx;
5426     RANfunctionsID_List_t *ranFuncAddedList;
5427
5428    if(ricServiceQuery)
5429    {
5430       if(ricServiceQuery->protocolIEs.list.array)
5431       {
5432          for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
5433          {
5434             if(ricServiceQuery->protocolIEs.list.array[arrIdx])
5435             {
5436                switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
5437                {
5438                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5439                   {
5440                      ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5441                      if(ranFuncAddedList->list.array)
5442                      {
5443                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
5444                         {
5445                            free(ranFuncAddedList->list.array[ranFuncIdx]);
5446                         }
5447                         free(ranFuncAddedList->list.array);;
5448                      }
5449                      break;
5450                   }
5451                   default:
5452                      break;
5453                }
5454                free(ricServiceQuery->protocolIEs.list.array[arrIdx]);
5455             }
5456          }
5457          free(ricServiceQuery->protocolIEs.list.array);
5458       }
5459    }
5460 }
5461 /*******************************************************************
5462  *
5463  * @brief Build RanFunction Delete List
5464  *
5465  * @details
5466  *
5467  *    Function : BuildRanFunctionDeleteList
5468  *
5469  * Functionality:  Build RanFunction Delete List
5470  *
5471  * @params[in]
5472  *    RANfunctionsID List
5473  *    Count of the RAN function
5474  *    Received RAN function list
5475  *
5476  * @return ROK     - success
5477  *         RFAILED - failure
5478  *
5479  ******************************************************************/
5480
5481 uint8_t BuildRanFunctionDeleteList(RANfunctionsID_List_t *deleteList, uint8_t count, RanFuncInfo *recvdRanFunc)
5482 {
5483    uint8_t ranFuncIdx=0;
5484    RANfunctionID_ItemIEs_t *delRanFuncItem;
5485
5486    if(count)
5487    {
5488       deleteList->list.count = count;
5489       deleteList->list.size = deleteList->list.count * sizeof(RANfunctionID_ItemIEs_t*);
5490       DU_ALLOC(deleteList->list.array, deleteList->list.size);
5491       if(deleteList->list.array == NULLP)
5492       {
5493          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
5494          return RFAILED;
5495       }
5496       for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
5497       {
5498          DU_ALLOC(deleteList->list.array[ranFuncIdx], sizeof(RANfunctionID_ItemIEs_t));
5499          if(deleteList->list.array[ranFuncIdx] == NULLP)
5500          {
5501             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
5502             return RFAILED;
5503          }
5504          delRanFuncItem= (RANfunctionID_ItemIEs_t *) deleteList->list.array[ranFuncIdx];
5505          delRanFuncItem->id = ProtocolIE_IDE2_id_RANfunctionID_Item;
5506          delRanFuncItem->criticality = CriticalityE2_ignore;
5507          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionID = recvdRanFunc[ranFuncIdx].id;
5508          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionRevision = recvdRanFunc[ranFuncIdx].revisionCounter;
5509
5510       }
5511    }
5512    return ROK;
5513 }
5514 /*******************************************************************
5515  *
5516  * @brief De Allocate  Ric Service Update message
5517  *
5518  * @details
5519  *
5520  *    Function : FreeRicServiceUpdate
5521  *
5522  *    Functionality: De-Allocating Ric Service Update message
5523  *
5524  * @params[in] E2AP_PDU_t *e2apMsg
5525
5526  * @return void
5527  *
5528  * ****************************************************************/
5529
5530 void FreeRicServiceUpdate(E2AP_PDU_t *e2apMsg)
5531 {
5532    uint8_t arrIdx = 0;
5533    uint8_t ranFuncAddListIdx=0, ranFuncDelIdx=0;
5534    RICserviceUpdate_t *ricServiceUpdate;
5535    RANfunctions_List_t *ranFunctionsList;
5536    RANfunction_ItemIEs_t *ranFuncItemIe;
5537    RANfunction_Item_t  *ranFunItem;
5538    RANfunctionsID_List_t *deleteList;
5539
5540    /* De-allocating Memory */
5541    if(e2apMsg != NULLP)
5542    {
5543       if(e2apMsg->choice.initiatingMessage != NULLP)
5544       {
5545          ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
5546          if(ricServiceUpdate->protocolIEs.list.array != NULLP)
5547          {
5548             for(arrIdx = 0; arrIdx < ricServiceUpdate->protocolIEs.list.count; arrIdx++)
5549             {
5550                if(ricServiceUpdate->protocolIEs.list.array[arrIdx] != NULLP)
5551                {
5552                   switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
5553                   {
5554                      case ProtocolIE_IDE2_id_TransactionID:
5555                         break;
5556
5557                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
5558                      case ProtocolIE_IDE2_id_RANfunctionsModified:
5559                         {
5560                            ranFunctionsList = &(ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List);
5561                            if(ranFunctionsList->list.array)
5562                            {
5563                               for(ranFuncAddListIdx= 0; ranFuncAddListIdx< ranFunctionsList->list.count; ranFuncAddListIdx++)
5564                               {
5565                                  if(ranFunctionsList->list.array[ranFuncAddListIdx])
5566                                  {
5567                                     ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncAddListIdx];
5568                                     ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
5569                                     DU_FREE(ranFunItem->ranFunctionOID.buf, ranFunItem->ranFunctionOID.size);
5570                                     DU_FREE(ranFunItem->ranFunctionDefinition.buf, ranFunItem->ranFunctionDefinition.size);
5571                                     DU_FREE(ranFunctionsList->list.array[ranFuncAddListIdx], sizeof(RANfunction_ItemIEs_t));
5572                                  }
5573                               }
5574                               DU_FREE(ranFunctionsList->list.array, ranFunctionsList->list.size);
5575                            }
5576                            break;
5577                         }
5578                      case ProtocolIE_IDE2_id_RANfunctionsDeleted:
5579                         {
5580                            deleteList= &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5581                            if(deleteList->list.array)
5582                            {
5583                               for(ranFuncDelIdx = 0; ranFuncDelIdx< deleteList->list.count; ranFuncDelIdx++)
5584                               {
5585                                  DU_FREE(deleteList->list.array[ranFuncDelIdx], sizeof(RANfunctionID_ItemIEs_t));
5586                               }
5587                               DU_FREE(deleteList->list.array, deleteList->list.size);
5588   
5589                            }
5590                            break;
5591                         }
5592                      default:
5593                         DU_LOG("\nERROR  --> E2AP: Invalid event at ricServiceUpdate %ld ",\
5594                               (ricServiceUpdate->protocolIEs.list.array[arrIdx]->id));
5595                         break;
5596                   }
5597                   DU_FREE(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
5598                }
5599             }
5600             DU_FREE(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
5601          }
5602          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5603       }
5604       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
5605    }
5606 }
5607
5608 /*******************************************************************
5609  *
5610  * @brief Builds and Send the RicServiceUpdateuest
5611  *
5612  * @details
5613  *
5614  *    Function : BuildAndSendRicServiceUpdate
5615  *
5616  * Functionality:Fills the RicServiceUpdateuest
5617  *
5618  * @return ROK     - success
5619  *         RFAILED - failure
5620  *
5621  ******************************************************************/
5622
5623 uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate)
5624 {
5625    uint8_t arrIdx = 0, elementCnt=0;
5626    uint8_t transId = 0, ret = RFAILED;
5627    bool memAllocFailed =false;
5628    E2AP_PDU_t        *e2apMsg = NULLP;
5629    RICserviceUpdate_t  *ricServiceUpdate = NULLP;
5630    asn_enc_rval_t     encRetVal;       /* Encoder return value */
5631
5632    DU_LOG("\nINFO   -->  E2AP : Building Ric Service Update\n");
5633    do
5634    {
5635       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
5636       if(e2apMsg == NULLP)
5637       {
5638          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
5639          break;
5640       }
5641       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
5642       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5643       if(e2apMsg->choice.initiatingMessage == NULLP)
5644       {
5645          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
5646          break;
5647       }
5648       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
5649       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
5650       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceUpdate;
5651       ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
5652       
5653       /* For TransId IE, set elementCnt to 1.
5654       If there is any item in the RAN function add list, RAN function modification list, or RAN function delete list, increment the elementCnt.*/
5655
5656       elementCnt =1;
5657       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5658         elementCnt++;
5659       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
5660          elementCnt++;
5661       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
5662          elementCnt++;
5663        
5664       ricServiceUpdate->protocolIEs.list.count = elementCnt;
5665       ricServiceUpdate->protocolIEs.list.size = elementCnt * sizeof(RICserviceUpdate_IEs_t*);
5666
5667       /* Initialize the E2Setup members */
5668       DU_ALLOC(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
5669       if(ricServiceUpdate->protocolIEs.list.array == NULLP)
5670       {
5671          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
5672          break;
5673       }
5674       
5675       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
5676       {
5677          DU_ALLOC(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
5678          if(ricServiceUpdate->protocolIEs.list.array[arrIdx] == NULLP)
5679          {
5680             memAllocFailed = true;
5681             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayIdx [%d]", arrIdx);
5682             break;
5683          }
5684       }
5685       if(memAllocFailed == true)
5686          break;
5687
5688       arrIdx = 0;
5689
5690       /* TransactionID */
5691       ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
5692       ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5693       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
5694       if(serviceUpdate.dir == E2_NODE_INITIATED)
5695          transId = assignTransactionId();
5696       else
5697         transId = serviceUpdate.transId;
5698       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
5699
5700       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5701       {
5702          arrIdx++;
5703          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAdded;
5704          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5705          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
5706          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,\
5707          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded, serviceUpdate.recvRanFuncList.ranFunToBeAdded) !=ROK)
5708          {
5709             break;
5710          }
5711       }
5712
5713       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
5714       {
5715          arrIdx++;
5716          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsModified;
5717          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5718          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
5719          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,
5720          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeModified, serviceUpdate.recvRanFuncList.ranFunToBeModified) !=ROK)
5721          {
5722             break;
5723          }
5724       }
5725
5726       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
5727       {
5728          arrIdx++;
5729          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsDeleted;
5730          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5731          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctionsID_List;
5732          if(BuildRanFunctionDeleteList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List,\
5733          serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted, serviceUpdate.recvRanFuncList.ranFunToBeDeleted) != ROK)
5734          {
5735             break;
5736          }
5737       }
5738       /* Prints the Msg formed */
5739       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5740
5741       memset(encBuf, 0, ENC_BUF_MAX_LEN);
5742       encBufSize = 0;
5743       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
5744       if(encRetVal.encoded == ENCODE_FAIL)
5745       {
5746          DU_LOG("\nERROR  -->  E2AP : Could not encode RicServiceUpdateuest structure (at %s)\n",\
5747                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
5748          break;
5749       }
5750       else
5751       {
5752          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RicServiceUpdateuest\n");
5753 #ifdef DEBUG_ASN_PRINT
5754          for(int i=0; i< encBufSize; i++)
5755          {
5756             printf("%x",encBuf[i]);
5757          }
5758 #endif
5759       }
5760       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
5761       {
5762          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
5763          break;
5764       }
5765       ret = ROK;
5766       break;
5767    }while(true);
5768    
5769    if(ret == ROK)
5770    {
5771       if(serviceUpdate.dir == E2_NODE_INITIATED)
5772       {
5773          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
5774          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5775       }
5776       else
5777       {
5778          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId = transId;
5779          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5780       }
5781       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.dir = serviceUpdate.dir;
5782       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.transId =transId;
5783       memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.recvRanFuncList, &serviceUpdate.recvRanFuncList, sizeof(E2TmpRanFunList));
5784    }
5785    FreeRicServiceUpdate(e2apMsg);
5786    return ret;
5787 }
5788 /******************************************************************
5789  *
5790  * @brief Processes RIC service Query sent by RIC
5791  *
5792  * @details
5793  *
5794  *    Function : procRicServiceQuery
5795  *
5796  *    Functionality: Processes RIC service Query sent by RIC
5797  *
5798  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5799  * @return ROK     - success
5800  *         RFAILED - failure
5801  *
5802  * ****************************************************************/
5803
5804 void procRicServiceQuery(E2AP_PDU_t *e2apMsg)
5805 {
5806    ConfigType action;
5807    uint16_t arrIdx =0, ranFuncIdx=0,tmpIdx=0;
5808    uint16_t id,revisionCcounter;
5809    bool tmpArray[MAX_RAN_FUNCTION] = {false};
5810    RICserviceQuery_t *ricServiceQuery=NULL;
5811    RicServiceUpdate ricUpdate;
5812    RANfunctionID_ItemIEs_t *ranFuncAddedItemIe;
5813    RANfunctionsID_List_t *ranFuncAddedList;
5814
5815    DU_LOG("\nINFO   -->  E2AP : RIC Service Query received");
5816    memset(&ricUpdate, 0, sizeof(RicServiceUpdate));
5817    ricUpdate.dir = RIC_INITIATED;
5818    ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
5819
5820    for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
5821    {
5822       switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
5823       {
5824          /* TODO completing in next patch/gerrit */
5825          case ProtocolIE_IDE2_id_TransactionID:
5826          {
5827             ricUpdate.transId = ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
5828             break;
5829          }
5830
5831          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5832          {
5833             ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5834             if(ranFuncAddedList->list.array)
5835             {
5836                for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
5837                {
5838                   if(ranFuncAddedList->list.array[ranFuncIdx])
5839                   {
5840                      /* Using the RAN function Id, identify the RAN function to be modified or deleted.  */
5841                      
5842                      ranFuncAddedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAddedList->list.array[ranFuncIdx];
5843                      id = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionID;
5844                      revisionCcounter = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision;
5845                      
5846                      if((id != duCb.e2apDb.ranFunction[id-1].id))
5847                      {
5848                         action = CONFIG_DEL;
5849                      }
5850                      else if((id == duCb.e2apDb.ranFunction[id-1].id)&&(revisionCcounter!=duCb.e2apDb.ranFunction[id-1].revisionCounter))
5851                      {
5852                         action = CONFIG_MOD;
5853                      }
5854
5855                      if(action == CONFIG_DEL)
5856                      {
5857                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].id = id;
5858                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].revisionCounter = revisionCcounter;
5859                         ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted++;
5860                      }
5861                      else if(action == CONFIG_MOD)
5862                      {
5863                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].id = id;
5864                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].revisionCounter = revisionCcounter;
5865                         ricUpdate.recvRanFuncList.numOfRanFunToBeModified++;
5866                      }
5867
5868                      /* If any ID is set to true, it means that the ID has been used in either modification or deletion list. 
5869                       * Else we will add the IDs into the added list */
5870                      tmpArray[id-1] = true;
5871                   }
5872                }
5873             }
5874             break;
5875          }
5876       }
5877    }
5878
5879    /*  Traversing the whole RAN function list in ducb to check if any new Ran function ids have been added. */
5880    for(arrIdx =0; arrIdx<MAX_RAN_FUNCTION; arrIdx++)
5881    {
5882       tmpIdx= ricUpdate.recvRanFuncList.numOfRanFunToBeAdded;
5883       if((duCb.e2apDb.ranFunction[arrIdx].id >0)&&(!tmpArray[arrIdx]))
5884       {
5885          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[arrIdx].id;
5886          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[arrIdx].revisionCounter;
5887          ricUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
5888       }
5889    }
5890
5891    if(BuildAndSendRicServiceUpdate(ricUpdate)!= ROK)
5892    {
5893       DU_LOG("\nERROR  -->  E2AP : Failed to build and send ric service update message");
5894    }
5895
5896    freeAperDecodingOfRicServiceQuery(ricServiceQuery);
5897 }
5898
5899 /******************************************************************
5900  *
5901  * @brief Deallocation of memory allocated by aper decoder for 
5902  *    RIC service update ack
5903  *
5904  * @details
5905  *
5906  *    Function : freeAperDecodingOfRicServiceUpdateAck
5907  *
5908  *    Functionality: Deallocation of memory allocated by aper decoder 
5909  *    for RIC service update ack
5910  *
5911  * @params[in] RICserviceUpdateAck_t *ricServiceAck;
5912  * @return void
5913  *
5914  * ****************************************************************/
5915
5916 void freeAperDecodingOfRicServiceUpdateAck(RICserviceUpdateAcknowledge_t *ricServiceAck)
5917 {
5918    uint8_t arrIdx=0,ranFuncIdx=0;
5919    RANfunctionsID_List_t *ranFuncAddedList=NULL;
5920
5921    if(ricServiceAck)
5922    {
5923       if(ricServiceAck->protocolIEs.list.array)
5924       {
5925          for(arrIdx=0; arrIdx<ricServiceAck->protocolIEs.list.count; arrIdx++)
5926          {
5927             if(ricServiceAck->protocolIEs.list.array[arrIdx])
5928             {
5929                switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id)
5930                {
5931                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5932                   {
5933                      ranFuncAddedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5934                      if(ranFuncAddedList->list.array)
5935                      {
5936                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
5937                         {
5938                            free(ranFuncAddedList->list.array[ranFuncIdx]);
5939                         }
5940                         free(ranFuncAddedList->list.array);
5941                      }
5942                      break;
5943                   }
5944                   default:
5945                      break;
5946                }
5947                free(ricServiceAck->protocolIEs.list.array[arrIdx]);  
5948             }
5949          }
5950          free(ricServiceAck->protocolIEs.list.array);
5951       }
5952    }
5953 }
5954
5955 /******************************************************************
5956  *
5957  * @brief Processes RIC service update ack sent by RIC
5958  *
5959  * @details
5960  *
5961  *    Function : procRicServiceUpdateAck
5962  *
5963  *    Functionality: Processes RIC service update ack sent by RIC
5964  *
5965  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5966  * @return ROK     - success
5967  *         RFAILED - failure
5968  *
5969  * ****************************************************************/
5970
5971 void procRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
5972 {
5973    uint8_t arrIdx =0, transId =0; 
5974    uint16_t id =0, tmpIdx=0, ranFuncIdx=0;
5975    RicServiceUpdate serviceUpdate;
5976    RANfunctionsIDcause_List_t *rejectedList=NULL;
5977    RICserviceUpdateAcknowledge_t *ricServiceAck=NULL;
5978    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
5979    
5980    DU_LOG("\nINFO   -->  E2AP : RIC service update ack received"); 
5981    memset(&serviceUpdate, 0, sizeof(RicServiceUpdate));
5982    ricServiceAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
5983    
5984    for(arrIdx=0; arrIdx<ricServiceAck->protocolIEs.list.count; arrIdx++)
5985    {
5986       switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id)
5987       {
5988          case ProtocolIE_IDE2_id_TransactionID:
5989          {
5990             transId = ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
5991             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
5992             (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
5993             {
5994               memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
5995             }
5996             else if((duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId == transId) &&\
5997             (duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
5998             {
5999               memset(&duCb.e2apDb.e2TransInfo.ricInitTransaction[transId], 0, sizeof(E2TransInfo));
6000             }
6001             else
6002             {
6003                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
6004                return ;
6005             }
6006             break;
6007          }
6008          
6009          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
6010             break;
6011
6012          case ProtocolIE_IDE2_id_RANfunctionsRejected:
6013          {
6014             rejectedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
6015             if(rejectedList->list.array)
6016             {
6017                for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
6018                {
6019                   ranFuncRejectedItemIe =  (RANfunctionIDcause_ItemIEs_t*)rejectedList->list.array[ranFuncIdx];
6020                   id = ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID;
6021                   tmpIdx= serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded;
6022                   serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[id-1].id;
6023                   serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[id-1].revisionCounter;
6024                   serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
6025                }
6026             }
6027             break;
6028          }
6029
6030       }
6031    }
6032
6033    if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
6034    {
6035       serviceUpdate.dir = E2_NODE_INITIATED;
6036       BuildAndSendRicServiceUpdate(serviceUpdate);
6037    }
6038    freeAperDecodingOfRicServiceUpdateAck(ricServiceAck);
6039 }
6040
6041 /******************************************************************
6042  *
6043  * @brief Deallocation of memory allocated by aper decoder for 
6044  *       RIC service update failure
6045  *
6046  * @details
6047  *
6048  *    Function : freeAperDecodingOfRicServiceUpdateFailure
6049  *
6050  *    Functionality: Deallocation of memory allocated by aper decoder 
6051  *    for RIC service update failure
6052  *
6053  * @params[in] RICserviceUpdateFailure_t *ricServiceFailure;
6054  * @return void
6055  *
6056  * ****************************************************************/
6057
6058 void freeAperDecodingOfRicServiceUpdateFailure(RICserviceUpdateFailure_t *ricServiceFailure)
6059 {
6060    uint8_t arrIdx=0;
6061
6062    if(ricServiceFailure)
6063    {
6064       if(ricServiceFailure->protocolIEs.list.array)
6065       {
6066          for(arrIdx=0; arrIdx<ricServiceFailure->protocolIEs.list.count; arrIdx++)
6067          {
6068             if(ricServiceFailure->protocolIEs.list.array[arrIdx])
6069             {
6070                free(ricServiceFailure->protocolIEs.list.array[arrIdx]);  
6071             }
6072          }
6073          free(ricServiceFailure->protocolIEs.list.array);
6074       }
6075    }
6076 }
6077
6078 /******************************************************************
6079  *
6080  * @brief Processes RIC service update failure sent by RIC
6081  *
6082  * @details
6083  *
6084  *    Function : procRicServiceUpdateFailure
6085  *
6086  *    Functionality: Processes RIC service update failure sent by RIC
6087  *
6088  * @params[in] E2AP_PDU_t ASN decoded E2AP message
6089  * @return ROK     - success
6090  *         RFAILED - failure
6091  *
6092  * ****************************************************************/
6093
6094 void procRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
6095 {
6096    uint8_t arrIdx =0, timerValue=0; 
6097    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
6098
6099    DU_LOG("\nINFO   -->  E2AP : RIC service update failure received"); 
6100    ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
6101
6102    for(arrIdx=0; arrIdx<ricServiceFailure->protocolIEs.list.count; arrIdx++)
6103    {
6104       switch(ricServiceFailure->protocolIEs.list.array[arrIdx]->id)
6105       {
6106          case ProtocolIE_IDE2_id_TransactionID:
6107             {
6108                break;
6109             }
6110          case ProtocolIE_IDE2_id_TimeToWaitE2:
6111             {
6112                timerValue = convertE2WaitTimerEnumToValue(ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
6113                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR)) == FALSE)
6114                {
6115                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR, timerValue);
6116                }
6117                else
6118                {
6119                   DU_LOG("\nERROR   -->  E2AP : EVENT_RIC_SERVICE_UPDATE_TMR  timer is already running");
6120                   return;
6121                }
6122                break; 
6123             }
6124          case ProtocolIE_IDE2_id_CauseE2:
6125             {
6126                break;
6127             }
6128       }
6129    }
6130
6131    freeAperDecodingOfRicServiceUpdateFailure(ricServiceFailure);
6132 }
6133
6134 /******************************************************************
6135  *
6136  * @brief DU Send E2 Node Configuration Update
6137  *
6138  * @details
6139  *
6140  *    Function : duSendE2NodeConfigurationUpdate 
6141  *
6142  *    Functionality: DU Send E2 Node Configuration Update
6143  *
6144  * @return ROK     - success
6145  *         RFAILED - failure
6146  *
6147  * ****************************************************************/
6148
6149 uint8_t duSendE2NodeConfigurationUpdate()
6150 {
6151    E2NodeConfigList e2NodeList;
6152    CmLList *node =NULL;
6153    E2NodeComponent *e2NodeComponentInfo=NULL;
6154
6155    memset(&e2NodeList, 0, sizeof(E2NodeConfigList));
6156    CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node);
6157    while(node)
6158    {
6159       e2NodeComponentInfo = (E2NodeComponent*)node->node;
6160
6161       if(e2NodeComponentInfo->addConfiguration)
6162       {
6163          e2NodeList.addE2Node[e2NodeList.addE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
6164          e2NodeList.addE2Node[e2NodeList.addE2NodeCount].componentId= e2NodeComponentInfo->componentId;
6165          e2NodeList.addE2NodeCount++;
6166          break;
6167       }
6168       if(e2NodeComponentInfo->updateConfiguration)
6169       {
6170          e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
6171          e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].componentId= e2NodeComponentInfo->componentId;
6172          e2NodeList.updateE2NodeCount++;
6173          break;
6174       }
6175       if(e2NodeComponentInfo->deleteConfiguration == true)
6176       {
6177          e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
6178          e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].componentId = e2NodeComponentInfo->componentId;
6179          e2NodeList.removeE2NodeCount++;
6180          break;
6181       }
6182       node = node->next;
6183    }
6184
6185    if(BuildAndSendE2NodeConfigUpdate(&e2NodeList) !=ROK)
6186    {
6187       DU_LOG("\nERROR  -->  E2AP : Failed to build and send e2 node config update message to RIC_stub");
6188       return RFAILED;
6189    }
6190    return ROK;
6191 }
6192
6193 /*******************************************************************
6194  *
6195  * @brief Free RIC Subscription Modification Required
6196  *
6197  * @details
6198  *
6199  *    Function : FreeRicSubsModRequired
6200  *
6201  * Functionality: Freqq RIC Subscription Modification required
6202  *
6203  * @param  E2AP Message PDU to be freed
6204  * @return void
6205  *
6206  ******************************************************************/
6207 void FreeRicSubsModRequired(E2AP_PDU_t *e2apMsg)
6208 {
6209    uint8_t ieIdx = 0, arrIdx = 0;
6210    RICsubscriptionModificationRequired_t  *ricSubsModReqd = NULLP;
6211    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
6212    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
6213    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
6214
6215    if(e2apMsg)
6216    {
6217       if(e2apMsg->choice.initiatingMessage)
6218       {
6219          ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired;
6220          if(ricSubsModReqd->protocolIEs.list.array)
6221          {
6222             for(ieIdx = 0; ieIdx < ricSubsModReqd->protocolIEs.list.count; ieIdx++)
6223             {
6224                if(ricSubsModReqd->protocolIEs.list.array[ieIdx])
6225                {
6226                   ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6227                   switch(ricSubsModReqdIe->id)
6228                   {
6229                      case ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List:
6230                         {
6231                            actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
6232                            if(actionToBeModList->list.array)
6233                            {
6234                               for(arrIdx = 0; arrIdx < actionToBeModList->list.count; arrIdx++)
6235                               { 
6236                                  DU_FREE(actionToBeModList->list.array[arrIdx], \
6237                                     sizeof(RICaction_RequiredToBeModified_ItemIEs_t));
6238                               }
6239                               DU_FREE(actionToBeModList->list.array, actionToBeModList->list.size);
6240                            }
6241                            break;
6242                         }
6243
6244                      case ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List:
6245                         {
6246                            actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
6247                            if(actionToBeRmvList->list.array)
6248                            {
6249                               for(arrIdx = 0; arrIdx < actionToBeRmvList->list.count; arrIdx++)
6250                               { 
6251                                  DU_FREE(actionToBeRmvList->list.array[arrIdx], \
6252                                     sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t));
6253                               }
6254                               DU_FREE(actionToBeRmvList->list.array, actionToBeRmvList->list.size);
6255                            }
6256                            break;
6257                         }
6258
6259                      default:
6260                         break;
6261                   }
6262                   DU_FREE(ricSubsModReqd->protocolIEs.list.array[ieIdx], \
6263                         sizeof(RICsubscriptionModificationRequired_IEs_t));
6264                }
6265             }
6266             DU_FREE(ricSubsModReqd->protocolIEs.list.array, ricSubsModReqd->protocolIEs.list.size);
6267          }
6268          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
6269       }
6270       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
6271    }
6272 }
6273
6274 /* A RIC Subscription includes RIC subsequent action only for RIC Insert service.
6275  * However, E2SM-KPM supports only RIC Report service.
6276  * Hence there is no subsequent action in RIC subscription that may require modification.
6277  * So commenting the action-modification IEs for the time being
6278  */
6279 #if 0
6280 /*******************************************************************
6281  *
6282  * @brief Fill Action required to be modified list
6283  *
6284  * @details
6285  *
6286  *    Function : FillActionReqdToBeModList
6287  *
6288  * Functionality: Fill Action required to be modified list
6289  *
6290  * @param  RIC Actions Required To Be Modified List to be filled
6291  *         Number of actions to be modified
6292  *         RIC Subscription DB
6293  * @return ROK     - success
6294  *         RFAILED - failure
6295  *
6296  ******************************************************************/
6297 uint8_t FillActionReqdToBeModList(RICactions_RequiredToBeModified_List_t *actionToBeModList, uint8_t numActionsMod,\
6298       RicSubscription *ricSubscription)
6299 {
6300    uint8_t arrIdx = 0;
6301    CmLList *actionNode = NULLP;
6302    ActionInfo *actionDb = NULLP;
6303    RICaction_RequiredToBeModified_ItemIEs_t *actionToBeMod = NULL;
6304
6305    actionToBeModList->list.count = numActionsMod;
6306    actionToBeModList->list.size = numActionsMod * sizeof(RICaction_RequiredToBeModified_ItemIEs_t *);
6307    DU_ALLOC(actionToBeModList->list.array, actionToBeModList->list.size);
6308    if(!actionToBeModList->list.array)
6309    {
6310       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6311       return RFAILED;
6312    }
6313
6314    arrIdx = 0;
6315    CM_LLIST_FIRST_NODE(&ricSubscription->actionSequence, actionNode);
6316    while(actionNode)
6317    {
6318       actionDb = (ActionInfo*)(actionNode->node);
6319       if(actionDb->action == CONFIG_MOD)
6320       {
6321          DU_ALLOC(actionToBeModList->list.array[arrIdx], sizeof(RICaction_RequiredToBeModified_ItemIEs_t));
6322          if(!actionToBeModList->list.array[arrIdx])
6323          {
6324             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6325             return RFAILED;
6326          }
6327          actionToBeMod = (RICaction_RequiredToBeModified_ItemIEs_t *)actionToBeModList->list.array[arrIdx];
6328
6329          actionToBeMod->id = ProtocolIE_IDE2_id_RICaction_RequiredToBeModified_Item;
6330          actionToBeMod->criticality = CriticalityE2_reject;
6331          actionToBeMod->value.present = \
6332             RICaction_RequiredToBeModified_ItemIEs__value_PR_RICaction_RequiredToBeModified_Item;
6333          actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricActionID = \
6334             actionDb->actionId;
6335          actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricTimeToWait = RICtimeToWait_w5ms;
6336
6337          arrIdx++;
6338       }
6339    }
6340
6341    return ROK;
6342 }
6343 #endif
6344 /*******************************************************************
6345  *
6346  * @brief Fill Action required to be removed list
6347  *
6348  * @details
6349  *
6350  *    Function : FillActionReqdToBeRmvList
6351  *
6352  * Functionality: Fill Action required to be removed list
6353  *
6354  * @param  RIC Actions Required To Be Removed List to be filled
6355  *         Number of actions to be removed
6356  *         RIC Subscription DB
6357  * @return ROK     - success
6358  *         RFAILED - failure
6359  *
6360  ******************************************************************/
6361 uint8_t FillActionReqdToBeRmvList(RICactions_RequiredToBeRemoved_List_t *actionToBeRmvList, uint8_t numActionsRmv, \
6362    RicSubscription *ricSubscription)
6363 {
6364    uint8_t arrIdx = 0;
6365    CmLList *actionNode = NULLP;
6366    ActionInfo *actionDb = NULLP;
6367    RICaction_RequiredToBeRemoved_ItemIEs_t *actionToBeRmv = NULL;
6368
6369    actionToBeRmvList->list.count = numActionsRmv;
6370    actionToBeRmvList->list.size = numActionsRmv * sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t *);
6371    DU_ALLOC(actionToBeRmvList->list.array, actionToBeRmvList->list.size);
6372    if(!actionToBeRmvList->list.array)
6373    {
6374       DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6375       return RFAILED;
6376    }
6377
6378    arrIdx = 0;
6379    CM_LLIST_FIRST_NODE(&ricSubscription->actionSequence, actionNode);
6380    while(actionNode)
6381    {
6382       actionDb = (ActionInfo*)(actionNode->node);
6383       if(actionDb->action == CONFIG_DEL)
6384       {
6385          DU_ALLOC(actionToBeRmvList->list.array[arrIdx], sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t));
6386          if(!actionToBeRmvList->list.array[arrIdx])
6387          {
6388             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6389             return RFAILED;
6390          }
6391          actionToBeRmv = (RICaction_RequiredToBeRemoved_ItemIEs_t *)actionToBeRmvList->list.array[arrIdx];
6392
6393          actionToBeRmv->id = ProtocolIE_IDE2_id_RICaction_RequiredToBeRemoved_Item;
6394          actionToBeRmv->criticality = CriticalityE2_reject;
6395          actionToBeRmv->value.present = \
6396             RICaction_RequiredToBeRemoved_ItemIEs__value_PR_RICaction_RequiredToBeRemoved_Item;
6397          actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.ricActionID = actionDb->actionId;
6398          fillE2Cause(&actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.cause, actionDb->failureCause);
6399          arrIdx++;
6400       }
6401    }
6402
6403    return ROK;
6404 }
6405
6406 /*******************************************************************
6407  *
6408  * @brief Fill RIC Subscription Modification Required IEs
6409  *
6410  * @details
6411  *
6412  *    Function : FillRicSubsModRequired
6413  *
6414  * Functionality: Fill RIC Subscription Modification Required IEs
6415  *
6416  * @param  RIC Subscription Modification Required IEs to be filled
6417  *         RIC Subscription DB
6418  * @return ROK     - success
6419  *         RFAILED - failure
6420  *
6421  ******************************************************************/
6422 uint8_t FillRicSubsModRequired(RICsubscriptionModificationRequired_t *ricSubsModReqd, RicSubscription *ricSubscription)
6423 {
6424    ActionInfo * actionDb=NULLP;
6425    CmLList *actionNode = NULLP;
6426    uint8_t ieIdx = 0, elementCnt=0;
6427    uint8_t numActionsMod = 0, numActionsRmv = 0;
6428    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
6429    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
6430
6431 /* Unused in case of E2SM-KPM */
6432 #if 0
6433    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
6434 #endif
6435
6436    /* Count number of Actions to be modified or deleted */
6437    CM_LLIST_FIRST_NODE(&ricSubscription->actionSequence, actionNode);
6438    while(actionNode)
6439    {
6440        actionDb = (ActionInfo*)(actionNode->node);
6441        if(actionDb->action == CONFIG_MOD)
6442           numActionsMod++;
6443        else if(actionDb->action == CONFIG_DEL)
6444           numActionsRmv++;
6445        actionNode = actionNode->next;
6446    }
6447
6448    /* Count number of IEs to be added to messages */
6449    elementCnt = 2;
6450    if(numActionsMod)
6451       elementCnt++;
6452    if(numActionsRmv)
6453       elementCnt++;
6454
6455    ricSubsModReqd->protocolIEs.list.count = elementCnt;
6456    ricSubsModReqd->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationRequired_IEs_t *);
6457    DU_ALLOC(ricSubsModReqd->protocolIEs.list.array, ricSubsModReqd->protocolIEs.list.size);
6458    if(!ricSubsModReqd->protocolIEs.list.array)
6459    {
6460       DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6461       return RFAILED;
6462    }
6463
6464    for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
6465    {
6466       DU_ALLOC(ricSubsModReqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRequired_IEs_t));
6467       if(!ricSubsModReqd->protocolIEs.list.array[ieIdx])
6468       {
6469          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6470          return RFAILED;
6471       }
6472    }
6473
6474    /* RIC Request ID */
6475    ieIdx = 0;
6476    ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6477    ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICrequestID;
6478    ricSubsModReqdIe->criticality = CriticalityE2_reject;
6479    ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RICrequestID;
6480    ricSubsModReqdIe->value.choice.RICrequestID.ricRequestorID = ricSubscription->requestId.requestorId;
6481    ricSubsModReqdIe->value.choice.RICrequestID.ricInstanceID = ricSubscription->requestId.instanceId;
6482
6483    /* RAN Function ID */
6484    ieIdx++;
6485    ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6486    ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RANfunctionID;
6487    ricSubsModReqdIe->criticality = CriticalityE2_reject;
6488    ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RANfunctionID;
6489    ricSubsModReqdIe->value.choice.RANfunctionID = ricSubscription->ranFuncId;
6490
6491 /* A RIC Subscription includes RIC subsequent action only for RIC Insert service.
6492  * However, E2SM-KPM supports only RIC Report service.
6493  * Hence there is no subsequent action in RIC subscription that may require modification.
6494  * So commenting the action-modification IEs for the time being
6495  */
6496 #if 0
6497    /* RIC Actions Required to be Modified */
6498    if(numActionsMod)
6499    {
6500       ieIdx++;
6501       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6502       ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List;
6503       ricSubsModReqdIe->criticality = CriticalityE2_reject;
6504       ricSubsModReqdIe->value.present = \
6505          RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeModified_List;
6506       actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
6507
6508       if(FillActionReqdToBeModList(actionToBeModList, numActionsMod, ricSubscription) != ROK)
6509       {
6510          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill actions required to be modified list", __func__);
6511          return RFAILED;
6512       }
6513    }
6514 #endif
6515
6516    /* RIC Actions Required to be removed */
6517    if(numActionsRmv)
6518    {
6519       ieIdx++;
6520       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6521       ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List;
6522       ricSubsModReqdIe->criticality = CriticalityE2_reject;
6523       ricSubsModReqdIe->value.present = \
6524          RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeRemoved_List;
6525       actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
6526
6527       if(FillActionReqdToBeRmvList(actionToBeRmvList, numActionsRmv, ricSubscription) != ROK)
6528       {
6529          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill actions required to be removed list", __func__);
6530          return RFAILED;
6531       }
6532    }
6533
6534    return ROK;
6535 }
6536
6537 /*******************************************************************
6538  *
6539  * @brief Builds and Send RIC Subscription Modification Required
6540  *        message
6541  *
6542  * @details
6543  *
6544  *    Function : BuildAndSendRicSubsModRequired
6545  *
6546  * Functionality:  Builds and Send RIC Subscription Modification 
6547  *    Required message
6548  *
6549  * @param  RIC Subscription DB
6550  * @return ROK     - success
6551  *         RFAILED - failure
6552  *
6553  ******************************************************************/
6554 uint8_t BuildAndSendRicSubsModRequired(RicSubscription *ricSubscription)
6555 {
6556    uint8_t ret = RFAILED;
6557    E2AP_PDU_t        *e2apMsg = NULLP;
6558    RICsubscriptionModificationRequired_t  *ricSubsModReqd = NULLP;
6559    asn_enc_rval_t     encRetVal;       /* Encoder return value */
6560
6561    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Required \n");
6562    while(true)
6563    {
6564       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
6565       if(e2apMsg == NULLP)
6566       {
6567          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6568          break;
6569       }
6570
6571       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
6572       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
6573       if(e2apMsg->choice.initiatingMessage == NULLP)
6574       {
6575          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6576          break;
6577       }
6578       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
6579       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired;
6580       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionModificationRequired;
6581
6582       ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired;
6583
6584       if(FillRicSubsModRequired(ricSubsModReqd, ricSubscription) != ROK)
6585       {
6586          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Subscription Modification Required IEs", __func__);
6587          break;
6588       }
6589       
6590       /* Encode */
6591       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6592
6593       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6594       encBufSize = 0;
6595       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6596       if(encRetVal.encoded == ENCODE_FAIL)
6597       {
6598          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Modifiction Required structure (at %s)\n",\
6599                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6600          break;
6601       }
6602       else
6603       {
6604          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RIC Subscription Modification Required \n");
6605 #ifdef DEBUG_ASN_PRINT
6606          for(int i=0; i< encBufSize; i++)
6607          {
6608             printf("%x",encBuf[i]);
6609          }
6610 #endif
6611       }
6612       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
6613       {
6614          DU_LOG("\nERROR  -->  E2AP : Sending RIC Subscription Modification Required failed");
6615       }
6616
6617       ret = ROK;
6618       break;
6619    }
6620
6621    /* Free RIC Subscription modification required */
6622    FreeRicSubsModRequired(e2apMsg);
6623    return ret;
6624 }
6625
6626 /*******************************************************************
6627  *
6628  * @brief Free APER decoding of RIC Subscription Modification Confirm
6629  *
6630  * @details
6631  *
6632  *    Function : freeAperDecodingOfRicSubsModConfirm
6633  *
6634  * Functionality:  Free APER decoding of RIC Subscription 
6635  *   Modification Confirm
6636  *
6637  * @param  E2AP Message PDU
6638  * @return void
6639  *
6640  ******************************************************************/
6641 void freeAperDecodingOfRicSubsModConfirm(E2AP_PDU_t *e2apMsg)
6642 {
6643    uint8_t ieIdx = 0, arrIdx=0;
6644    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
6645    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
6646    RICactions_ConfirmedForModification_List_t *modCfmList = NULLP;
6647    RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP;
6648    RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP;
6649    RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP;
6650
6651    if(e2apMsg && e2apMsg->choice.successfulOutcome)
6652    {
6653       ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
6654       if(ricSubsModCfm->protocolIEs.list.array)
6655       {
6656          for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++)
6657          {
6658             if(ricSubsModCfm->protocolIEs.list.array[ieIdx])
6659             {
6660                ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
6661                switch(ricSubsModCfmIe->id)
6662                {
6663                   case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List:
6664                      {
6665                         modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List;
6666                         if(modCfmList->list.array)
6667                         {
6668                            for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
6669                            {
6670                               if(modCfmList->list.array[arrIdx])
6671                                  free(modCfmList->list.array[arrIdx]);
6672                            }
6673                            free(modCfmList->list.array);
6674                         }
6675                         break;
6676                      }
6677
6678                   case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List:
6679                      {
6680                         modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List;
6681                         if(modRefusedList->list.array)
6682                         {
6683                            for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
6684                            {
6685                               if(modRefusedList->list.array[arrIdx])
6686                                  free(modRefusedList->list.array[arrIdx]);
6687                            }
6688                            free(modRefusedList->list.array);
6689                         }
6690                         break;
6691                      }
6692
6693                   case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List:
6694                      {
6695                         rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List;
6696                         if(rmvCfmList->list.array)
6697                         {
6698                            for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
6699                            {
6700                               if(rmvCfmList->list.array[arrIdx])
6701                                  free(rmvCfmList->list.array[arrIdx]);
6702                            }
6703                            free(rmvCfmList->list.array);
6704                         }
6705                         break;
6706                      }
6707
6708                   case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List:
6709                      {
6710                         rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List;
6711                         if(rmvFailList->list.array)
6712                         {
6713                            for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
6714                            {
6715                               if(rmvFailList->list.array[arrIdx])
6716                                  free(rmvFailList->list.array[arrIdx]);
6717                            }
6718                            free(rmvFailList->list.array);
6719                         }
6720                         break;
6721                      }
6722
6723                   default:
6724                      break;
6725
6726                }
6727                free(ricSubsModCfmIe);
6728             }
6729          }
6730          free(ricSubsModCfm->protocolIEs.list.array);
6731       }
6732    }
6733 }
6734
6735 /*******************************************************************
6736  *
6737  * @brief Process RIC Subscription Modification Confirm Message
6738  *
6739  * @details
6740  *
6741  *    Function : procRicSubscriptionModificationConfirm
6742  *
6743  * Functionality:  Process RIC Subscription Modification Confirm
6744  *    Message received from RIC. 
6745  *
6746  * @param  E2AP Message PDU
6747  * @return void
6748  *
6749  ******************************************************************/
6750 void procRicSubscriptionModificationConfirm(E2AP_PDU_t *e2apMsg)
6751 {
6752    uint8_t actionId = 0, ieIdx = 0, arrIdx = 0;
6753    uint16_t ranFuncId = 0;
6754    bool procFailure = false;
6755    RicRequestId ricReqId;
6756    RanFunction *ranFuncDb = NULLP;
6757    CmLList *ricSubsNode = NULLP;
6758    CmLList *actionNode= NULLP;
6759    RicSubscription *ricSubsDb = NULLP;
6760    ActionInfo *actionDb = NULLP;
6761
6762    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
6763    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
6764
6765 /* Not used in case of E2SM-KPM */
6766 #if 0
6767    RICactions_ConfirmedForModification_List_t *modCfmList = NULLP;
6768    RICaction_ConfirmedForModification_ItemIEs_t *modCfmListItem = NULLP;
6769
6770    RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP;
6771    RICaction_RefusedToBeModified_ItemIEs_t *modRefusedListItem = NULLP;
6772 #endif
6773
6774    RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP;
6775    RICaction_ConfirmedForRemoval_ItemIEs_t *rmvCfmListItem = NULLP;
6776
6777    RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP;
6778    RICaction_RefusedToBeRemoved_ItemIEs_t *rmvFailListItem = NULLP;
6779
6780    DU_LOG("\nINFO   -->  E2AP : %s: Received RIC Subscription Modification Confirm", __func__);
6781
6782    do{
6783       if(!e2apMsg)
6784       {
6785          DU_LOG("\nERROR  -->  E2AP : %s: E2AP Message is NULL", __func__);
6786          break;
6787       }
6788
6789       if(!e2apMsg->choice.successfulOutcome)
6790       {
6791          DU_LOG("\nERROR  -->  E2AP : %s: Successful Outcome in E2AP message is NULL", __func__);
6792          break;
6793       }
6794
6795       ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
6796       if(!ricSubsModCfm->protocolIEs.list.array)
6797       {
6798          DU_LOG("\nERROR  -->  E2AP : %s: Array conatining E2AP message IEs is null", __func__);
6799          break;
6800       }
6801
6802       for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++)
6803       {
6804          if(!ricSubsModCfm->protocolIEs.list.array[ieIdx])
6805          {
6806             DU_LOG("\nERROR  -->  E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx);
6807             break;
6808          }
6809
6810          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
6811          switch(ricSubsModCfmIe->id)
6812          {
6813             case ProtocolIE_IDE2_id_RICrequestID:
6814                {
6815                   memset(&ricReqId, 0, sizeof(RicRequestId));
6816                   ricReqId.requestorId = ricSubsModCfmIe->value.choice.RICrequestID.ricRequestorID;
6817                   ricReqId.instanceId = ricSubsModCfmIe->value.choice.RICrequestID.ricInstanceID;
6818                   break;
6819                }
6820
6821             case ProtocolIE_IDE2_id_RANfunctionID:
6822                {
6823                   ranFuncId = ricSubsModCfmIe->value.choice.RANfunctionID;
6824                   ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
6825                   if(!ranFuncDb)
6826                   {
6827                      DU_LOG("\nERROR  -->  E2AP : %s: RAN Function ID [%d] not found", __func__, ranFuncId);
6828                      procFailure = true;
6829                      break;
6830                   }
6831
6832                   ricSubsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode); 
6833                   if(!ricSubsDb)
6834                   {
6835                      DU_LOG("\nERROR  -->  E2AP : %s: RIC Subscription not found for Requestor_ID [%d] Instance_ID [%d]",\
6836                            __func__, ricReqId.requestorId, ricReqId.instanceId);
6837                      procFailure = true;
6838                      break;
6839                   }
6840
6841                   break;
6842                }
6843
6844 /* A RIC Subscription includes RIC subsequent action only for RIC Insert service. 
6845  * However, E2SM-KPM supports only RIC Report service. 
6846  * Hence there is no subsequent action in RIC subscription that may require modification. 
6847  * So commenting the action-modification IEs for the time being 
6848  */
6849 #if 0
6850             case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List:
6851                {
6852                   modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List;
6853                   for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
6854                   {
6855                      modCfmListItem = (RICaction_ConfirmedForModification_ItemIEs_t *)modCfmList->list.array[arrIdx];
6856                      actionId = modCfmListItem->value.choice.RICaction_ConfirmedForModification_Item.ricActionID;
6857
6858                      actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb, &actionNode, CONFIG_UNKNOWN);
6859                      if(!actionDb)
6860                      {
6861                         DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6862                      }
6863                      else
6864                      {
6865                         actionDb->action = CONFIG_UNKNOWN;
6866                         /* Further handling can be added here in future once the
6867                          * use case of this procedure is identified */
6868                      }
6869                      actionDb = NULLP;
6870                   }
6871                   break;
6872                }
6873
6874             case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List:
6875                {
6876                   modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List;
6877                   for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
6878                   {
6879                     modRefusedListItem = (RICaction_RefusedToBeModified_ItemIEs_t *)modRefusedList->list.array[arrIdx];
6880                     actionId = modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.ricActionID;
6881                     actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb, &actionNode, CONFIG_UNKNOWN);
6882                     if(!actionDb)
6883                     {
6884                        DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6885                     }
6886                     else
6887                     {
6888                        /* Spec doesnt mention if in case of failure, DU should retry for modify action 
6889                         * Hence, chaging the action from CONFIG_MOD to CONFIG_UNKNOWN
6890                         */
6891                         actionDb->action = CONFIG_UNKNOWN;
6892                     }
6893                     actionDb = NULLP;
6894                   }
6895                   break;
6896                }
6897 #endif
6898
6899             case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List:
6900                {
6901                   rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List;
6902                   for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
6903                   {
6904                      rmvCfmListItem = (RICaction_ConfirmedForRemoval_ItemIEs_t *)rmvCfmList->list.array[arrIdx];
6905                      actionId = rmvCfmListItem->value.choice.RICaction_ConfirmedForRemoval_Item.ricActionID;
6906                      actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb, &actionNode, CONFIG_UNKNOWN);
6907                      if(!actionDb)
6908                      {
6909                         DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6910                      }
6911                      else
6912                      {
6913                         cmLListDelFrm(&ricSubsDb->actionSequence, actionNode);
6914                         deleteActionSequence(actionNode);
6915                         actionDb =NULLP;
6916                         /* Further handling can include :
6917                          * Deletion of this action from all DU layers 
6918                          */
6919                      }
6920                      actionDb = NULLP;
6921                   }
6922                   break;
6923                }
6924
6925             case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List:
6926                {
6927                   rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List;
6928                   for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
6929                   {
6930                      rmvFailListItem = (RICaction_RefusedToBeRemoved_ItemIEs_t *)rmvFailList->list.array[arrIdx];
6931                      actionId = rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.ricActionID;
6932                      actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb,  &actionNode, CONFIG_UNKNOWN);
6933                      if(!actionDb)
6934                      {
6935                         DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6936                      }
6937                      else
6938                      {
6939                         actionDb->action = CONFIG_UNKNOWN;
6940                      }
6941                      actionDb = NULLP;
6942                   }
6943                   break;
6944                }
6945
6946             default:
6947                break;
6948          } /* End of switch for Protocol IE Id */
6949
6950          if(procFailure)
6951             break;
6952       } /* End of for loop for Protocol IE list */
6953
6954       break;
6955    }while(true);
6956
6957    freeAperDecodingOfRicSubsModConfirm(e2apMsg);
6958    return;
6959 }
6960
6961 /******************************************************************
6962 * @brief Deallocate the memory allocated for E2 Reset Response
6963 *
6964 * @details
6965 *
6966 *    Function : FreeE2ResetResponse
6967 *
6968 *    Functionality:
6969 *       - freeing the memory allocated for E2ResetResponse
6970 *
6971 * @params[in] E2AP_PDU_t *e2apMsg
6972 * @return ROK     - success
6973 *         RFAILED - failure
6974 *
6975 * ****************************************************************/
6976 void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg)
6977 {
6978    uint8_t ieIdx =0;
6979    ResetResponseE2_t *resetResponse;
6980
6981    if(e2apMsg != NULLP)
6982    {
6983       if(e2apMsg->choice.successfulOutcome != NULLP)
6984       {
6985          resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
6986          if(resetResponse->protocolIEs.list.array)
6987          {
6988             for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
6989             {
6990                if(resetResponse->protocolIEs.list.array[ieIdx])
6991                {
6992                   DU_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
6993                }
6994             }
6995             DU_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
6996          }
6997
6998          DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
6999       }
7000       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
7001    }
7002 }
7003
7004 /*******************************************************************
7005  *
7006  * @brief Buld and send the E2 Reset Response msg
7007  *
7008  * @details
7009  *
7010  *    Function : BuildAndSendE2ResetResponse
7011  *
7012  *    Functionality:
7013  *         - Buld and send the E2 Reset Response Message
7014  *
7015  * @params[in] Trans Id
7016  * @return ROK     - success
7017  *         RFAILED - failure
7018  *
7019  * ****************************************************************/
7020 uint8_t BuildAndSendResetResponse(uint8_t transId)
7021 {
7022    uint8_t           ieIdx = 0, elementCnt = 0;
7023    uint8_t           ret = RFAILED;
7024    E2AP_PDU_t        *e2apMsg = NULLP;
7025    ResetResponseE2_t *resetResponse;
7026    asn_enc_rval_t    encRetVal;       /* Encoder return value */
7027
7028    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
7029    do
7030    {
7031       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
7032       if(e2apMsg == NULLP)
7033       {
7034          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
7035          break;
7036       }
7037       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
7038
7039       DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
7040       if(e2apMsg->choice.successfulOutcome == NULLP)
7041       {
7042          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
7043          break;
7044       }
7045
7046       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
7047       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
7048       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
7049       resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
7050
7051       elementCnt = 1;
7052       resetResponse->protocolIEs.list.count = elementCnt;
7053       resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
7054       DU_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
7055       if(!resetResponse->protocolIEs.list.array)
7056       {
7057          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
7058          break;
7059       }
7060
7061       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
7062       {
7063          DU_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
7064          if(!resetResponse->protocolIEs.list.array[ieIdx])
7065          {
7066             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
7067             break;
7068          }
7069       }
7070       if(ieIdx < elementCnt)
7071          break;
7072
7073       ieIdx = 0;
7074       resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
7075       resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
7076       resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
7077       resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
7078
7079       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
7080
7081       memset(encBuf, 0, ENC_BUF_MAX_LEN);
7082       encBufSize = 0;
7083       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
7084       if(encRetVal.encoded == ENCODE_FAIL)
7085       {
7086          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
7087                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
7088          break;
7089       }
7090       else
7091       {
7092          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
7093          for(int i=0; i< encBufSize; i++)
7094          {
7095             DU_LOG("%x",encBuf[i]);
7096          }
7097       }
7098
7099       /* Sending msg */
7100       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
7101       {
7102          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
7103          break;
7104       }
7105
7106       ret = ROK;
7107       break;
7108    }while(true);
7109
7110    FreeE2ResetResponse(e2apMsg);
7111    return ret;
7112 }
7113
7114 /******************************************************************
7115  *
7116  * @brief Deallocation of memory allocated by aper decoder for reset req
7117  *
7118  * @details
7119  *
7120  *    Function : freeAperDecodingOfE2ResetReq
7121  *
7122  *    Functionality: Deallocation of memory allocated by aper decoder for
7123  *    reset req
7124  *
7125  * @params[in] Pointer to resetReq
7126  * @return void
7127  *
7128  * ****************************************************************/
7129 void freeAperDecodingOfE2ResetReq(ResetRequestE2_t *resetReq)
7130 {
7131    uint8_t arrIdx=0;
7132
7133    if(resetReq)
7134    {
7135       if(resetReq->protocolIEs.list.array)
7136       {
7137          for(arrIdx=0; arrIdx<resetReq->protocolIEs.list.count; arrIdx++)
7138          {
7139             if(resetReq->protocolIEs.list.array[arrIdx])
7140             {
7141                free(resetReq->protocolIEs.list.array[arrIdx]);
7142             }
7143          }
7144          free(resetReq->protocolIEs.list.array);
7145       }
7146    }
7147 }
7148
7149 /*******************************************************************
7150  *
7151  * @brief Process reset req received from RIC
7152  *
7153  * @details
7154  *
7155  *    Function : procE2ResetRequest
7156  *
7157  * Functionality: Process reset req received from RIC
7158  *
7159  * @param  E2AP_PDU_t  *e2apMsg
7160  * @return void
7161  *
7162  ******************************************************************/
7163
7164 void procE2ResetRequest(E2AP_PDU_t  *e2apMsg)
7165 {
7166    uint16_t ranFuncIdx=0;
7167    uint8_t arrIdx =0, transId =0;
7168    ResetRequestE2_t *resetReq;
7169
7170    DU_LOG("\nINFO   -->  E2AP : E2 Reset request received");
7171    resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
7172
7173    for(arrIdx=0; arrIdx<resetReq->protocolIEs.list.count; arrIdx++)
7174    {
7175       switch(resetReq->protocolIEs.list.array[arrIdx]->id)
7176       {
7177          case ProtocolIE_IDE2_id_TransactionID:
7178             {
7179                transId = resetReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
7180                break;
7181             }
7182
7183          case ProtocolIE_IDE2_id_CauseE2:
7184             {
7185                for(ranFuncIdx=0; ranFuncIdx<MAX_RAN_FUNCTION; ranFuncIdx++)
7186                {
7187                   if(duCb.e2apDb.ranFunction[ranFuncIdx].id >0)
7188                   {
7189                      deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList));
7190                      memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo));
7191                   }
7192                }
7193                break;
7194             }
7195       }
7196    }
7197    if(BuildAndSendResetResponse(transId) != ROK)
7198    {
7199       DU_LOG("\nERROR  -->  E2AP : Failed to build and send reset response");
7200    }
7201    freeAperDecodingOfE2ResetReq(resetReq);
7202 }
7203
7204 /*******************************************************************
7205  *
7206  * @brief Free APER decoding of RIC Subscription Modification Refuse
7207  *
7208  * @details
7209  *
7210  *    Function : freeAperDecodingOfRicSubsModRefuse
7211  *
7212  * Functionality:  Free APER decoding of RIC Subscription 
7213  *   Modification Refuse
7214  *
7215  * @param  E2AP Message PDU
7216  * @return void
7217  *
7218  ******************************************************************/
7219 void freeAperDecodingOfRicSubsModRefuse(E2AP_PDU_t *e2apMsg)
7220 {
7221    uint8_t ieIdx =0;
7222    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
7223
7224    if(e2apMsg && e2apMsg->choice.unsuccessfulOutcome)
7225    {
7226       ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
7227       if(ricSubsModRefuse->protocolIEs.list.array)
7228       {
7229          for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++)
7230          {
7231             if(ricSubsModRefuse->protocolIEs.list.array[ieIdx])
7232                free(ricSubsModRefuse->protocolIEs.list.array[ieIdx]);
7233          }
7234          free(ricSubsModRefuse->protocolIEs.list.array);
7235       }
7236    }
7237 }
7238
7239 /*******************************************************************
7240  *
7241  * @brief Process RIC Subscription Modification Refuse Message
7242  *
7243  * @details
7244  *
7245  *    Function : procRicSubscriptionModificationRefuse
7246  *
7247  * Functionality:  Process RIC Subscription Modification Refuse
7248  *    Message received from RIC. 
7249  *
7250  * @param  E2AP Message PDU
7251  * @return void
7252  *
7253  ******************************************************************/
7254 void procRicSubscriptionModificationRefuse(E2AP_PDU_t *e2apMsg)
7255 {
7256    uint8_t ieIdx = 0;
7257    uint16_t ranFuncId = 0;
7258    RicRequestId ricReqId;
7259    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
7260    RICsubscriptionModificationRefuse_IEs_t *ricSubsModRefuseIe = NULLP;
7261    CauseE2_t *cause = NULLP;
7262
7263    DU_LOG("\nINFO   -->  E2AP : %s: Received RIC Subscription Modification Refuse", __func__);
7264
7265    do{
7266       if(!e2apMsg)
7267       {
7268          DU_LOG("\nERROR  -->  E2AP : %s: E2AP Message is NULL", __func__);
7269          break;
7270       }
7271
7272       if(!e2apMsg->choice.unsuccessfulOutcome)
7273       {
7274          DU_LOG("\nERROR  -->  E2AP : %s: Unsuccessful Outcome in E2AP message is NULL", __func__);
7275          break;
7276       }
7277
7278       ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
7279       if(!ricSubsModRefuse->protocolIEs.list.array)
7280       {
7281          DU_LOG("\nERROR  -->  E2AP : %s: Array conatining E2AP message IEs is null", __func__);
7282          break;
7283       }
7284
7285       for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++)
7286       {
7287          if(!ricSubsModRefuse->protocolIEs.list.array[ieIdx])
7288          {
7289             DU_LOG("\nERROR  -->  E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx);
7290             break;
7291          }
7292
7293          ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
7294          switch(ricSubsModRefuseIe->id)
7295          {
7296             case ProtocolIE_IDE2_id_RICrequestID:
7297                {
7298                   memset(&ricReqId, 0, sizeof(RicRequestId));
7299                   ricReqId.requestorId = ricSubsModRefuseIe->value.choice.RICrequestID.ricRequestorID;
7300                   ricReqId.instanceId = ricSubsModRefuseIe->value.choice.RICrequestID.ricInstanceID;
7301                   break;
7302                }
7303
7304             case ProtocolIE_IDE2_id_RANfunctionID:
7305                {
7306                   ranFuncId = ricSubsModRefuseIe->value.choice.RANfunctionID;
7307                   break;
7308                }
7309
7310             case ProtocolIE_IDE2_id_CauseE2:
7311                {
7312                   DU_LOG("\nDEBUG  -->  E2AP : %s: RIC subscriptiom modification refused for RIC_Requestor_ID [%d] \
7313                         RIC_Instance_ID [%d] RAN_Function_ID [%d] ", __func__, ricReqId.requestorId, \
7314                         ricReqId.instanceId, ranFuncId);
7315
7316                   cause = &ricSubsModRefuseIe->value.choice.CauseE2;
7317                   printE2ErrorCause(cause);
7318                }
7319
7320             default:
7321                break;
7322          } /* End of switch for Protocol IE Id */
7323       } /* End of for loop for Protocol IE list */
7324
7325       break;
7326    }while(true);
7327
7328    freeAperDecodingOfRicSubsModRefuse(e2apMsg);
7329    return;
7330 }
7331
7332 /*******************************************************************
7333  *
7334  * @brief Free RIC Subscription Delete Required Message
7335  *
7336  * @details
7337  *
7338  *    Function : FreeRicSubscriptionDeleteRequired
7339  *
7340  * Functionality:  Free RIC Subscription Delete Required
7341  *
7342  * @param  E2AP Message PDU
7343  * @return void
7344  *
7345  ******************************************************************/
7346 void FreeRicSubscriptionDeleteRequired(E2AP_PDU_t *e2apMsg, CmLListCp *ricSubsToBeDelList)
7347 {
7348    uint8_t ieIdx = 0, arrIdx = 0;
7349    RICsubscriptionDeleteRequired_t *ricSubsDelRqd = NULLP;
7350    RICsubscriptionDeleteRequired_IEs_t *ricSubsDelRqdIe = NULLP;
7351    RICsubscription_List_withCause_t *ricSubsList = NULLP;
7352    CmLList *subsNode = NULLP;
7353
7354    if(e2apMsg)
7355    {
7356       if(e2apMsg->choice.initiatingMessage)
7357       {
7358          ricSubsDelRqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired;
7359          if(ricSubsDelRqd->protocolIEs.list.array)
7360          {
7361             for(ieIdx = 0; ieIdx < ricSubsDelRqd->protocolIEs.list.count; ieIdx++)
7362             {
7363                if(ricSubsDelRqd->protocolIEs.list.array[ieIdx])
7364                {
7365                   ricSubsDelRqdIe = ricSubsDelRqd->protocolIEs.list.array[ieIdx];
7366                   switch(ricSubsDelRqdIe->id)
7367                   {
7368                      case ProtocolIE_IDE2_id_RICsubscriptionToBeRemoved:
7369                         {
7370                            ricSubsList = &ricSubsDelRqdIe->value.choice.RICsubscription_List_withCause;
7371                            if(ricSubsList->list.array)
7372                            {
7373                               for(arrIdx = 0; arrIdx < ricSubsList->list.count; arrIdx++)
7374                               {
7375                                  DU_FREE(ricSubsList->list.array[ieIdx], sizeof(RICsubscription_withCause_ItemIEs_t));
7376                               }
7377                               DU_FREE(ricSubsList->list.array, ricSubsList->list.size);
7378                            }
7379                            break;
7380                         }
7381                   }
7382                   DU_FREE(ricSubsDelRqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequired_IEs_t));
7383                }
7384             }
7385             DU_FREE(ricSubsDelRqd->protocolIEs.list.array, ricSubsDelRqd->protocolIEs.list.size);
7386          }
7387          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
7388       }
7389       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));;
7390    }
7391
7392    if(ricSubsToBeDelList)
7393    {
7394       CM_LLIST_FIRST_NODE(ricSubsToBeDelList, subsNode);
7395       while(subsNode)
7396       {
7397          cmLListDelFrm(ricSubsToBeDelList, subsNode);
7398          DU_FREE(subsNode, sizeof(CmLList));
7399          CM_LLIST_FIRST_NODE(ricSubsToBeDelList, subsNode);
7400       }
7401    }
7402 }
7403
7404 /*******************************************************************
7405  *
7406  * @brief Fill list of RIC subscriptions required to be deleted
7407  *    with the cause of deletion
7408  *
7409  * @details
7410  *
7411  *    Function : fillRicSubsListWithCause
7412  *
7413  * Functionality:  Fill list of RIC subscriptions required to be 
7414  *    deleted with the cause of deletion
7415  *
7416  * @param  E2AP Message PDU
7417  * @return void
7418  *
7419  ******************************************************************/
7420 uint8_t fillRicSubsListWithCause(RICsubscription_List_withCause_t *ricSubsList, CmLListCp ricSubsToBeDelList)
7421 {
7422    uint16_t ieIdx = 0;
7423    CmLList *subsNode = NULLP;
7424    RicSubscription *subsInfo = NULLP;
7425    RICsubscription_withCause_ItemIEs_t *subsItemIe = NULLP;
7426    RICsubscription_withCause_Item_t *subsItem = NULLP;
7427
7428    ricSubsList->list.count = ricSubsToBeDelList.count;
7429    ricSubsList->list.size = ricSubsList->list.count * sizeof(RICsubscription_withCause_ItemIEs_t *);
7430    DU_ALLOC(ricSubsList->list.array, ricSubsList->list.size);
7431    if(!ricSubsList->list.array)
7432    {
7433       DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7434       return RFAILED;
7435    }
7436
7437    CM_LLIST_FIRST_NODE(&ricSubsToBeDelList, subsNode);
7438    while(subsNode && (ieIdx < ricSubsList->list.count))
7439    {
7440       subsInfo = (RicSubscription *)subsNode->node;
7441       DU_ALLOC(ricSubsList->list.array[ieIdx], sizeof(RICsubscription_withCause_ItemIEs_t));
7442       if(!ricSubsList->list.array[ieIdx])
7443       {
7444          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7445          return RFAILED;
7446       }
7447
7448       subsItemIe = (RICsubscription_withCause_ItemIEs_t *)ricSubsList->list.array[ieIdx];
7449       subsItemIe->id = ProtocolIE_IDE2_id_RICsubscription_withCause_Item;
7450       subsItemIe->criticality = CriticalityE2_ignore;
7451       subsItemIe->value.present = RICsubscription_withCause_ItemIEs__value_PR_RICsubscription_withCause_Item;
7452
7453       subsItem = & subsItemIe->value.choice.RICsubscription_withCause_Item;
7454       subsItem->ricRequestID.ricRequestorID = subsInfo->requestId.requestorId;
7455       subsItem->ricRequestID.ricInstanceID = subsInfo->requestId.instanceId;
7456       subsItem->ranFunctionID = subsInfo->ranFuncId;
7457       fillE2Cause(&subsItem->cause, subsInfo->failureCause);
7458
7459       ieIdx++;
7460       subsNode = subsNode->next;
7461    }
7462
7463    return ROK;   
7464 }
7465
7466 /*******************************************************************
7467  *
7468  * @brief Builds and Send RIC Subscription delete required
7469  *
7470  * @details
7471  *
7472  *    Function : BuildAndSendRicSubscriptionDeleteRequired
7473  *
7474  * Functionality: Build and send RIC subscription delete required.
7475  *    There can be 2 approaches to trigger following. One of these
7476  *    approaches may/may not be implemented in future:
7477  *    1. It can be triggerred immediately when a RIC subscription's
7478  *       End Time has expired. In this case, only this subscription's
7479  *       info will be sent in this message.
7480  *       Since we have not yet added support to execute RIC 
7481  *       Subscription based on Start Time and End Timer, this message is 
7482  *       not triggered anywhere from DU APP yet.
7483  *    2. Another approach is to have a periodic timer to check subscription
7484  *       status running in background.
7485  *       When RIC Subscription End Time expires, this subscription is
7486  *       marked to be deleted. Later when this background timer expires,
7487  *       a RIC Subscription delete required is sent with all the 
7488  *       subscription's info which is marked to be deleted.
7489  *    The following function is implemented keeping in mind the second 
7490  *    approach.
7491  *
7492  * @params[in] 
7493  * @return ROK     - success
7494  *         RFAILED - failure
7495  *
7496  ******************************************************************/
7497 uint8_t BuildAndSendRicSubscriptionDeleteRequired()
7498 {
7499    uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED;
7500    E2AP_PDU_t         *e2apMsg = NULLP;
7501    RICsubscriptionDeleteRequired_t *ricSubsDelRqd = NULLP;
7502    RICsubscriptionDeleteRequired_IEs_t *ricSubsDelRqdIe = NULLP;
7503    asn_enc_rval_t     encRetVal;        /* Encoder return value */
7504    CmLListCp ricSubsToBeDelList;
7505
7506    while(true)
7507    {
7508       /* Check if there are any RIC subscriptions to be deleted */
7509       cmLListInit(&ricSubsToBeDelList);
7510       fetchRicSubsToBeDeleted(&ricSubsToBeDelList);
7511       if(ricSubsToBeDelList.count == 0)
7512       {
7513          DU_LOG("\nDEBUG  -->  E2AP : %s: No RIC subscriptions are required to be deleted", __func__);
7514          return ROK;
7515       }
7516
7517       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Delete Required Message\n");
7518
7519       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
7520       if(e2apMsg == NULLP)
7521       {
7522          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7523          break;
7524       }
7525
7526       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
7527       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
7528       if(e2apMsg->choice.initiatingMessage == NULLP)
7529       {
7530          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7531          break;
7532       }
7533       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionDeleteRequired;
7534       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
7535       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequired;
7536
7537       ricSubsDelRqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired;
7538       
7539       elementCnt = 1;
7540       ricSubsDelRqd->protocolIEs.list.count = elementCnt;
7541       ricSubsDelRqd->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionDeleteRequired_IEs_t *);
7542
7543       DU_ALLOC(ricSubsDelRqd->protocolIEs.list.array, ricSubsDelRqd->protocolIEs.list.size);
7544       if(ricSubsDelRqd->protocolIEs.list.array == NULLP)
7545       {
7546          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__);
7547          break;
7548       }
7549       
7550       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
7551       {
7552          DU_ALLOC(ricSubsDelRqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequired_IEs_t));
7553          if(ricSubsDelRqd->protocolIEs.list.array[ieIdx] == NULLP)
7554          {
7555             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for index [%d] at line %d", \
7556                __func__, ieIdx, __LINE__);
7557             break;
7558          }
7559       }
7560       if(ieIdx < elementCnt)
7561          break;
7562
7563       ieIdx = 0;
7564       ricSubsDelRqdIe = ricSubsDelRqd->protocolIEs.list.array[ieIdx];
7565       ricSubsDelRqdIe->id = ProtocolIE_IDE2_id_RICsubscriptionToBeRemoved;
7566       ricSubsDelRqdIe->criticality = CriticalityE2_ignore;
7567       ricSubsDelRqdIe->value.present = RICsubscriptionDeleteRequired_IEs__value_PR_RICsubscription_List_withCause;
7568       if(fillRicSubsListWithCause(&ricSubsDelRqdIe->value.choice.RICsubscription_List_withCause, ricSubsToBeDelList)\
7569             != ROK)
7570       {
7571          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Subscription list with cause", __func__);
7572          break;
7573       }
7574
7575       /* Prints the Msg formed */
7576       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
7577       memset(encBuf, 0, ENC_BUF_MAX_LEN);
7578       encBufSize = 0;
7579       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
7580       if(encRetVal.encoded == ENCODE_FAIL)
7581       {
7582          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Delete Required Message (at %s)\n",\
7583                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
7584          break;
7585       }
7586       else
7587       {
7588          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Delete Required Message \n");
7589 #ifdef DEBUG_ASN_PRINT
7590          for(int i=0; i< encBufSize; i++)
7591          {
7592             printf("%x",encBuf[i]);
7593          } 
7594 #endif
7595       }
7596
7597       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
7598       {
7599          DU_LOG("\nERROR   -->  E2AP : Failed to send RIC Susbcription Delete Required Message");      
7600
7601       }
7602       ret = ROK;
7603       break;
7604    }
7605
7606    FreeRicSubscriptionDeleteRequired(e2apMsg, &ricSubsToBeDelList);     
7607    return ret;
7608 }
7609
7610 /*******************************************************************
7611  *
7612  * @brief Free RIC Subscription Delete Failure Message
7613  *
7614  * @details
7615  *
7616  *    Function : FreeRicSubscriptionDeleteFailure
7617  *
7618  * Functionality:  Free RIC Subscription Delete Failure
7619  *
7620  * @param  E2AP Message PDU
7621  * @return void
7622  *
7623  ******************************************************************/
7624 void FreeRicSubscriptionDeleteFailure(E2AP_PDU_t *e2apMsg)
7625 {
7626    uint8_t ieIdx = 0;
7627    RICsubscriptionDeleteFailure_t *ricSubsDelFailure = NULLP;
7628
7629    if(e2apMsg)
7630    {
7631       if(e2apMsg->choice.unsuccessfulOutcome)
7632       {
7633          ricSubsDelFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionDeleteFailure;
7634          if(ricSubsDelFailure->protocolIEs.list.array)
7635          {
7636             for(ieIdx = 0; ieIdx < ricSubsDelFailure->protocolIEs.list.count; ieIdx++)
7637             {
7638                DU_FREE(ricSubsDelFailure->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteFailure_IEs_t));
7639             }
7640             DU_FREE(ricSubsDelFailure->protocolIEs.list.array, ricSubsDelFailure->protocolIEs.list.size);
7641          }
7642          DU_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
7643       }
7644       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));;
7645    }
7646 }
7647
7648 /*******************************************************************
7649  *
7650  * @brief Builds and Send RIC Subscription Delete Failure
7651  *
7652  * @details
7653  *
7654  *    Function : BuildAndSendRicSubscriptionDeleteFailure
7655  *
7656  * Functionality: Build and send RIC Subscription Delete Failure.
7657  *
7658  * @params[in] 
7659  *          Ran Func Id
7660  *          Ric Req Id
7661  *          E2 failure cause
7662  * @return ROK     - success
7663  *         RFAILED - failure
7664  *
7665  ******************************************************************/
7666 uint8_t BuildAndSendRicSubscriptionDeleteFailure(uint16_t ranFuncId,  RicRequestId requestId, E2FailureCause failureCause)
7667 {
7668    uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED;
7669    E2AP_PDU_t         *e2apMsg = NULLP;
7670    RICsubscriptionDeleteFailure_t *ricSubsDelFailure = NULLP;
7671    RICsubscriptionDeleteFailure_IEs_t *ricSubsDelFailureIe = NULLP;
7672    asn_enc_rval_t     encRetVal;        /* Encoder return value */
7673
7674    while(true)
7675    {
7676       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Delete Failure Message\n");
7677
7678       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
7679       if(e2apMsg == NULLP)
7680       {
7681          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7682          break;
7683       }
7684
7685       e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome;
7686       DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
7687       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
7688       {
7689          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7690          break;
7691       }
7692       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionDelete;
7693       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
7694       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICsubscriptionDeleteFailure;
7695
7696
7697       ricSubsDelFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionDeleteFailure;
7698
7699       elementCnt = 3;
7700       ricSubsDelFailure->protocolIEs.list.count = elementCnt;
7701       ricSubsDelFailure->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionDeleteFailure_IEs_t *);
7702
7703       DU_ALLOC(ricSubsDelFailure->protocolIEs.list.array, ricSubsDelFailure->protocolIEs.list.size);
7704       if(ricSubsDelFailure->protocolIEs.list.array == NULLP)
7705       {
7706          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__);
7707          break;
7708       }
7709
7710       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
7711       {
7712          DU_ALLOC(ricSubsDelFailure->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteFailure_IEs_t));
7713          if(ricSubsDelFailure->protocolIEs.list.array[ieIdx] == NULLP)
7714          {
7715             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for index [%d] at line %d", \
7716                   __func__, ieIdx, __LINE__);
7717             break;
7718          }
7719       }
7720       if(ieIdx < elementCnt)
7721          break;
7722
7723       ieIdx = 0;
7724       ricSubsDelFailureIe = ricSubsDelFailure->protocolIEs.list.array[ieIdx];
7725       ricSubsDelFailureIe->id = ProtocolIE_IDE2_id_RICrequestID;
7726       ricSubsDelFailureIe->criticality = CriticalityE2_reject;
7727       ricSubsDelFailureIe->value.present = RICsubscriptionDeleteFailure_IEs__value_PR_RICrequestID;
7728       ricSubsDelFailureIe->value.choice.RICrequestID.ricRequestorID= requestId.requestorId;
7729       ricSubsDelFailureIe->value.choice.RICrequestID.ricInstanceID = requestId.instanceId;
7730
7731       ieIdx++;
7732       ricSubsDelFailureIe = ricSubsDelFailure->protocolIEs.list.array[ieIdx];
7733       ricSubsDelFailureIe->id = ProtocolIE_IDE2_id_RANfunctionID;
7734       ricSubsDelFailureIe->criticality = CriticalityE2_reject;
7735       ricSubsDelFailureIe->value.present = RICsubscriptionDeleteFailure_IEs__value_PR_RANfunctionID;
7736       ricSubsDelFailureIe->value.choice.RANfunctionID = ranFuncId;
7737       
7738       ieIdx++;
7739       ricSubsDelFailureIe = ricSubsDelFailure->protocolIEs.list.array[ieIdx];
7740       ricSubsDelFailureIe->id = ProtocolIE_IDE2_id_CauseE2;
7741       ricSubsDelFailureIe->criticality = CriticalityE2_ignore;
7742       ricSubsDelFailureIe->value.present = RICsubscriptionDeleteFailure_IEs__value_PR_CauseE2;
7743       fillE2Cause(&ricSubsDelFailureIe->value.choice.CauseE2, failureCause);
7744
7745       /* Prints the Msg formed */
7746       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
7747       memset(encBuf, 0, ENC_BUF_MAX_LEN);
7748       encBufSize = 0;
7749       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
7750       if(encRetVal.encoded == ENCODE_FAIL)
7751       {
7752          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Delete Failure Message (at %s)\n",\
7753                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
7754          break;
7755       }
7756       else
7757       {
7758          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Delete Failure Message \n");
7759 #ifdef DEBUG_ASN_PRINT
7760          for(int i=0; i< encBufSize; i++)
7761          {
7762             printf("%x",encBuf[i]);
7763          }
7764 #endif
7765       }
7766
7767       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
7768       {
7769          DU_LOG("\nERROR   -->  E2AP : Failed to send RIC Susbcription Delete Failure Message");
7770          break;
7771       }
7772
7773       ret = ROK;
7774       break;
7775    }
7776
7777    FreeRicSubscriptionDeleteFailure(e2apMsg);
7778    return ret;
7779 }
7780
7781
7782 /*******************************************************************
7783  *
7784  * @brief Free RIC Subscription Delete Response Message
7785  *
7786  * @details
7787  *
7788  *    Function : FreeRicSubscriptionDeleteResponse
7789  *
7790  * Functionality:  Free RIC Subscription Delete Response
7791  *
7792  * @param  E2AP Message PDU
7793  * @return void
7794  *
7795  ******************************************************************/
7796 void FreeRicSubscriptionDeleteResponse(E2AP_PDU_t *e2apMsg)
7797 {
7798    uint8_t ieIdx = 0;
7799    RICsubscriptionDeleteResponse_t *ricSubsDelRsp = NULLP;
7800
7801    if(e2apMsg)
7802    {
7803       if(e2apMsg->choice.successfulOutcome)
7804       {
7805          ricSubsDelRsp = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionDeleteResponse;
7806          if(ricSubsDelRsp->protocolIEs.list.array)
7807          {
7808             for(ieIdx = 0; ieIdx < ricSubsDelRsp->protocolIEs.list.count; ieIdx++)
7809             {
7810                DU_FREE(ricSubsDelRsp->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteResponse_IEs_t));
7811             }
7812             DU_FREE(ricSubsDelRsp->protocolIEs.list.array, ricSubsDelRsp->protocolIEs.list.size);
7813          }
7814          DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
7815       }
7816       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));;
7817    }
7818 }
7819
7820 /*******************************************************************
7821  *
7822  * @brief Builds and Send RIC Subscription delete Response
7823  *
7824  * @details
7825  *
7826  *    Function : BuildAndSendRicSubscriptionDeleteResponse
7827  *
7828  * Functionality: Build and send RIC subscription delete Response.
7829  *
7830  * @params[in]
7831  *          Ran Func Id
7832  *          Ric Req Id
7833  * @return ROK     - success
7834  *         RFAILED - failure
7835  *
7836  ******************************************************************/
7837 uint8_t BuildAndSendRicSubscriptionDeleteResponse(uint16_t ranFuncId,  RicRequestId requestId)
7838 {
7839    uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED;
7840    E2AP_PDU_t         *e2apMsg = NULLP;
7841    RICsubscriptionDeleteResponse_t *ricSubsDelRsp = NULLP;
7842    RICsubscriptionDeleteResponse_IEs_t *ricSubsDelRspIe = NULLP;
7843    asn_enc_rval_t     encRetVal;        /* Encoder return value */
7844
7845    while(true)
7846    {
7847       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Delete Response Message\n");
7848
7849       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
7850       if(e2apMsg == NULLP)
7851       {
7852          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7853          break;
7854       }
7855
7856       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
7857       DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
7858       if(e2apMsg->choice.successfulOutcome == NULLP)
7859       {
7860          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7861          break;
7862       }
7863       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionDelete;
7864       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
7865       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICsubscriptionDeleteResponse;
7866
7867
7868       ricSubsDelRsp = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionDeleteResponse;
7869
7870       elementCnt = 2;
7871       ricSubsDelRsp->protocolIEs.list.count = elementCnt;
7872       ricSubsDelRsp->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionDeleteResponse_IEs_t *);
7873
7874       DU_ALLOC(ricSubsDelRsp->protocolIEs.list.array, ricSubsDelRsp->protocolIEs.list.size);
7875       if(ricSubsDelRsp->protocolIEs.list.array == NULLP)
7876       {
7877          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__);
7878          break;
7879       }
7880
7881       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
7882       {
7883          DU_ALLOC(ricSubsDelRsp->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteResponse_IEs_t));
7884          if(ricSubsDelRsp->protocolIEs.list.array[ieIdx] == NULLP)
7885          {
7886             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for index [%d] at line %d", \
7887                   __func__, ieIdx, __LINE__);
7888             break;
7889          }
7890       }
7891       if(ieIdx < elementCnt)
7892          break;
7893
7894       ieIdx = 0;
7895       ricSubsDelRspIe = ricSubsDelRsp->protocolIEs.list.array[ieIdx];
7896       ricSubsDelRspIe->id = ProtocolIE_IDE2_id_RICrequestID;
7897       ricSubsDelRspIe->criticality = CriticalityE2_reject;
7898       ricSubsDelRspIe->value.present = RICsubscriptionDeleteResponse_IEs__value_PR_RICrequestID;
7899       ricSubsDelRspIe->value.choice.RICrequestID.ricRequestorID= requestId.requestorId;
7900       ricSubsDelRspIe->value.choice.RICrequestID.ricInstanceID = requestId.instanceId;
7901
7902       ieIdx++;
7903       ricSubsDelRspIe = ricSubsDelRsp->protocolIEs.list.array[ieIdx];
7904       ricSubsDelRspIe->id = ProtocolIE_IDE2_id_RANfunctionID;
7905       ricSubsDelRspIe->criticality = CriticalityE2_reject;
7906       ricSubsDelRspIe->value.present = RICsubscriptionDeleteResponse_IEs__value_PR_RANfunctionID;
7907       ricSubsDelRspIe->value.choice.RANfunctionID = ranFuncId;
7908
7909       /* Prints the Msg formed */
7910       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
7911       memset(encBuf, 0, ENC_BUF_MAX_LEN);
7912       encBufSize = 0;
7913       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
7914       if(encRetVal.encoded == ENCODE_FAIL)
7915       {
7916          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Delete Response Message (at %s)\n",\
7917                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
7918          break;
7919       }
7920       else
7921       {
7922          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Delete Response Message \n");
7923 #ifdef DEBUG_ASN_PRINT
7924          for(int i=0; i< encBufSize; i++)
7925          {
7926             printf("%x",encBuf[i]);
7927          }
7928 #endif
7929       }
7930
7931       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
7932       {
7933          DU_LOG("\nERROR   -->  E2AP : Failed to send RIC Susbcription Delete Response Message");
7934          break;
7935       }
7936
7937       ret = ROK;
7938       break;
7939    }
7940
7941    FreeRicSubscriptionDeleteResponse(e2apMsg);
7942    return ret;
7943 }
7944
7945 /*******************************************************************
7946  *
7947  * @brief Free RIC Subscription Delete Request Message
7948  *
7949  * @details
7950  *
7951  *    Function : freeAperDecodingOfRicSubsDeleteReq
7952  *
7953  * Functionality:  Free RIC Subscription Delete Request
7954  *
7955  * @param  E2AP Message PDU
7956  * @return void
7957  *
7958  ******************************************************************/
7959 void freeAperDecodingOfRicSubsDeleteReq(E2AP_PDU_t *e2apMsg)
7960 {
7961    uint8_t ieIdx = 0;
7962    RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
7963
7964    if(e2apMsg)
7965    {
7966       if(e2apMsg->choice.initiatingMessage)
7967       {
7968          ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
7969          if(ricSubsDelReq->protocolIEs.list.array)
7970          {
7971             for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++)
7972             {
7973                if(ricSubsDelReq->protocolIEs.list.array[ieIdx])
7974                {
7975                   free(ricSubsDelReq->protocolIEs.list.array[ieIdx]);
7976                }
7977             }
7978             free(ricSubsDelReq->protocolIEs.list.array);
7979          }
7980       }
7981    }
7982 }
7983
7984 /*******************************************************************
7985  *
7986  * @brief Process RIC Subscription delete request
7987  *
7988  * @details
7989  *
7990  *    Function : procRicSubscriptionDeleteRequest
7991  *
7992  * Functionality: Process RIC subscription delete request.
7993  *    Fetch RAN Function and RIC subscription to be deleted. 
7994  *    Send statistics delete request to MAC for all action sequence
7995  *    within this RIC subscription.
7996  *
7997  * @params[in] E2AP PDU
7998  * @return void
7999  *
8000  ******************************************************************/
8001 void procRicSubscriptionDeleteRequest(E2AP_PDU_t *e2apMsg)
8002 {
8003    uint8_t ieIdx = 0;
8004    uint16_t ranFuncId = 0;
8005    bool procFailure = false;
8006    RicRequestId ricReqId;
8007    RanFunction *ranFuncDb = NULLP;
8008    CmLList *ricSubsNode = NULLP;
8009    RicSubscription *ricSubsDb = NULLP;
8010    RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
8011    RICsubscriptionDeleteRequest_IEs_t *ricSubsDelReqIe = NULLP;
8012
8013    DU_LOG("\nINFO   -->  E2AP : %s: Received RIC Subscription Delete Request", __func__);
8014
8015    do{
8016       if(!e2apMsg)
8017       {
8018          DU_LOG("\nERROR  -->  E2AP : %s: E2AP Message is NULL", __func__);
8019          break;
8020       }
8021
8022       if(!e2apMsg->choice.initiatingMessage)
8023       {
8024          DU_LOG("\nERROR  -->  E2AP : %s: Initiating Message in E2AP PDU is NULL", __func__);
8025          break;
8026       }
8027
8028       ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
8029       if(!ricSubsDelReq->protocolIEs.list.array)
8030       {
8031          DU_LOG("\nERROR  -->  E2AP : %s: Array conatining E2AP message IEs is null", __func__);
8032          break;
8033       }
8034
8035       for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++)
8036       {
8037          if(!ricSubsDelReq->protocolIEs.list.array[ieIdx])
8038          {
8039             DU_LOG("\nERROR  -->  E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx);
8040             break;
8041          }
8042
8043          ricSubsDelReqIe = ricSubsDelReq->protocolIEs.list.array[ieIdx];
8044          switch(ricSubsDelReqIe->id)
8045          {
8046             case ProtocolIE_IDE2_id_RICrequestID:
8047                {
8048                   memset(&ricReqId, 0, sizeof(RicRequestId));
8049                   ricReqId.requestorId = ricSubsDelReqIe->value.choice.RICrequestID.ricRequestorID;
8050                   ricReqId.instanceId = ricSubsDelReqIe->value.choice.RICrequestID.ricInstanceID;
8051                   break;
8052                }
8053
8054             case ProtocolIE_IDE2_id_RANfunctionID:
8055                {
8056                   ranFuncId = ricSubsDelReqIe->value.choice.RANfunctionID;
8057                   ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
8058                   if(!ranFuncDb)
8059                   {
8060                      DU_LOG("\nERROR  -->  E2AP : %s: RAN Function ID [%d] not found", __func__, ranFuncId);
8061                      procFailure = true;
8062                      break;
8063                   }
8064
8065                   ricSubsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode); 
8066                   if(!ricSubsDb)
8067                   {
8068                      DU_LOG("\nERROR  -->  E2AP : %s: RIC Subscription not found for Requestor_ID [%d] Instance_ID [%d]",\
8069                            __func__, ricReqId.requestorId, ricReqId.instanceId);
8070                      procFailure = true;
8071                      break;
8072                   }
8073
8074                   if(BuildAndSendStatsDeleteReq(ricSubsDb, true) != ROK)
8075                   {
8076                      DU_LOG("\nERROR  -->  E2AP : Failed to build and send ric subscription delete req to du layers");
8077                   }
8078                   break;
8079                }
8080
8081             default:
8082                break;
8083          } /* End of switch for Protocol IE Id */
8084          
8085          if(procFailure)
8086             break;
8087       } /* End of for loop for Protocol IE list */
8088
8089       break;
8090    }while(true);
8091
8092    freeAperDecodingOfRicSubsDeleteReq(e2apMsg);
8093    return;
8094 }
8095
8096 /*******************************************************************
8097  *
8098  * @brief Deallocate the memory allocated for E2 node configuration
8099  * update ack msg by aper decoder
8100  *
8101  * @details
8102  *
8103  *    Function : freeAperDecodingOfE2NodeConfigUpdateAck 
8104  *
8105  *    Functionality:
8106  *       - Deallocate the memory allocated for E2 node configuration
8107  * update ack msg by aper decoder
8108  *
8109  * @params[in] E2AP_PDU_t *e2apMsg
8110  * @return ROK     - success
8111  *         RFAILED - failure
8112  *
8113  * ****************************************************************/
8114
8115 void freeAperDecodingOfE2NodeConfigUpdateAck(E2nodeConfigurationUpdateAcknowledge_t *updateAckMsg)
8116 {
8117    uint8_t arrIdx =0, e2NodeConfigIdx=0;
8118    E2nodeComponentConfigUpdateAck_ItemIEs_t *updateAckItemIe=NULL;
8119    E2nodeComponentConfigUpdateAck_List_t *updateAckList=NULL;
8120    E2nodeComponentConfigRemovalAck_ItemIEs_t *removalAckItemIe=NULL;
8121    E2nodeComponentConfigRemovalAck_List_t *removalAckList=NULL;
8122    E2nodeComponentConfigAdditionAck_ItemIEs_t *additionAckItemIte=NULL;
8123    E2nodeComponentConfigAdditionAck_List_t *additionAckList=NULL;
8124
8125    E2nodeComponentInterfaceF1_t *f1InterfaceInfo=NULLP;
8126    if(updateAckMsg->protocolIEs.list.array != NULLP)
8127    {
8128       for(arrIdx = 0; arrIdx < updateAckMsg->protocolIEs.list.count; arrIdx++)
8129       {
8130          if(updateAckMsg->protocolIEs.list.array[arrIdx])
8131          {
8132             switch(updateAckMsg->protocolIEs.list.array[arrIdx]->id)
8133             {
8134                case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
8135                   {
8136                      additionAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
8137                      if(additionAckList->list.array)
8138                      {
8139                         for(e2NodeConfigIdx=0; e2NodeConfigIdx<additionAckList->list.count; e2NodeConfigIdx++)
8140                         {
8141                            additionAckItemIte = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) additionAckList->list.array[e2NodeConfigIdx];
8142                            if(additionAckItemIte)
8143                            {
8144                               switch(additionAckItemIte->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present)
8145                               {
8146                                  case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
8147                                     {
8148                                        f1InterfaceInfo = additionAckItemIte->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
8149                                        free(f1InterfaceInfo->gNB_DU_ID.buf);
8150                                        free(f1InterfaceInfo);
8151                                        break;
8152                                     }
8153                                  default:
8154                                     break;
8155                               }
8156                               free(additionAckItemIte);
8157                            }
8158                            free(additionAckList->list.array);
8159                         }
8160                         break;
8161                      }
8162                   }
8163                case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
8164                   {
8165                      updateAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List;
8166                      if(updateAckList->list.array)
8167                      {
8168                         for(e2NodeConfigIdx=0; e2NodeConfigIdx<updateAckList->list.count; e2NodeConfigIdx++)
8169                         {
8170                            updateAckItemIe = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) updateAckList->list.array[e2NodeConfigIdx];
8171                            if(updateAckItemIe)
8172                            {
8173                               switch(updateAckItemIe->value.choice.E2nodeComponentConfigUpdateAck_Item.e2nodeComponentID.present)
8174                               {
8175                                  case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
8176                                     {
8177                                        f1InterfaceInfo = updateAckItemIe->value.choice.E2nodeComponentConfigUpdateAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
8178                                        free(f1InterfaceInfo->gNB_DU_ID.buf);
8179                                        free(f1InterfaceInfo);
8180                                        break;
8181                                     }
8182                                  default:
8183                                     break;
8184                               }
8185                               free(updateAckItemIe);
8186                            }
8187                         }
8188                         free(updateAckList->list.array);
8189                      }
8190                      break;
8191                   }
8192                case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
8193                   {
8194                      removalAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List;
8195                      if(removalAckList->list.array)
8196                      {
8197                         for(e2NodeConfigIdx=0; e2NodeConfigIdx<removalAckList->list.count; e2NodeConfigIdx++)
8198                         {
8199                            removalAckItemIe = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) removalAckList->list.array[e2NodeConfigIdx];
8200                            if(removalAckItemIe)
8201                            {
8202                               switch(removalAckItemIe->value.choice.E2nodeComponentConfigRemovalAck_Item.e2nodeComponentID.present)
8203                               {
8204                                  case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
8205                                     {
8206                                        f1InterfaceInfo = removalAckItemIe->value.choice.E2nodeComponentConfigRemovalAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
8207                                        free(f1InterfaceInfo->gNB_DU_ID.buf);
8208                                        free(f1InterfaceInfo);
8209                                        break;
8210                                     }
8211                                  default:
8212                                     break;
8213                               }
8214                               free(removalAckItemIe);
8215                            }
8216                         }
8217                         free(removalAckList->list.array);
8218                      }
8219                      break;
8220                   }
8221             }
8222             free(updateAckMsg->protocolIEs.list.array[arrIdx]);
8223          }
8224       }
8225       free(updateAckMsg->protocolIEs.list.array);
8226    }
8227 }
8228
8229 /******************************************************************
8230  *
8231  * @brief Processes the E2 node config update ack msg
8232  *
8233  * @details
8234  *
8235  *    Function :procE2NodeConfigUpdateAck 
8236  *
8237  *    Functionality: Processes the E2 node config update ack msg
8238  *
8239  * @params[in] E2AP_PDU_t ASN decoded E2AP message
8240  * @return ROK     - success
8241  *         RFAILED - failure
8242  *
8243  * ****************************************************************/
8244
8245 void procE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg)
8246 {
8247    uint8_t arrIdx =0;
8248    uint16_t e2CfgIdx =0;
8249    E2nodeConfigurationUpdateAcknowledge_t *e2NodeConfigUpdateAck =NULLP;
8250    E2nodeComponentConfigUpdateAck_List_t *e2NodeConfigUpdateAckList=NULLP;
8251    E2nodeComponentConfigUpdateAck_ItemIEs_t *e2NodeUpdateAckItem=NULLP;
8252    E2nodeComponentConfigRemovalAck_List_t *e2NodeConfigRemovalAckList=NULLP;
8253    E2nodeComponentConfigRemovalAck_ItemIEs_t *e2NodeRemovalAckItem=NULLP;
8254    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList=NULLP;
8255    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAdditionAckItem=NULLP;
8256
8257    e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
8258
8259    if(e2NodeConfigUpdateAck->protocolIEs.list.array)
8260    {
8261        for(arrIdx =0; arrIdx<e2NodeConfigUpdateAck->protocolIEs.list.count; arrIdx++)
8262        {
8263             switch(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id)
8264             {
8265                case ProtocolIE_IDE2_id_TransactionID:
8266                {
8267                   break;
8268                }
8269                case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
8270                {
8271                   e2NodeConfigAdditionAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
8272                   if(e2NodeConfigAdditionAckList->list.array)
8273                   {
8274                      for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigAdditionAckList->list.count; e2CfgIdx++) 
8275                      {
8276                         e2NodeAdditionAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[e2CfgIdx];    
8277                         handleE2NodeConfigUpdateAckIes((PTR)&e2NodeAdditionAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item,\
8278                         ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck);
8279                      }
8280                   }
8281                   break;
8282                }
8283                case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
8284                {
8285                   e2NodeConfigUpdateAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List;
8286                   if(e2NodeConfigUpdateAckList->list.array)
8287                   {
8288                      for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigUpdateAckList->list.count; e2CfgIdx++) 
8289                      {
8290                         e2NodeUpdateAckItem = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) e2NodeConfigUpdateAckList->list.array[e2CfgIdx];    
8291                         handleE2NodeConfigUpdateAckIes((PTR)&e2NodeUpdateAckItem->value.choice.E2nodeComponentConfigUpdateAck_Item,\
8292                         ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck);
8293                      }
8294                   }
8295                   break;
8296                }
8297                case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
8298                {
8299                   e2NodeConfigRemovalAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List;
8300                   if(e2NodeConfigRemovalAckList->list.array)
8301                   {
8302                      for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigRemovalAckList->list.count; e2CfgIdx++) 
8303                      {
8304                         e2NodeRemovalAckItem = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) e2NodeConfigRemovalAckList->list.array[e2CfgIdx];    
8305                         handleE2NodeConfigUpdateAckIes((PTR)&e2NodeRemovalAckItem->value.choice.E2nodeComponentConfigRemovalAck_Item,\
8306                         ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck);
8307                      }
8308                   }
8309                   break;
8310                }
8311             }
8312        }
8313    }
8314
8315    freeAperDecodingOfE2NodeConfigUpdateAck(e2NodeConfigUpdateAck);
8316 }
8317
8318 /*******************************************************************
8319  *
8320  * @brief Deallocate the memory allocated for RemovalRequest msg
8321  *
8322  * @details
8323  *
8324  *    Function : FreeRemovalRequest
8325  *
8326  *    Functionality:
8327  *       - freeing the memory allocated for RemovalRequest
8328  *
8329  * @params[in] E2AP_PDU_t *e2apMsg
8330  * @return ROK     - success
8331  *         RFAILED - failure
8332  *
8333  * ****************************************************************/
8334 void FreeRemovalRequest(E2AP_PDU_t *e2apMsg)
8335 {
8336    uint8_t ieIdx =0;
8337    E2RemovalRequest_t  *removalReq = NULLP;
8338
8339    if(e2apMsg != NULLP)
8340    {
8341       if(e2apMsg->choice.initiatingMessage != NULLP)
8342       {
8343          removalReq = &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest;
8344          if(removalReq->protocolIEs.list.array)
8345          {
8346             for(ieIdx = 0; ieIdx < removalReq->protocolIEs.list.count; ieIdx++)
8347             {
8348                DU_FREE(removalReq->protocolIEs.list.array[ieIdx], sizeof(E2RemovalRequestIEs_t));
8349             }
8350             DU_FREE(removalReq->protocolIEs.list.array, removalReq->protocolIEs.list.size);
8351          }
8352          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
8353       }
8354       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
8355    }
8356 }
8357
8358 /*******************************************************************
8359  *
8360  * @brief Build and send the removal request msg
8361  *
8362  * @details
8363  *
8364  *    Function : BuildAndSendRemovalRequest
8365  *
8366  *    Functionality:
8367  *         - Buld and send the removal request msg to E2 node
8368  *
8369  * @return ROK     - success
8370  *         RFAILED - failure
8371  *
8372  * ****************************************************************/
8373
8374 uint8_t BuildAndSendRemovalRequest()
8375 {
8376    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
8377    uint8_t ret = RFAILED;
8378    E2AP_PDU_t        *e2apMsg = NULLP;
8379    E2RemovalRequest_t  *removalReq = NULLP;
8380    asn_enc_rval_t     encRetVal;       /* Encoder return value */
8381
8382    DU_LOG("\nINFO   -->  E2AP : Building Removal Request\n");
8383
8384    do
8385    {
8386       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
8387       if(e2apMsg == NULLP)
8388       {
8389          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8390          break;
8391       }
8392
8393       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
8394       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
8395       if(e2apMsg->choice.initiatingMessage == NULLP)
8396       {
8397          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8398          break;
8399       }
8400
8401       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2removal;
8402       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
8403       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2RemovalRequest;
8404       removalReq = &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest;
8405
8406       elementCnt = 1;
8407       removalReq->protocolIEs.list.count = elementCnt;
8408       removalReq->protocolIEs.list.size = elementCnt * sizeof(E2RemovalRequestIEs_t *);
8409
8410       DU_ALLOC(removalReq->protocolIEs.list.array, removalReq->protocolIEs.list.size);
8411       if(!removalReq->protocolIEs.list.array)
8412       {
8413          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8414          break;
8415       }
8416
8417       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
8418       {
8419          DU_ALLOC(removalReq->protocolIEs.list.array[ieIdx], sizeof(E2RemovalRequestIEs_t));
8420          if(!removalReq->protocolIEs.list.array[ieIdx])
8421          {
8422             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8423             break;
8424          }
8425       }
8426
8427       /* In case of failure */
8428       if(ieIdx < elementCnt)
8429          break;
8430
8431       ieIdx = 0;
8432       removalReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
8433       removalReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
8434       removalReq->protocolIEs.list.array[ieIdx]->value.present = E2RemovalRequestIEs__value_PR_TransactionID;
8435       transId = assignTransactionId();
8436       removalReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
8437
8438       /* Prints the Msg formed */
8439       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
8440
8441       memset(encBuf, 0, ENC_BUF_MAX_LEN);
8442       encBufSize = 0;
8443       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
8444             encBuf);
8445       if(encRetVal.encoded == ENCODE_FAIL)
8446       {
8447          DU_LOG("\nERROR  -->  E2AP : Could not encode removal request structure (at %s)\n",\
8448                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
8449          break;
8450       }
8451       else
8452       {
8453          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for removal request\n");
8454 #ifdef DEBUG_ASN_PRINT
8455          for(int i=0; i< encBufSize; i++)
8456          {
8457             printf("%x",encBuf[i]);
8458          }
8459 #endif
8460       }
8461       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
8462       {
8463          DU_LOG("\nERROR  -->  E2AP : Sending removal request failed");
8464          break;
8465       }
8466
8467
8468       ret = ROK;
8469       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
8470       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
8471       break;
8472    }while(true);
8473
8474    /* Free all memory */
8475    FreeRemovalRequest(e2apMsg);
8476    
8477    return ret;
8478 }
8479
8480 /******************************************************************
8481  *
8482  * @brief Deallocation of memory allocated by aper decoder
8483  *   for Removal failure
8484  *
8485  * @details
8486  *
8487  *    Function : freeAperDecodingOfE2RemovalFailure
8488  *
8489  *    Functionality: Deallocation of memory allocated by aper decoder
8490  * for Removal failure
8491  *
8492  * @params[in] Pointer to removalFailure
8493  * @return void
8494  *
8495  * ****************************************************************/
8496 void freeAperDecodingOfE2RemovalFailure(E2RemovalFailure_t *removalFailure)
8497 {
8498    uint8_t arrIdx=0;
8499
8500    if(removalFailure)
8501    {
8502       if(removalFailure->protocolIEs.list.array)
8503       {
8504          for(arrIdx=0; arrIdx<removalFailure->protocolIEs.list.count; arrIdx++)
8505          {
8506             if(removalFailure->protocolIEs.list.array[arrIdx])
8507             {
8508                free(removalFailure->protocolIEs.list.array[arrIdx]);
8509             }
8510          }
8511          free(removalFailure->protocolIEs.list.array);
8512       }
8513    }
8514 }
8515
8516 /******************************************************************
8517  *
8518  * @brief Processes the E2 removal failure msg
8519  *
8520  * @details
8521  *
8522  *    Function : procE2RemovalFailure
8523  *
8524  *    Functionality: Processes the E2 removal failure msg
8525  *
8526  * @params[in] 
8527  *       E2AP_PDU_t *e2apMsg
8528  *
8529  * @return void
8530  *
8531  * ****************************************************************/
8532 void ProcE2RemovalFailure(E2AP_PDU_t *e2apMsg) 
8533 {
8534    uint8_t ieIdx = 0, transId=0;
8535    CauseE2_t *cause = NULLP;
8536    E2RemovalFailure_t *e2RemovalFailure=NULLP;
8537
8538    e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure;
8539
8540    if(!e2RemovalFailure->protocolIEs.list.array)      
8541    {
8542       DU_LOG("\nERROR  -->  E2AP : e2RemovalFailure array pointer is null");
8543       return;
8544    }
8545    
8546    for(ieIdx=0; ieIdx < e2RemovalFailure->protocolIEs.list.count; ieIdx++)
8547    {
8548       if(e2RemovalFailure->protocolIEs.list.array[ieIdx])
8549       {
8550          switch(e2RemovalFailure->protocolIEs.list.array[ieIdx]->id)
8551          {
8552             case ProtocolIE_IDE2_id_TransactionID:
8553                {
8554                   transId = e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
8555                   if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
8556                         (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
8557                   {
8558                      memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
8559                   }
8560                   else
8561                   {
8562                      DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
8563                   }
8564                   break;
8565                }
8566             case ProtocolIE_IDE2_id_CauseE2:
8567                {
8568                    cause = &e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2;
8569                    printE2ErrorCause(cause);
8570                    break; 
8571                }
8572             default:
8573                {
8574                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", e2RemovalFailure->protocolIEs.list.array[ieIdx]->id);
8575                   break;
8576                }
8577          }
8578       }
8579    }
8580    freeAperDecodingOfE2RemovalFailure(e2RemovalFailure);
8581 }
8582
8583  /******************************************************************
8584   *
8585   * @brief Deallocation of memory allocated by aper decoder
8586   *   for Removal failure
8587   *
8588   * @details
8589   *
8590   *    Function : freeAperDecodingOfE2RemovalResponse
8591   *
8592   *    Functionality: Deallocation of memory allocated by aper decoder
8593   * for Removal failure
8594   *
8595   * @params[in] Pointer to removalResponse
8596   * @return void
8597   *
8598   * ****************************************************************/
8599  void freeAperDecodingOfE2RemovalResponse(E2RemovalResponse_t *removalResponse)
8600  {
8601     uint8_t arrIdx=0;
8602
8603     if(removalResponse)
8604     {
8605        if(removalResponse->protocolIEs.list.array)
8606        {
8607           for(arrIdx=0; arrIdx<removalResponse->protocolIEs.list.count; arrIdx++)
8608           {
8609              if(removalResponse->protocolIEs.list.array[arrIdx])
8610              {
8611                 free(removalResponse->protocolIEs.list.array[arrIdx]);
8612              }
8613           }
8614           free(removalResponse->protocolIEs.list.array);
8615        }
8616     }
8617  }
8618
8619 /*******************************************************************
8620  *
8621  * @brief process the E2 Removal Response
8622  *
8623  * @details
8624  *
8625  *    Function : ProcE2RemovalResponse 
8626  *
8627  * Functionality: Process E2 Removal Response 
8628  *
8629  * @params[in] 
8630  *      E2AP_PDU_t *e2apMsg
8631  * @return void
8632  *
8633  ******************************************************************/
8634
8635 void ProcE2RemovalResponse(E2AP_PDU_t *e2apMsg)
8636 {
8637    uint8_t ieIdx = 0, transId=0;
8638    E2RemovalResponse_t *removalRsp = NULLP;
8639    
8640    removalRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse;
8641
8642    if(!removalRsp->protocolIEs.list.array)      
8643    {
8644       DU_LOG("\nERROR  -->  E2AP : removalRsp array pointer is null");
8645       return;
8646    }
8647
8648    for(ieIdx=0; ieIdx < removalRsp->protocolIEs.list.count; ieIdx++)
8649    {
8650       if(removalRsp->protocolIEs.list.array[ieIdx])
8651       {
8652          switch(removalRsp->protocolIEs.list.array[ieIdx]->id)
8653          {
8654             case ProtocolIE_IDE2_id_TransactionID:
8655                {
8656                   transId = removalRsp->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
8657                   if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
8658                         (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
8659                   {
8660                      DU_LOG("\nINFO  -->  E2AP : Sending request to close the sctp connection");
8661                      cmInetClose(&ricParams.sockFd);
8662                      memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
8663                      removeE2NodeInformation();
8664                   }
8665                   else
8666                   {
8667                      DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
8668                   }
8669                   break;
8670                }
8671             default:
8672                {
8673                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", removalRsp->protocolIEs.list.array[ieIdx]->id);
8674                   break;
8675                }
8676          }
8677       }
8678    }
8679    
8680    freeAperDecodingOfE2RemovalResponse(removalRsp);
8681 }
8682
8683 /*******************************************************************
8684  *
8685  * @brief Deallocate the memory allocated for E2 Connection Update Failure
8686  *
8687  * @details
8688  *
8689  *    Function : FreeE2ConnectionUpdateFailure
8690  *
8691  *    Functionality:
8692  *       - freeing the memory allocated for E2ConnectionUpdateFailure
8693  *
8694  * @params[in] E2AP_PDU_t *e2apMsg
8695  * @return ROK     - success
8696  *         RFAILED - failure
8697  *
8698  * ****************************************************************/
8699 void FreeE2ConnectionUpdateFailure(E2AP_PDU_t *e2apMsg)
8700 {
8701    uint8_t ieIdx =0;
8702    E2connectionUpdateFailure_t *e2ConnectionUpdateFailure=NULLP;
8703
8704    if(e2apMsg != NULLP)
8705    {
8706       if(e2apMsg->choice.unsuccessfulOutcome != NULLP)
8707       {
8708          e2ConnectionUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2connectionUpdateFailure;
8709          if(e2ConnectionUpdateFailure->protocolIEs.list.array)
8710          {
8711             for(ieIdx=0; ieIdx < e2ConnectionUpdateFailure->protocolIEs.list.count; ieIdx++)
8712             {
8713                DU_FREE(e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdateFailure_IEs_t));
8714             }
8715             DU_FREE(e2ConnectionUpdateFailure->protocolIEs.list.array, e2ConnectionUpdateFailure->protocolIEs.list.size);
8716          }
8717          DU_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
8718       }
8719       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
8720    }
8721 }
8722
8723 /*******************************************************************
8724  *
8725  * @brief Buld and send the E2 Connection Update Failure msg
8726  *
8727  * @details
8728  *
8729  *    Function : BuildAndSendE2ConnectionUpdateFailure
8730  *
8731  *    Functionality:
8732  *         - Buld and send the E2 Connection Update Failure Message
8733  * @params[in] 
8734  *    Trans Id 
8735  *    Failure Cause
8736  * @return ROK     - success
8737  *         RFAILED - failure
8738  *
8739  * ****************************************************************/
8740
8741 uint8_t BuildAndSendE2ConnectionUpdateFailure(uint16_t transId, E2FailureCause failureCause)
8742 {
8743    uint8_t           ieIdx = 0, elementCnt = 0;
8744    uint8_t           ret = RFAILED;
8745    E2AP_PDU_t        *e2apMsg = NULLP;
8746    E2connectionUpdateFailure_t *e2ConnectionUpdateFailure=NULLP;
8747    asn_enc_rval_t    encRetVal;       /* Encoder return value */
8748
8749    DU_LOG("\nINFO   -->  E2AP : Building E2 Connection Update Failure Message\n");
8750    do
8751    {
8752       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
8753       if(e2apMsg == NULLP)
8754       {
8755          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8756          break;
8757       }
8758       e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome;
8759
8760       DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
8761       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
8762       {
8763          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8764          break;
8765       }
8766
8767       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2connectionUpdate;
8768       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
8769       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2connectionUpdateFailure;
8770       e2ConnectionUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2connectionUpdateFailure;
8771
8772       elementCnt = 2;
8773       e2ConnectionUpdateFailure->protocolIEs.list.count = elementCnt;
8774       e2ConnectionUpdateFailure->protocolIEs.list.size = elementCnt * sizeof(E2connectionUpdateFailure_IEs_t *);
8775       DU_ALLOC(e2ConnectionUpdateFailure->protocolIEs.list.array, e2ConnectionUpdateFailure->protocolIEs.list.size);
8776       if(!e2ConnectionUpdateFailure->protocolIEs.list.array)
8777       {
8778          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8779          break;
8780       }
8781
8782       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
8783       {
8784          DU_ALLOC(e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdateFailure_IEs_t));
8785          if(!e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx])
8786          {
8787             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8788             break;
8789          }
8790       }
8791       if(ieIdx < elementCnt)
8792          break;
8793
8794       ieIdx = 0;
8795       e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
8796       e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
8797       e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateFailure_IEs__value_PR_TransactionID;
8798       e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
8799
8800       /* Cause */
8801       ieIdx++;
8802       e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
8803       e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
8804       e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateFailure_IEs__value_PR_CauseE2;
8805       fillE2Cause(&e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, failureCause);
8806       
8807       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
8808
8809       memset(encBuf, 0, ENC_BUF_MAX_LEN);
8810       encBufSize = 0;
8811       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
8812       if(encRetVal.encoded == ENCODE_FAIL)
8813       {
8814          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 connection update failure structure (at %s)\n",\
8815                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
8816          break;
8817       }
8818       else
8819       {
8820          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Connection Update Failure \n");
8821          for(int i=0; i< encBufSize; i++)
8822          {
8823             DU_LOG("%x",encBuf[i]);
8824          }
8825       }
8826
8827       /* Sending msg */
8828       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
8829       {
8830          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Connection Update Failure");
8831          break;
8832       }
8833
8834       ret = ROK;
8835       break;
8836    }while(true);
8837
8838    FreeE2ConnectionUpdateFailure(e2apMsg);
8839    return ret;
8840 }
8841
8842 /*******************************************************************
8843  *
8844  * @brief fill E2 connection update item
8845  *
8846  * @details
8847  *
8848  *    Function : fillE2connectionUpdateItem
8849  *
8850  *    Functionality: fill E2 connection update item
8851  *
8852  * @params[in]
8853  *    E2connectionUpdate Item to be filled
8854  *    Protocol Id
8855  *    IP Address
8856  *    Usage
8857  * @return ROK - success
8858  *         RFAILED - failure
8859  * ****************************************************************/
8860
8861 uint8_t fillE2connectionUpdateItem(PTR connectionInfo, uint8_t protocolId, uint32_t ipAddress, AssocUsage usage)
8862 {
8863    CauseE2_t *cause=NULLP;
8864    TNLusage_t  *tnlUsage=NULLP;
8865    E2FailureCause failureCause;
8866    TNLinformation_t *tnlInformation = NULLP;
8867    E2connectionUpdate_Item_t *connectionModifyItem=NULLP;
8868    E2connectionSetupFailed_Item_t *connectionRemoveITem=NULLP;
8869
8870    switch(protocolId)
8871    {
8872       case ProtocolIE_IDE2_id_E2connectionUpdate_Item:
8873       {
8874          connectionModifyItem = (E2connectionUpdate_Item_t*)connectionInfo;
8875          tnlInformation = &connectionModifyItem->tnlInformation;
8876          tnlUsage = &connectionModifyItem->tnlUsage;
8877          break;
8878       }
8879
8880       case ProtocolIE_IDE2_id_E2connectionSetupFailed_Item:
8881       {
8882          connectionRemoveITem = (E2connectionSetupFailed_Item_t*)connectionInfo;
8883          tnlInformation= &connectionRemoveITem->tnlInformation;
8884          cause = &connectionRemoveITem->cause;
8885          break;
8886       }
8887       default:
8888          return RFAILED;
8889    }
8890
8891    tnlInformation->tnlAddress.size =  4*sizeof(uint8_t);
8892    DU_ALLOC(tnlInformation->tnlAddress.buf, tnlInformation->tnlAddress.size);
8893    if(!tnlInformation->tnlAddress.buf)
8894    {
8895       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8896       return RFAILED;
8897    }
8898
8899    tnlInformation->tnlAddress.buf[3] =  ipAddress & 0xFF;
8900    tnlInformation->tnlAddress.buf[2] = (ipAddress>> 8) & 0xFF;
8901    tnlInformation->tnlAddress.buf[1] = (ipAddress>> 16) & 0xFF;
8902    tnlInformation->tnlAddress.buf[0] = (ipAddress>> 24) & 0xFF;
8903    tnlInformation->tnlAddress.bits_unused = 0;
8904
8905    switch(protocolId)
8906    {
8907       case ProtocolIE_IDE2_id_E2connectionUpdate_Item:
8908          {
8909             *tnlUsage = usage;
8910             break;
8911          }
8912       case ProtocolIE_IDE2_id_E2connectionSetupFailed_Item:
8913          {
8914             failureCause.causeType = E2_TRANSPORT;
8915             failureCause.cause = E2_TRANSPORT_CAUSE_UNSPECIFIED;
8916             fillE2Cause(cause, failureCause);
8917             break;
8918          }
8919       default:
8920          return RFAILED;
8921    }
8922    return ROK;
8923 }
8924
8925
8926 /*******************************************************************
8927  *
8928  * @brief Build E2 connection modification list
8929  *
8930  * @details
8931  *
8932  *    Function :BuildE2ConnectionUpdateList 
8933  *
8934  *    Functionality: Build E2 connection modification list
8935  *
8936  * @params[in]
8937  *    E2 connection update list to be filled
8938  *    Count of E2 connection to be added in the list    
8939  *    Received list of E2 connection
8940  *
8941  * @return ROK - success
8942  *         RFAILED - failure
8943  * ****************************************************************/
8944
8945 uint8_t BuildE2ConnectionUpdateList(E2connectionUpdate_List_t *connectionSetupList, uint8_t count, E2ConnectionItem *tmpConnectionList)
8946 {
8947    uint8_t arrIdx = 0;
8948    E2connectionUpdate_ItemIEs_t *connectionSetupItem=NULLP;
8949
8950    connectionSetupList->list.count = count;
8951
8952    connectionSetupList->list.size = connectionSetupList->list.count*sizeof(E2connectionUpdate_ItemIEs_t*);
8953    DU_ALLOC(connectionSetupList->list.array, connectionSetupList->list.size);
8954    if(connectionSetupList->list.array)
8955    {
8956       for(arrIdx = 0; arrIdx< connectionSetupList->list.count; arrIdx++)
8957       {
8958          DU_ALLOC(connectionSetupList->list.array[arrIdx], sizeof(E2connectionUpdate_ItemIEs_t));
8959          if(connectionSetupList->list.array[arrIdx] == NULLP)
8960          {
8961             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8962             return RFAILED;
8963          }
8964          connectionSetupItem = (E2connectionUpdate_ItemIEs_t*)connectionSetupList->list.array[arrIdx];
8965          connectionSetupItem->id = ProtocolIE_IDE2_id_E2connectionUpdate_Item;
8966          connectionSetupItem->criticality= CriticalityE2_ignore;
8967          connectionSetupItem->value.present = E2connectionUpdate_ItemIEs__value_PR_E2connectionUpdate_Item;
8968          if(fillE2connectionUpdateItem((PTR)&connectionSetupItem->value.choice.E2connectionUpdate_Item, ProtocolIE_IDE2_id_E2connectionUpdate_Item,\
8969           tmpConnectionList[arrIdx].ipV4Addr, tmpConnectionList[arrIdx].usage) != ROK)
8970          {
8971             DU_LOG("\nERROR  -->  E2AP : Failed to fill E2 connection update item");
8972             return RFAILED;
8973          }
8974
8975       }
8976    }
8977    else
8978    {
8979       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8980       return RFAILED;
8981    }
8982    return ROK;
8983 }
8984
8985 /*******************************************************************
8986  *
8987  * @brief Build E2 connection setup failed list
8988  *
8989  * @details
8990  *
8991  *    Function : BuildE2ConnectionSetupFailedList
8992  *
8993  *    Functionality: Build E2 connection setup failed list
8994  *
8995  * @params[in]
8996  *    E2 connection setup failed list to be filled
8997  *    Count of E2 connection to be added in the list    
8998  *    Received list of E2 connection
8999  *
9000  * @return ROK - success
9001  *         RFAILED - failure
9002  * ****************************************************************/
9003
9004 uint8_t BuildE2ConnectionSetupFailedList(E2connectionSetupFailed_List_t *setupFailedList, uint8_t count, E2ConnectionItem *tmpConnectionList)
9005 {
9006    uint8_t arrIdx = 0;
9007    E2connectionSetupFailed_ItemIEs_t *setupFailedItem=NULLP;
9008
9009    setupFailedList->list.count = 1;
9010
9011    setupFailedList->list.size = setupFailedList->list.count*sizeof(E2connectionSetupFailed_ItemIEs_t *);
9012    DU_ALLOC(setupFailedList->list.array, setupFailedList->list.size);
9013    if(setupFailedList->list.array)
9014    {
9015       for(arrIdx = 0; arrIdx< setupFailedList->list.count; arrIdx++)
9016       {
9017          DU_ALLOC(setupFailedList->list.array[arrIdx], sizeof(E2connectionSetupFailed_ItemIEs_t));
9018          if(setupFailedList->list.array[arrIdx] == NULLP)
9019          {
9020             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
9021             return RFAILED;
9022          }
9023          setupFailedItem = (E2connectionSetupFailed_ItemIEs_t*)setupFailedList->list.array[arrIdx];
9024          setupFailedItem->id = ProtocolIE_IDE2_id_E2connectionSetupFailed_Item;
9025          setupFailedItem->criticality= CriticalityE2_ignore;
9026          setupFailedItem->value.present = E2connectionSetupFailed_ItemIEs__value_PR_E2connectionSetupFailed_Item;
9027          if(fillE2connectionUpdateItem((PTR)&setupFailedItem->value.choice.E2connectionSetupFailed_Item, ProtocolIE_IDE2_id_E2connectionSetupFailed_Item,\
9028           tmpConnectionList[arrIdx].ipV4Addr, tmpConnectionList[arrIdx].usage) != ROK)
9029          {
9030             DU_LOG("\nERROR  -->  E2AP : Failed to fill E2 connection failed to update item");
9031             return RFAILED;
9032          }
9033
9034       }
9035    }
9036    else
9037    {
9038       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
9039       return RFAILED;
9040    }
9041    return ROK;
9042 }
9043
9044 /*******************************************************************
9045  *
9046  * @brief Deallocate the memory allocated for E2 Connection
9047  * Update ack msg 
9048  *
9049  * @details
9050  *
9051  *    Function :FreeE2ConnectionUpdateAcknowledge 
9052  *
9053  *    Functionality:
9054  *       - freeing the memory allocated for E2 Connection
9055  * Update ack msg
9056  *
9057  * @params[in] E2AP_PDU_t *e2apMsg
9058  * @return ROK     - success
9059  *         RFAILED - failure
9060  *
9061  * ****************************************************************/
9062
9063 void FreeE2ConnectionUpdateAcknowledge(E2AP_PDU_t *e2apMsg)
9064 {
9065    uint8_t ieIdx =0, arrIdx=0;
9066    E2connectionUpdateAcknowledge_t *connectionUpdate = NULLP;
9067    E2connectionUpdate_List_t *connectionSetupList = NULLP;
9068    E2connectionSetupFailed_List_t *setupFailedList = NULLP;
9069
9070    if(e2apMsg != NULLP)
9071    {
9072       if(e2apMsg->choice.successfulOutcome != NULLP)
9073       {
9074          connectionUpdate = &e2apMsg->choice.successfulOutcome->value.choice.E2connectionUpdateAcknowledge;
9075          if(connectionUpdate->protocolIEs.list.array)
9076          {
9077             for(ieIdx = 0; ieIdx < connectionUpdate->protocolIEs.list.count; ieIdx++)
9078             {
9079                if(connectionUpdate->protocolIEs.list.array[ieIdx])
9080                {
9081                   switch(connectionUpdate->protocolIEs.list.array[ieIdx]->id)
9082                   {
9083                      case ProtocolIE_IDE2_id_TransactionID:
9084                         break;
9085
9086                      case ProtocolIE_IDE2_id_E2connectionSetup:
9087                         {
9088                            connectionSetupList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List;
9089                            if(connectionSetupList->list.array)
9090                            {
9091                               for(arrIdx = 0; arrIdx < connectionSetupList->list.count; arrIdx++)
9092                               {
9093                                  DU_FREE(connectionSetupList->list.array[arrIdx], sizeof(E2connectionUpdate_ItemIEs_t));
9094                               }
9095                               DU_FREE(connectionSetupList->list.array, connectionSetupList->list.size);
9096                            }
9097                            break;
9098                         }
9099
9100                      case ProtocolIE_IDE2_id_E2connectionSetupFailed:
9101                         {
9102                            setupFailedList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionSetupFailed_List;
9103                            if(setupFailedList->list.array)
9104                            {
9105                               for(arrIdx = 0; arrIdx < setupFailedList->list.count; arrIdx++)
9106                               {
9107                                  DU_FREE(setupFailedList->list.array[arrIdx], sizeof(E2connectionSetupFailed_ItemIEs_t));
9108                               }
9109                               DU_FREE(setupFailedList->list.array, setupFailedList->list.size);
9110                            }
9111                            break;
9112                         }
9113                   }
9114                   DU_FREE(connectionUpdate->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdateAck_IEs_t));
9115                }
9116             }
9117             DU_FREE(connectionUpdate->protocolIEs.list.array, connectionUpdate->protocolIEs.list.size);
9118          }
9119          DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
9120       }
9121       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
9122    }
9123 }
9124
9125 /*******************************************************************
9126  *
9127  * @brief Buld and send the E2 Connection Update Acknowledge msg
9128  *
9129  * @details
9130  *
9131  *    Function : BuildAndSendE2ConnectionUpdateAcknowledge
9132  *
9133  *    Functionality:
9134  *         - Buld and send the E2 Connection Update Acknowledge Message
9135  * @params[in] 
9136  *    Trans Id 
9137  *    List of E2 connection needs to fill in IE 
9138  * @return ROK     - success
9139  *         RFAILED - failure
9140  *
9141  * ****************************************************************/
9142
9143 uint8_t BuildAndSendE2ConnectionUpdateAcknowledge(uint16_t transId,  E2ConnectionList connectionInfoList)
9144 {
9145    uint8_t           ieIdx = 0, elementCnt = 0;
9146    uint8_t           ret = RFAILED;
9147    E2AP_PDU_t        *e2apMsg = NULLP;
9148    asn_enc_rval_t    encRetVal;       
9149    E2connectionUpdateAcknowledge_t *e2ConnectionUpdateAcknowledge=NULLP;
9150
9151    DU_LOG("\nINFO   -->  E2AP : Building E2 Connection Update Acknowledge Message\n");
9152    do
9153    {
9154       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
9155       if(e2apMsg == NULLP)
9156       {
9157          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
9158          break;
9159       }
9160       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
9161
9162       DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
9163       if(e2apMsg->choice.successfulOutcome == NULLP)
9164       {
9165          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
9166          break;
9167       }
9168
9169       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2connectionUpdate;
9170       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
9171       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2connectionUpdateAcknowledge;
9172       e2ConnectionUpdateAcknowledge = &e2apMsg->choice.successfulOutcome->value.choice.E2connectionUpdateAcknowledge;
9173
9174       elementCnt = 1;
9175       if(connectionInfoList.numOfE2ConnectionSetup)
9176          elementCnt++;
9177       if(connectionInfoList.numOfE2ConnectionFailedToSetup)
9178          elementCnt++;
9179
9180       e2ConnectionUpdateAcknowledge->protocolIEs.list.count = elementCnt;
9181       e2ConnectionUpdateAcknowledge->protocolIEs.list.size = elementCnt * sizeof(E2connectionUpdateAck_IEs_t*);
9182       DU_ALLOC(e2ConnectionUpdateAcknowledge->protocolIEs.list.array, e2ConnectionUpdateAcknowledge->protocolIEs.list.size);
9183       if(!e2ConnectionUpdateAcknowledge->protocolIEs.list.array)
9184       {
9185          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
9186          break;
9187       }
9188
9189       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
9190       {
9191          DU_ALLOC(e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdateAck_IEs_t));
9192          if(!e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx])
9193          {
9194             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
9195             break;
9196          }
9197       }
9198       if(ieIdx < elementCnt)
9199          break;
9200
9201       ieIdx = 0;
9202       e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
9203       e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
9204       e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateAck_IEs__value_PR_TransactionID;
9205       e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
9206
9207       if(connectionInfoList.numOfE2ConnectionSetup)
9208       {
9209          ieIdx++;
9210          e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_E2connectionSetup;
9211          e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
9212          e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateAck_IEs__value_PR_E2connectionUpdate_List;
9213          if(BuildE2ConnectionUpdateList(&e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List, \
9214                   connectionInfoList.numOfE2ConnectionSetup, connectionInfoList.setupE2Connection) != ROK)
9215          {
9216             DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Connection setup list");
9217             break;
9218          }
9219       }
9220       
9221       if(connectionInfoList.numOfE2ConnectionFailedToSetup)
9222       {
9223          ieIdx++;
9224          e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_E2connectionSetupFailed;
9225          e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
9226          e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateAck_IEs__value_PR_E2connectionSetupFailed_List;
9227          if(BuildE2ConnectionSetupFailedList(&e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.choice.E2connectionSetupFailed_List, \
9228                connectionInfoList.numOfE2ConnectionFailedToSetup, connectionInfoList.failedToSetupE2Connection) != ROK) 
9229          {
9230             DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Connection failed to setup list");
9231             break;
9232          }
9233       }
9234
9235       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
9236
9237       memset(encBuf, 0, ENC_BUF_MAX_LEN);
9238       encBufSize = 0;
9239       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
9240       if(encRetVal.encoded == ENCODE_FAIL)
9241       {
9242          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 connection update acknowledge failure structure (at %s)\n",\
9243                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
9244          break;
9245       }
9246       else
9247       {
9248          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Connection Update Acknowledge \n");
9249          for(int i=0; i< encBufSize; i++)
9250          {
9251             DU_LOG("%x",encBuf[i]);
9252          }
9253       }
9254
9255       /* Sending msg */
9256       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
9257       {
9258          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Connection Update Acknowledge");
9259          break;
9260       }
9261
9262       ret = ROK;
9263       break;
9264    }while(true);
9265
9266    FreeE2ConnectionUpdateAcknowledge(e2apMsg);
9267    return ret;
9268 }
9269
9270 /******************************************************************
9271  *
9272  * @brief Deallocation of memory allocated by aper decoder for 
9273  * E2 Connection Update
9274  *
9275  * @details
9276  *
9277  *    Function :freeAperDecodingOfE2ConnectionUpdate 
9278  *
9279  *    Functionality: Deallocation of memory allocated by aper decoder for
9280  *    E2 Connection Update
9281  *
9282  * @params[in] Pointer to connectionUpdate 
9283  * @return void
9284  *
9285  * ****************************************************************/
9286
9287 void freeAperDecodingOfE2ConnectionUpdate(E2connectionUpdate_t *connectionUpdate)
9288 {
9289    uint8_t ieIdx =0, arrIdx=0;
9290    E2connectionUpdate_List_t *connectionToBeModifyList = NULLP;
9291    E2connectionUpdateRemove_List_t *connectionToBeRemoveList = NULLP;
9292
9293    if(connectionUpdate->protocolIEs.list.array)
9294    {
9295       for(ieIdx = 0; ieIdx < connectionUpdate->protocolIEs.list.count; ieIdx++)
9296       {
9297          if(connectionUpdate->protocolIEs.list.array[ieIdx])
9298          {
9299             switch(connectionUpdate->protocolIEs.list.array[ieIdx]->id)
9300             {
9301                case ProtocolIE_IDE2_id_TransactionID:
9302                   break;
9303
9304                case ProtocolIE_IDE2_id_E2connectionUpdateModify:
9305                   {
9306                      connectionToBeModifyList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List;
9307                      if(connectionToBeModifyList->list.array)
9308                      {
9309                         for(arrIdx= 0; arrIdx< connectionToBeModifyList->list.count; arrIdx++)
9310                         {
9311                            free(connectionToBeModifyList->list.array[arrIdx]);
9312                         }
9313                         free(connectionToBeModifyList->list.array);
9314                      }
9315                      break;
9316                   }
9317                case ProtocolIE_IDE2_id_E2connectionUpdateRemove:
9318                   {
9319                      connectionToBeRemoveList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdateRemove_List;
9320                      if(connectionToBeRemoveList->list.array)
9321                      {
9322                         for(arrIdx= 0; arrIdx< connectionToBeRemoveList->list.count; arrIdx++)
9323                         {
9324                            free(connectionToBeRemoveList->list.array[arrIdx]);
9325                         }
9326                         free(connectionToBeRemoveList->list.array);
9327                      }
9328                      break;
9329                   }
9330             }
9331             free(connectionUpdate->protocolIEs.list.array[ieIdx]);
9332          }
9333       }
9334       free(connectionUpdate->protocolIEs.list.array);
9335    }
9336 }
9337
9338 /*******************************************************************
9339  *
9340  * @brief Handling of E2 connection modification Ie
9341  *
9342  * @details
9343  *
9344  *    Function : handleE2ConnectionModification 
9345  *
9346  * Functionality: Handling of E2 connection modification Ie
9347  *
9348  * @param 
9349  *        E2 Connection update list
9350  *        E2 connection list which needs to be filled
9351  * @return void
9352  *
9353  ******************************************************************/
9354
9355 void handleE2ConnectionModification(E2connectionUpdate_List_t *connectionUpdateList, E2ConnectionList *connectionInfoList)
9356 {
9357    uint32_t ipAddress=0;
9358    bool infoFound = false;
9359    uint8_t arrIdx=0,idx=0, count =0;
9360    E2connectionUpdate_ItemIEs_t *connectionModifyItem=NULLP;
9361
9362    if(connectionUpdateList->list.array)
9363    {
9364       for(arrIdx = 0; arrIdx < connectionUpdateList->list.count; arrIdx++)
9365       {
9366          connectionModifyItem= (E2connectionUpdate_ItemIEs_t*)connectionUpdateList->list.array[arrIdx];
9367          bitStringToInt(&connectionModifyItem->value.choice.E2connectionUpdate_Item.tnlInformation.tnlAddress, &ipAddress);
9368          for(idx=0; idx<duCb.e2apDb.numOfTNLAssoc; idx++)
9369          {
9370             /* If the TNL information is found in the data base, update the
9371              * information in the database */
9372             if(duCb.e2apDb.tnlAssoc[idx].destIpAddress.ipV4Addr == ipAddress)
9373             {
9374                duCb.e2apDb.tnlAssoc[idx].usage = connectionModifyItem->value.choice.E2connectionUpdate_Item.tnlUsage;
9375                infoFound = true;
9376                break;
9377             }
9378          }
9379          
9380          /* If the TNL information is found in the data base, then add the
9381           * information in setupE2Connection array else add in failedToSetupE2Connection array */
9382          if(infoFound == true)
9383          {
9384             count =connectionInfoList->numOfE2ConnectionSetup;
9385             connectionInfoList->setupE2Connection[count].ipV4Addr =  duCb.e2apDb.tnlAssoc[idx].destIpAddress.ipV4Addr;
9386             connectionInfoList->setupE2Connection[count].usage = duCb.e2apDb.tnlAssoc[idx].usage;
9387             connectionInfoList->numOfE2ConnectionSetup++;
9388          }
9389          else
9390          {
9391             count = connectionInfoList->numOfE2ConnectionFailedToSetup;
9392             connectionInfoList->failedToSetupE2Connection[count].ipV4Addr =  ipAddress;
9393             connectionInfoList->failedToSetupE2Connection[count].usage = connectionModifyItem->value.choice.E2connectionUpdate_Item.tnlUsage;
9394             connectionInfoList->numOfE2ConnectionFailedToSetup++;
9395          }
9396       }
9397
9398    }
9399 }
9400
9401 /*******************************************************************
9402  *
9403  * @brief Handling of E2 connection removal Ie
9404  *
9405  * @details
9406  *
9407  *    Function : handleE2ConnectionRemoval 
9408  *
9409  * Functionality: Handling of E2 connection removal Ie
9410  *
9411  * @param  
9412  *    E2 Connection removal List 
9413  * @return void
9414  *
9415  ******************************************************************/
9416
9417 void handleE2ConnectionRemoval(E2connectionUpdateRemove_List_t *connectionRemovalList)
9418 {
9419    uint32_t ipAddress=0;
9420    uint8_t arrIdx=0,idx=0;
9421    E2connectionUpdateRemove_ItemIEs_t *connectionRemovalItem=NULLP;
9422
9423    if(connectionRemovalList->list.array)
9424    {
9425       for(arrIdx = 0; arrIdx < connectionRemovalList->list.count; arrIdx++)
9426       {
9427          connectionRemovalItem= (E2connectionUpdateRemove_ItemIEs_t*)connectionRemovalList->list.array[arrIdx];
9428          bitStringToInt(&connectionRemovalItem->value.choice.E2connectionUpdateRemove_Item.tnlInformation.tnlAddress, &ipAddress);
9429          for(idx=0; idx<duCb.e2apDb.numOfTNLAssoc; idx++)
9430          {
9431             if(duCb.e2apDb.tnlAssoc[idx].destIpAddress.ipV4Addr == ipAddress)
9432             {
9433                cmInetClose(&ricParams.sockFd);
9434                removeE2NodeInformation();
9435                break;
9436             }
9437          }
9438          
9439       }
9440    }
9441 }
9442
9443 /*******************************************************************
9444  *
9445  * @brief Process e2 connection update received from RIC
9446  *
9447  * @details
9448  *
9449  *    Function : procE2ConnectionUpdate
9450  *
9451  * Functionality: Process e2 connection update received from RIC
9452  *
9453  * @param  E2AP_PDU_t  *e2apMsg
9454  * @return void
9455  *
9456  ******************************************************************/
9457
9458 void procE2ConnectionUpdate(E2AP_PDU_t  *e2apMsg)
9459 {
9460    uint8_t arrIdx =0, transId =0;
9461    bool invalidTransId = false, connectionFailedToUpdate=false;
9462    E2FailureCause failureCause;
9463    E2ConnectionList connectionInfoList;
9464    E2connectionUpdate_t *connectionUpdate=NULLP;
9465
9466    DU_LOG("\nINFO   -->  E2AP : E2 connection update received");
9467    connectionUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2connectionUpdate;
9468    
9469    memset(&connectionInfoList, 0, sizeof(E2ConnectionList));
9470    for(arrIdx=0; arrIdx<connectionUpdate->protocolIEs.list.count; arrIdx++)
9471    {
9472       switch(connectionUpdate->protocolIEs.list.array[arrIdx]->id)
9473       {
9474          case ProtocolIE_IDE2_id_TransactionID:
9475             {
9476                transId = connectionUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
9477                if(transId>255)
9478                {
9479                   failureCause.causeType = E2_PROTOCOL;
9480                   failureCause.cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE;
9481                   invalidTransId = true;
9482                }
9483                break;
9484             }
9485
9486          case ProtocolIE_IDE2_id_E2connectionUpdateModify:
9487             {
9488                handleE2ConnectionModification(&connectionUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2connectionUpdate_List,\
9489                      &connectionInfoList);
9490                if((connectionInfoList.numOfE2ConnectionSetup == 0) && (connectionInfoList.numOfE2ConnectionFailedToSetup > 0))
9491                {
9492                   failureCause.causeType = E2_TRANSPORT;
9493                   failureCause.cause = E2_TRANSPORT_CAUSE_UNSPECIFIED;
9494                   connectionFailedToUpdate =true;
9495                }
9496
9497                break;
9498             }
9499
9500          case ProtocolIE_IDE2_id_E2connectionUpdateRemove:
9501             {
9502                handleE2ConnectionRemoval(&connectionUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2connectionUpdateRemove_List);
9503                break;
9504             }
9505
9506          default:
9507             {
9508                DU_LOG("\nERROR  -->  E2AP : Invalid IE received[%ld]",connectionUpdate->protocolIEs.list.array[arrIdx]->id);
9509                break;
9510             }
9511       }
9512
9513       if(invalidTransId == true || connectionFailedToUpdate ==true)
9514          break;
9515    }
9516    
9517    if(invalidTransId == true || connectionFailedToUpdate == true)
9518    {
9519       if(BuildAndSendE2ConnectionUpdateFailure(transId, failureCause) != ROK)
9520       {
9521          DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 connection update failure");
9522       }
9523    }
9524    else
9525    {
9526       if(BuildAndSendE2ConnectionUpdateAcknowledge(transId, connectionInfoList) != ROK)
9527       {
9528          DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 connection update ack");
9529       }
9530    }
9531
9532    freeAperDecodingOfE2ConnectionUpdate(connectionUpdate);
9533 }
9534
9535 /*******************************************************************
9536  *
9537  * @brief Free RIC Subscription  action to be added list
9538  *
9539  * @details
9540  *
9541  *    Function : freeAperDecodingOfRicSubsActionToBeAdded
9542  *
9543  *    Functionality: Free the RIC Subscription action to be added list
9544  *
9545  * @params[in] RICactions_ToBeAddedForModification_List_t *subsDetails
9546  * @return void
9547  *
9548  * ****************************************************************/
9549 void freeAperDecodingOfRicSubsActionToBeAdded(RICactions_ToBeAddedForModification_List_t *subsDetails)
9550 {
9551    uint8_t elementIdx = 0;
9552    RICaction_ToBeAddedForModification_ItemIEs_t *addedActionItemIe=NULLP;
9553
9554    if(subsDetails->list.array)
9555    {
9556       for(elementIdx = 0; elementIdx < subsDetails->list.count; elementIdx++)
9557       {
9558          if(subsDetails->list.array[elementIdx])
9559          {
9560             addedActionItemIe = (RICaction_ToBeAddedForModification_ItemIEs_t*)subsDetails->list.array[elementIdx];
9561             free(addedActionItemIe->value.choice.RICaction_ToBeAddedForModification_Item.ricActionDefinition.buf);
9562             free(subsDetails->list.array[elementIdx]);
9563          }
9564       }
9565       free(subsDetails->list.array);
9566    }
9567 }
9568
9569 /*******************************************************************
9570  *
9571  * @brief Deallocation of memory allocated by aper decoder for
9572  * RIC Subscription  action to be removed list
9573  *
9574  * @details
9575  *
9576  *    Function : freeAperDecodingOfRicSubsActionToBeRemoved
9577  *
9578  *    Functionality: Free the RIC Subscription action to be removed list
9579  *
9580  * @params[in] RICactions_ToBeRemovedForModification_List_t *subsDetails
9581  * @return void
9582  *
9583  * ****************************************************************/
9584 void freeAperDecodingOfRicSubsActionToBeRemoved(RICactions_ToBeRemovedForModification_List_t *subsDetails)
9585 {
9586    uint8_t elementIdx = 0;
9587
9588    if(subsDetails->list.array)
9589    {
9590       for(elementIdx = 0; elementIdx < subsDetails->list.count; elementIdx++)
9591       {
9592          if(subsDetails->list.array[elementIdx])
9593          {
9594             free(subsDetails->list.array[elementIdx]);
9595          }
9596       }
9597       free(subsDetails->list.array);
9598    }
9599 }
9600
9601 /*******************************************************************
9602  *
9603  * @brief Deallocation of memory allocated by aper decoder for
9604  * RIC Subscription action to be modify
9605  *
9606  * @details
9607  *
9608  *    Function : freeAperDecodingOfRicSubsActionToBeModified
9609  *
9610  *    Functionality: Free the RIC Subscription action to be modify
9611  *
9612  * @params[in] RICactions_ToBeModifiedForModification_List_t List
9613  * @return void
9614  *
9615  * ****************************************************************/
9616 void freeAperDecodingOfRicSubsActionToBeModified(RICactions_ToBeModifiedForModification_List_t *subsDetails)
9617 {
9618    uint8_t elementIdx = 0;
9619    RICaction_ToBeModifiedForModification_ItemIEs_t *actionItem = NULLP;
9620
9621    if(subsDetails->list.array)
9622    {
9623       for(elementIdx = 0; elementIdx < subsDetails->list.count; elementIdx++)
9624       {
9625          if(subsDetails->list.array[elementIdx])
9626          {
9627             actionItem = (RICaction_ToBeModifiedForModification_ItemIEs_t *)subsDetails->list.array[elementIdx];
9628             if(actionItem->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition)
9629             {
9630                free(actionItem->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition->buf);
9631                free(actionItem->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition);
9632             }
9633             free(subsDetails->list.array[elementIdx]);
9634          }
9635       }
9636       free(subsDetails->list.array);
9637    }
9638 }
9639
9640 /*******************************************************************
9641  *
9642  * @brief Deallocation of memory allocated by aper decoder for 
9643  * RIC Subscription modification Request
9644  *
9645  * @details
9646  *
9647  *    Function freeAperDecodingOfRicSubsModificationReq
9648  *
9649  * Functionality : Free RIC Subscription modification Request
9650  *
9651  * @params[in] E2AP_PDU  
9652  * @return void
9653  *
9654  ******************************************************************/
9655 void freeAperDecodingOfRicSubsModificationReq(E2AP_PDU_t *e2apRicMsg)
9656 {
9657    uint8_t idx = 0;
9658    RICsubscriptionModificationRequest_t   *ricSubscriptionModReq;
9659    RICsubscriptionModificationRequest_IEs_t *ricSubscriptionModReqIe;
9660
9661    ricSubscriptionModReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequest;
9662    
9663    if(ricSubscriptionModReq->protocolIEs.list.array)
9664    {
9665       for(idx=0; idx < ricSubscriptionModReq->protocolIEs.list.count; idx++)
9666       {
9667          if(ricSubscriptionModReq->protocolIEs.list.array[idx])
9668          {
9669             ricSubscriptionModReqIe = ricSubscriptionModReq->protocolIEs.list.array[idx];
9670
9671             switch(ricSubscriptionModReq->protocolIEs.list.array[idx]->id)
9672             {
9673                case ProtocolIE_IDE2_id_RICrequestID:
9674                   break;
9675                
9676                case ProtocolIE_IDE2_id_RANfunctionID:
9677                   break;
9678
9679                case ProtocolIE_IDE2_id_RICactionsToBeRemovedForModification_List:
9680                   {
9681                      freeAperDecodingOfRicSubsActionToBeRemoved(&(ricSubscriptionModReqIe->value.choice.RICactions_ToBeRemovedForModification_List));
9682                      break;
9683                   }
9684                case ProtocolIE_IDE2_id_RICactionsToBeModifiedForModification_List:
9685                   {
9686                      freeAperDecodingOfRicSubsActionToBeModified(&(ricSubscriptionModReqIe->value.choice.RICactions_ToBeModifiedForModification_List));
9687                      break;
9688                   }
9689                case ProtocolIE_IDE2_id_RICactionsToBeAddedForModification_List:
9690                   {
9691                      freeAperDecodingOfRicSubsActionToBeAdded(&(ricSubscriptionModReqIe->value.choice.RICactions_ToBeAddedForModification_List));
9692                      break;
9693                   }
9694                default:
9695                   {
9696                      DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", ricSubscriptionModReq->protocolIEs.list.array[idx]->id);
9697                      break;
9698                   }
9699
9700             }
9701
9702             free(ricSubscriptionModReq->protocolIEs.list.array[idx]);
9703          }
9704       }
9705       free(ricSubscriptionModReq->protocolIEs.list.array);
9706    }
9707 }
9708 /*******************************************************************
9709  *
9710  * @brief Extract RIC Action to be added
9711  *
9712  * @details
9713  *
9714  *    Function : extractRicActionToBeAddedForModification
9715  *
9716  * Functionality : This function :
9717  *     - [Step -1] Traverse each AddedForModification item indexes.
9718  *     - [Step -2] Add each action id related information in 
9719  *                 RicSubscription Db.
9720  *     - [Step -3] If failed to store then add action related info in 
9721  *                 pending rsp's rejectedActionList.
9722  *     - [Step -4] Else increment action added count
9723  *     - [Step -5] If there is even 1 action that can be added, 
9724  *                 return ROK, else RFAILED.
9725  *
9726  * @params[in] RAN Function Database structure
9727  *             RIC Subscription Info to be added to RAN function
9728  *             RIC Action To Be AddedForModification List received from RIC
9729  *             failure Cause
9730  *             Pending Subs Mod Rsp Info
9731  * @return ROK     - success
9732  *         RFAILED - failure
9733  *
9734  ******************************************************************/
9735 uint8_t extractRicActionToBeAddedForModification(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \
9736       RICactions_ToBeAddedForModification_List_t *actionList, E2FailureCause *failureCause, PendingSubsModRspInfo *subsModRsp)
9737 {
9738    uint8_t actionAdded=0;
9739    CmLList *actionNode = NULLP;
9740    uint8_t actionIdx = 0;
9741    uint8_t ricActionId = 0;
9742    RICaction_ToBeAddedForModification_ItemIEs_t *actionItem = NULLP;
9743
9744    if(actionList->list.array)
9745    {
9746       for(actionIdx = 0; actionIdx < actionList->list.count; actionIdx++)
9747       {
9748          /* Step -1 */
9749          actionItem =(RICaction_ToBeAddedForModification_ItemIEs_t *)actionList->list.array[actionIdx];
9750          switch(actionItem->id)
9751          {
9752             case ProtocolIE_IDE2_id_RICaction_ToBeAddedForModification_Item:
9753                {
9754                   /* Step -2 */
9755                   actionNode = addRicSubsAction(ranFuncDb, (PTR)&actionItem->value.choice.RICaction_ToBeAddedForModification_Item,\
9756                         &ricSubscriptionInfo->actionSequence, ProtocolIE_IDE2_id_RICaction_ToBeAddedForModification_Item, failureCause);
9757
9758                   if(!actionNode)
9759                   {
9760                      /* Step -3 */
9761                      subsModRsp->addActionStatus.rejectedActionList[subsModRsp->addActionStatus.numOfRejectedActions].id = ricActionId;
9762                      if(failureCause->causeType == E2_NOTHING)
9763                      {
9764                         failureCause->causeType = E2_RIC_REQUEST;
9765                         failureCause->cause = E2_CONTROL_FAILED_TO_EXECUTE;
9766                      }
9767                      memcpy(&subsModRsp->addActionStatus.rejectedActionList[subsModRsp->addActionStatus.numOfRejectedActions].failureCause, \
9768                            failureCause, sizeof(E2FailureCause));
9769                      subsModRsp->addActionStatus.numOfRejectedActions++;
9770                   }
9771                   else
9772                   {
9773                      /* Step -4 */
9774                      actionAdded++;
9775                   }
9776                   break;
9777                }
9778             default:
9779                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RicAddedForModificationLst:%ld",actionItem->id);
9780                break;
9781          }
9782       }
9783    }
9784
9785    /* Step -5 */
9786    if(actionAdded)
9787       return ROK;
9788
9789    if(failureCause->causeType == E2_NOTHING)
9790    {
9791       failureCause->causeType = E2_RIC_REQUEST;
9792       failureCause->cause = E2_ACTION_NOT_SUPPORTED;
9793    }
9794    return RFAILED;
9795 }
9796
9797 /*******************************************************************
9798  *
9799  * @brief Extract RIC Action to be Modified
9800  *
9801  * @details
9802  *
9803  *    Function : extractRicActionToBeModifiedForModification
9804  *
9805  * Functionality : This function :
9806  *     - [Step -1] Traverse each Modification item indexes.
9807  *     - [Step -2] Find each action id related information in 
9808  *                 RicSubscription Db.
9809  *     - [Step -3] If not found store the action related info in pending 
9810  *                 rsp's action rejected.
9811  *     - [Step -4] If found store the new node in action seq list.
9812  *          [Step -4.1] If action failed to store, add the action 
9813  *                 info in pending subscription rsp's rejected list.
9814  *          [Step -4.2] If action stored successfully, change the status 
9815  *             of added action to modified because action added as part of
9816  *             ric subscription modification req.
9817  *     - [Step -5] If there is even 1 action that can be modified, 
9818  *                 return ROK, else RFAILED.
9819  *
9820  * @params[in] RAN Function Database structure
9821  *             RIC Subscription Info to be Modified to RAN function
9822  *             RIC Action To Be ModifiedForModification List received from RIC
9823  *             failure Cause
9824  *             Pending Subs Mod Rsp Info
9825  * @return ROK     - success
9826  *         RFAILED - failure
9827  *
9828  ******************************************************************/
9829 uint8_t extractRicActionToBeModifiedForModification(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \
9830       RICactions_ToBeModifiedForModification_List_t *actionList, E2FailureCause *failureCause, PendingSubsModRspInfo *subsModRsp)
9831 {
9832    uint8_t actionId=0;
9833    uint8_t actionIdx = 0;
9834    uint8_t actionFound=0;
9835    CmLList *actionNode = NULLP;
9836    ActionInfo *actionDb = NULLP;
9837    RICaction_ToBeModifiedForModification_ItemIEs_t *actionItem = NULLP;
9838
9839    if(actionList->list.array)
9840    {
9841       for(actionIdx = 0; actionIdx < actionList->list.count; actionIdx++)
9842       {
9843          /* [Step -1] */
9844          actionItem =(RICaction_ToBeModifiedForModification_ItemIEs_t *)actionList->list.array[actionIdx];
9845          switch(actionItem->id)
9846          {
9847             case ProtocolIE_IDE2_id_RICaction_ToBeModifiedForModification_Item:
9848                {
9849                   /* [Step -2] */
9850                   actionId=actionItem->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionID;
9851                   actionDb = fetchActionInfoFromActionId(actionId, ricSubscriptionInfo, &actionNode, CONFIG_UNKNOWN);
9852                   if(!actionNode)
9853                   {
9854                      /* [Step -3] */
9855                      subsModRsp->removeActionStatus.rejectedActionList[subsModRsp->modActionStatus.numOfRejectedActions].id = actionDb->actionId;
9856                      failureCause->causeType = E2_RIC_REQUEST;
9857                      failureCause->cause = E2_ACTION_NOT_SUPPORTED;
9858                      memcpy(&subsModRsp->removeActionStatus.rejectedActionList[subsModRsp->modActionStatus.numOfRejectedActions].failureCause, \
9859                            failureCause, sizeof(E2FailureCause));
9860                      subsModRsp->modActionStatus.numOfRejectedActions++;
9861                   }
9862                   else
9863                   {
9864                      /* [Step -4] */
9865                      actionNode = NULLP;
9866                      actionNode = addRicSubsAction(ranFuncDb, (PTR)&actionItem->value.choice.RICaction_ToBeModifiedForModification_Item,\
9867                            &ricSubscriptionInfo->actionSequence, ProtocolIE_IDE2_id_RICaction_ToBeModifiedForModification_Item, failureCause);
9868
9869                      if(!actionNode)
9870                      {
9871                         /* [Step -4.1] */
9872                         subsModRsp->modActionStatus.rejectedActionList[subsModRsp->modActionStatus.numOfRejectedActions].id = actionId;
9873                         if(failureCause->causeType == E2_NOTHING)
9874                         {
9875                            failureCause->causeType = E2_RIC_REQUEST;
9876                            failureCause->cause = E2_CONTROL_FAILED_TO_EXECUTE;
9877                         }
9878                         memcpy(&subsModRsp->modActionStatus.rejectedActionList[subsModRsp->modActionStatus.numOfRejectedActions].failureCause, \
9879                               failureCause, sizeof(E2FailureCause));
9880                         subsModRsp->addActionStatus.numOfRejectedActions++;
9881                      }
9882                      else
9883                      {
9884                         /* [Step -4.2] */
9885                         actionDb = (ActionInfo*)actionNode->node;
9886                         actionDb->action=CONFIG_MOD;
9887                         actionFound++;
9888                      }
9889                      break;
9890                   }
9891                   break;
9892                }
9893             default:
9894                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RicModifiedForModificationLst:%ld",actionItem->id);
9895                break;
9896          }
9897       }
9898    }
9899
9900    /* [Step -5] */
9901    if(actionFound)
9902       return ROK;
9903
9904    return RFAILED;
9905 }
9906
9907 /*******************************************************************
9908  *
9909  * @brief Extract RIC Action to be Removed
9910  *
9911  * @details
9912  *
9913  *    Function : extractRicActionToBeRemovedForModification
9914  *
9915  * Functionality : This function :
9916  *     - [Step -1] Traverse each RemovedForModification item indexes.
9917  *     - [Step -2] Find each action id related information in 
9918  *                 RicSubscription Db.
9919  *     - [Step -3] If not found store the action related info in pending 
9920  *                 rsp's rejectedActionList.
9921  *     - [Step -4] If found mark action's status CONFIG_DEL.
9922  *     - [Step -5] If there is even 1 action that can be Removed, 
9923  *                 return ROK, else RFAILED.
9924  *
9925  * @params[in] RAN Function Database structure
9926  *             RIC Subscription Info to be Removed to RAN function
9927  *             RIC Action To Be RemovedForModification List received from RIC
9928  *             failure Cause
9929  *             Pending ric subs mod Rsp Info to store failure result
9930  * @return ROK     - success
9931  *         RFAILED - failure
9932  *
9933  ******************************************************************/
9934 uint8_t extractRicActionToBeRemovedForModification(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \
9935       RICactions_ToBeRemovedForModification_List_t *actionList, E2FailureCause *failureCause, PendingSubsModRspInfo *subsModRsp)
9936 {
9937    uint8_t actionId=0;
9938    uint8_t actionIdx = 0;
9939    uint8_t actionFound=0;
9940    CmLList *actionNode = NULLP;
9941    ActionInfo *actionDb = NULLP;
9942    RICaction_ToBeRemovedForModification_ItemIEs_t *actionItem = NULLP;
9943
9944    if(actionList->list.array)
9945    {
9946       for(actionIdx = 0; actionIdx < actionList->list.count; actionIdx++)
9947       {
9948          /* [Step -1] */
9949          actionItem =(RICaction_ToBeRemovedForModification_ItemIEs_t *)actionList->list.array[actionIdx];
9950          switch(actionItem->id)
9951          {
9952             case ProtocolIE_IDE2_id_RICaction_ToBeRemovedForModification_Item:
9953                {
9954                   /* [Step -2] */
9955                   actionId = actionItem->value.choice.RICaction_ToBeRemovedForModification_Item.ricActionID;
9956                   actionDb = fetchActionInfoFromActionId(actionId, ricSubscriptionInfo, &actionNode, CONFIG_UNKNOWN);
9957                   if(!actionNode)
9958                   {
9959                      /* [Step -3] */
9960                      subsModRsp->removeActionStatus.rejectedActionList[subsModRsp->removeActionStatus.numOfRejectedActions].id = actionDb->actionId;
9961                      if(failureCause->causeType == E2_NOTHING)
9962                      {
9963                         failureCause->causeType = E2_RIC_REQUEST;
9964                         failureCause->cause = E2_ACTION_NOT_SUPPORTED;
9965                      }
9966                      memcpy(&subsModRsp->removeActionStatus.rejectedActionList[subsModRsp->removeActionStatus.numOfRejectedActions].failureCause, \
9967                            failureCause, sizeof(E2FailureCause));
9968                      subsModRsp->removeActionStatus.numOfRejectedActions++;
9969                   }
9970                   else
9971                   {
9972                      /* [Step -4] */
9973                      actionDb->action=CONFIG_DEL;
9974                      actionFound++;
9975                   }
9976                   break;
9977                }
9978             default:
9979                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RicRemovedForModificationLst:%ld",actionItem->id);
9980                break;
9981          }
9982       }
9983    }
9984
9985    /* [Step -5] */
9986    if(actionFound)
9987       return ROK;
9988
9989    return RFAILED;
9990 }
9991
9992 /*******************************************************************
9993  *
9994  * @brief Process RIC Subscription modification request
9995  *
9996  * @details
9997  *
9998  *    Function : procRicSubscriptionModificationRequest
9999  *
10000  * Functionality: Process RIC subscription modification request.
10001  *
10002  * @params[in] E2AP PDU
10003  * @return void
10004  *
10005  ******************************************************************/
10006 void procRicSubscriptionModificationRequest(E2AP_PDU_t *e2apMsg)
10007 {
10008    uint8_t ieIdx = 0;
10009    uint16_t ranFuncId = 0;
10010    RicRequestId ricReqId;
10011    E2FailureCause failureCause;
10012    bool procFailure = false;
10013    bool addActionIeProcessed=false;
10014    bool modActionIeProcessed =false;
10015    bool removeActionIeProcessed =false;
10016    CmLList *ricSubsNode = NULLP;
10017    RanFunction *ranFuncDb = NULLP;
10018    RicSubscription *ricSubsDb = NULLP;
10019    RICsubscriptionModificationRequest_t *ricSubsModifyReq = NULLP;
10020    RICsubscriptionModificationRequest_IEs_t *ricSubsModifyReqIe = NULLP;
10021    
10022    DU_LOG("\nINFO   -->  E2AP : %s: Received RIC Subscription Modification Request", __func__);
10023
10024    do{
10025       if(!e2apMsg)
10026       {
10027          DU_LOG("\nERROR  -->  E2AP : %s: E2AP Message is NULL", __func__);
10028          break;
10029       }
10030
10031       if(!e2apMsg->choice.initiatingMessage)
10032       {
10033          DU_LOG("\nERROR  -->  E2AP : %s: Initiating Message in E2AP PDU is NULL", __func__);
10034          break;
10035       }
10036
10037       ricSubsModifyReq =  &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequest;
10038       for(ieIdx = 0; ieIdx < ricSubsModifyReq->protocolIEs.list.count; ieIdx++)
10039       {
10040          if(!ricSubsModifyReq->protocolIEs.list.array[ieIdx])
10041          {
10042             DU_LOG("\nERROR  -->  E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx);
10043             break;
10044          }
10045
10046          ricSubsModifyReqIe = ricSubsModifyReq->protocolIEs.list.array[ieIdx];
10047          switch(ricSubsModifyReqIe->id)
10048          {
10049             case ProtocolIE_IDE2_id_RICrequestID:
10050                {
10051                   memset(&ricReqId, 0, sizeof(RicRequestId));
10052                   ricReqId.requestorId = ricSubsModifyReqIe->value.choice.RICrequestID.ricRequestorID;
10053                   ricReqId.instanceId = ricSubsModifyReqIe->value.choice.RICrequestID.ricInstanceID;
10054                   break;
10055                }
10056
10057             case ProtocolIE_IDE2_id_RANfunctionID:
10058                {
10059                   ranFuncId = ricSubsModifyReqIe->value.choice.RANfunctionID;
10060                   ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
10061                   if(!ranFuncDb)
10062                   {
10063                      DU_LOG("\nERROR  -->  E2AP : %s: RAN Function ID [%d] not found", __func__, ranFuncId);
10064                      procFailure = true;
10065                      break;
10066                   }
10067
10068                   ricSubsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
10069                   if(!ricSubsDb)
10070                   {
10071                      DU_LOG("\nERROR  -->  E2AP : %s: RIC Subscription not found for Requestor_ID [%d] Instance_ID [%d]",\
10072                            __func__, ricReqId.requestorId, ricReqId.instanceId);
10073                      procFailure = true;
10074                      break;
10075                   }
10076                   memset(&ranFuncDb->pendingSubsModRspInfo[ranFuncDb->numPendingSubsModRsp], 0, sizeof(PendingSubsModRspInfo));
10077                   memcpy(&ranFuncDb->pendingSubsModRspInfo[ranFuncDb->numPendingSubsModRsp].requestId, 
10078                         &ricReqId, sizeof(RicRequestId));
10079                   ranFuncDb->pendingSubsModRspInfo[ranFuncDb->numPendingSubsModRsp].ranFuncId = ranFuncId;
10080
10081                   break;
10082                }
10083             case ProtocolIE_IDE2_id_RICactionsToBeRemovedForModification_List:
10084                {
10085                   if(extractRicActionToBeRemovedForModification(ranFuncDb, ricSubsDb,\
10086                   &ricSubsModifyReqIe->value.choice.RICactions_ToBeRemovedForModification_List,\
10087                   &failureCause, &ranFuncDb->pendingSubsModRspInfo[ranFuncDb->numPendingSubsModRsp]) == ROK)
10088                   {
10089                      removeActionIeProcessed= true;
10090                   }
10091
10092                   break;
10093                }
10094             case ProtocolIE_IDE2_id_RICactionsToBeModifiedForModification_List:
10095                {
10096                   if(extractRicActionToBeModifiedForModification(ranFuncDb, ricSubsDb,\
10097                   &ricSubsModifyReqIe->value.choice.RICactions_ToBeModifiedForModification_List,\
10098                   &failureCause, &ranFuncDb->pendingSubsModRspInfo[ranFuncDb->numPendingSubsModRsp]) == ROK)
10099                   {
10100                      modActionIeProcessed = true;
10101                   }
10102                   break;
10103                }
10104             case ProtocolIE_IDE2_id_RICactionsToBeAddedForModification_List:
10105                {
10106                   if(extractRicActionToBeAddedForModification(ranFuncDb, ricSubsDb,\
10107                   &ricSubsModifyReqIe->value.choice.RICactions_ToBeAddedForModification_List,\
10108                   &failureCause, &ranFuncDb->pendingSubsModRspInfo[ranFuncDb->numPendingSubsModRsp]) == ROK)
10109                   {
10110                      addActionIeProcessed = true;
10111                   }
10112                   break;
10113                }
10114             default:
10115                break;
10116          } /* End of switch for Protocol IE Id */
10117
10118          if(procFailure)
10119             break;
10120       } /* End of for loop for Protocol IE list */
10121
10122       break;
10123    }while(true);
10124    
10125    if(!removeActionIeProcessed && !addActionIeProcessed && !modActionIeProcessed)
10126    {
10127       BuildAndSendRicSubscriptionModificationFailure(ranFuncId, ricReqId, failureCause);
10128    }
10129    else
10130    {
10131       if(duChkTmr((PTR)ricSubsDb, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR) == true)
10132       {
10133          duStopTmr((PTR)ricSubsDb, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR);
10134       }
10135
10136       ricSubsDb->action = CONFIG_MOD;
10137       ranFuncDb->numPendingSubsModRsp++;
10138       
10139       /*If the remove-action ie is present, send a stats delete request; 
10140        * otherwise, change removeActionCompleted to true in the pendingSubsModRspInfo. */
10141       if(removeActionIeProcessed)
10142       {
10143          BuildAndSendStatsDeleteReq(ricSubsDb, false);
10144       }
10145       else
10146       {
10147          ranFuncDb->pendingSubsModRspInfo[ranFuncDb->numPendingSubsModRsp-1].removeActionCompleted = true;
10148       }
10149       
10150       /*If the mod-action ie is present, send a stats modification request; 
10151        * otherwise, change modActionCompleted to true in the pendingSubsModRspInfo. */
10152       if(modActionIeProcessed)
10153       {
10154          BuildAndSendStatsModificationReq(ricSubsDb);
10155       }
10156       else
10157       {
10158          ranFuncDb->pendingSubsModRspInfo[ranFuncDb->numPendingSubsModRsp-1].modActionCompleted= true;
10159       }
10160
10161       /*If the add-action ie is present, send a stats add request; 
10162        * otherwise, change addActionCompleted to true in the pendingSubsModRspInfo. */
10163       if(addActionIeProcessed)
10164       {
10165          BuildAndSendStatsReq(ricSubsDb);
10166       }
10167       else
10168       {
10169          ranFuncDb->pendingSubsModRspInfo[ranFuncDb->numPendingSubsModRsp-1].addActionCompleted= true;
10170       }
10171
10172    }
10173
10174    freeAperDecodingOfRicSubsModificationReq(e2apMsg);
10175 }
10176
10177 /*******************************************************************
10178  * @brief Free RIC Subscription Modification Failure Message
10179  *
10180  * @details
10181  *
10182  *    Function : FreeRicSubscriptionModificationFailure
10183  *
10184  * Functionality:  Free RIC Subscription Modification Failure
10185  *
10186  * @param  E2AP Message PDU
10187  * @return void
10188  *
10189  ******************************************************************/
10190 void FreeRicSubscriptionModificationFailure(E2AP_PDU_t *e2apMsg)
10191 {
10192    uint8_t ieIdx = 0;
10193    RICsubscriptionModificationFailure_t *ricSubsModFailure = NULLP;
10194
10195    if(e2apMsg)
10196    {
10197       if(e2apMsg->choice.unsuccessfulOutcome)
10198       {
10199          ricSubsModFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationFailure;
10200          if(ricSubsModFailure->protocolIEs.list.array)
10201          {
10202             for(ieIdx = 0; ieIdx < ricSubsModFailure->protocolIEs.list.count; ieIdx++)
10203             {
10204                DU_FREE(ricSubsModFailure->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationFailure_IEs_t));
10205             }
10206             DU_FREE(ricSubsModFailure->protocolIEs.list.array, ricSubsModFailure->protocolIEs.list.size);
10207          }
10208          DU_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
10209       }
10210       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));;
10211    }
10212 }
10213 /*******************************************************************
10214  *
10215  * @brief Builds and Send RIC Subscription Modification Failure
10216  *
10217  * @details
10218  *
10219  *    Function : BuildAndSendRicSubscriptionModificationFailure
10220  *
10221  * Functionality: Build and send RIC Subscription Modification Failure.
10222  *
10223  * @params[in]
10224  *          Ran Func Id
10225  *          Ric Req Id
10226  *          E2 failure cause
10227  * @return ROK     - success
10228  *         RFAILED - failure
10229  *
10230  ******************************************************************/
10231 uint8_t BuildAndSendRicSubscriptionModificationFailure(uint16_t ranFuncId,  RicRequestId requestId, E2FailureCause failureCause)
10232 {
10233    uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED;
10234    E2AP_PDU_t         *e2apMsg = NULLP;
10235    RICsubscriptionModificationFailure_t *ricSubsModFailure = NULLP;
10236    RICsubscriptionModificationFailure_IEs_t *ricSubsModFailureIe = NULLP;
10237    asn_enc_rval_t     encRetVal;        /* Encoder return value */
10238
10239    while(true)
10240    {
10241       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Failure Message\n");
10242
10243       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
10244       if(e2apMsg == NULLP)
10245       {
10246          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
10247          break;
10248       }
10249
10250       e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome;
10251       DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
10252       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
10253       {
10254          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
10255          break;
10256       }
10257       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionModification;
10258       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
10259       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICsubscriptionModificationFailure;
10260
10261
10262       ricSubsModFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationFailure;
10263
10264       elementCnt = 3;
10265       ricSubsModFailure->protocolIEs.list.count = elementCnt;
10266       ricSubsModFailure->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationFailure_IEs_t *);
10267
10268       DU_ALLOC(ricSubsModFailure->protocolIEs.list.array, ricSubsModFailure->protocolIEs.list.size);
10269       if(ricSubsModFailure->protocolIEs.list.array == NULLP)
10270       {
10271          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__);
10272          break;
10273       }
10274
10275       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
10276       {
10277          DU_ALLOC(ricSubsModFailure->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationFailure_IEs_t));
10278          if(ricSubsModFailure->protocolIEs.list.array[ieIdx] == NULLP)
10279          {
10280             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for index [%d] at line %d", \
10281                   __func__, ieIdx, __LINE__);
10282             break;
10283          }
10284       }
10285       if(ieIdx < elementCnt)
10286          break;
10287
10288       ieIdx = 0;
10289       ricSubsModFailureIe = ricSubsModFailure->protocolIEs.list.array[ieIdx];
10290       ricSubsModFailureIe->id = ProtocolIE_IDE2_id_RICrequestID;
10291       ricSubsModFailureIe->criticality = CriticalityE2_reject;
10292       ricSubsModFailureIe->value.present = RICsubscriptionModificationFailure_IEs__value_PR_RICrequestID;
10293       ricSubsModFailureIe->value.choice.RICrequestID.ricRequestorID= requestId.requestorId;
10294       ricSubsModFailureIe->value.choice.RICrequestID.ricInstanceID = requestId.instanceId;
10295
10296       ieIdx++;
10297       ricSubsModFailureIe = ricSubsModFailure->protocolIEs.list.array[ieIdx];
10298       ricSubsModFailureIe->id = ProtocolIE_IDE2_id_RANfunctionID;
10299       ricSubsModFailureIe->criticality = CriticalityE2_reject;
10300       ricSubsModFailureIe->value.present = RICsubscriptionModificationFailure_IEs__value_PR_RANfunctionID;
10301       ricSubsModFailureIe->value.choice.RANfunctionID = ranFuncId;
10302
10303       ieIdx++;
10304       ricSubsModFailureIe = ricSubsModFailure->protocolIEs.list.array[ieIdx];
10305       ricSubsModFailureIe->id = ProtocolIE_IDE2_id_CauseE2;
10306       ricSubsModFailureIe->criticality = CriticalityE2_reject;
10307       ricSubsModFailureIe->value.present = RICsubscriptionModificationFailure_IEs__value_PR_CauseE2;
10308       fillE2Cause(&ricSubsModFailureIe->value.choice.CauseE2, failureCause);
10309
10310       /* Prints the Msg formed */
10311       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
10312       memset(encBuf, 0, ENC_BUF_MAX_LEN);
10313       encBufSize = 0;
10314       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
10315       if(encRetVal.encoded == ENCODE_FAIL)
10316       {
10317          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Modification Failure Message (at %s)\n",\
10318                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
10319          break;
10320       }
10321       else
10322       {
10323          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Modification Failure Message \n");
10324 #ifdef DEBUG_ASN_PRINT
10325          for(int i=0; i< encBufSize; i++)
10326          {
10327             printf("%x",encBuf[i]);
10328          }
10329 #endif
10330       }
10331
10332       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
10333       {
10334          DU_LOG("\nERROR   -->  E2AP : Failed to send RIC Susbcription Modification Failure Message");
10335          break;
10336       }
10337
10338       ret = ROK;
10339       break;
10340    }
10341
10342    FreeRicSubscriptionModificationFailure(e2apMsg);
10343    return ret;
10344 }
10345
10346 /*******************************************************************
10347  * @brief Free RIC Subscription Modification Response Message
10348  *
10349  * @details
10350  *
10351  *    Function : FreeRicSubscriptionModificationResponse
10352  *
10353  * Functionality:  Free RIC Subscription Modification Response
10354  *
10355  * @param  E2AP Message PDU
10356  * @return void
10357  *
10358  ******************************************************************/
10359 void FreeRicSubscriptionModificationResponse(E2AP_PDU_t *e2apMsg)
10360 {
10361    uint8_t ieIdx = 0, elementIdx=0;
10362    RICactions_AddedForModification_List_t *actionsAdded = NULLP;
10363    RICactions_RemovedForModification_List_t *actionsRemoved = NULLP;
10364    RICactions_ModifiedForModification_List_t *actionsModified = NULLP;
10365    RICactions_FailedToBeAddedForModification_List_t  *actionsFailedToBeAdded = NULLP;
10366    RICactions_FailedToBeRemovedForModification_List_t *actionsFailedToBeRemoved = NULLP;
10367    RICactions_FailedToBeModifiedForModification_List_t *actionsFailedToBeModified = NULLP;
10368
10369    RICsubscriptionModificationResponse_t *ricSubsModResponse = NULLP;
10370
10371    if(e2apMsg)
10372    {
10373       if(e2apMsg->choice.successfulOutcome)
10374       {
10375          ricSubsModResponse = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationResponse;
10376          if(ricSubsModResponse->protocolIEs.list.array)
10377          {
10378             for(ieIdx = 0; ieIdx < ricSubsModResponse->protocolIEs.list.count; ieIdx++)
10379             {
10380                if(ricSubsModResponse->protocolIEs.list.array[ieIdx])
10381                {
10382                   switch(ricSubsModResponse->protocolIEs.list.array[ieIdx]->id)
10383                   {
10384                      case ProtocolIE_IDE2_id_RANfunctionID:
10385                      case ProtocolIE_IDE2_id_RICrequestID:
10386                         break;
10387                      case ProtocolIE_IDE2_id_RICactionsRemovedForModification_List:
10388                         {
10389                            actionsRemoved = &ricSubsModResponse->protocolIEs.list.array[ieIdx]->value.choice.RICactions_RemovedForModification_List;
10390                            if(actionsRemoved->list.array)
10391                            {
10392                               for(elementIdx = 0; elementIdx < actionsRemoved->list.count; elementIdx++)
10393                               {
10394                                  DU_FREE(actionsRemoved->list.array[elementIdx], sizeof(RICaction_RemovedForModification_ItemIEs_t));
10395                               }
10396                               DU_FREE(actionsRemoved->list.array, actionsRemoved->list.size);
10397                            }
10398                            break;
10399                         }
10400
10401                      case ProtocolIE_IDE2_id_RICactionsFailedToBeRemovedForModification_List:
10402                         {
10403                            actionsFailedToBeRemoved = &ricSubsModResponse->protocolIEs.list.array[ieIdx]->value.choice.RICactions_FailedToBeRemovedForModification_List;
10404                            if(actionsFailedToBeRemoved->list.array)
10405                            {
10406                               for(elementIdx = 0; elementIdx < actionsFailedToBeRemoved->list.count; elementIdx++)
10407                               {
10408                                  DU_FREE(actionsFailedToBeRemoved->list.array[elementIdx], sizeof(RICaction_FailedToBeRemovedForModification_ItemIEs_t));
10409                               }
10410                               DU_FREE(actionsFailedToBeRemoved->list.array, actionsFailedToBeRemoved->list.size);
10411                            }
10412                            break;
10413                         }
10414                      case ProtocolIE_IDE2_id_RICactionsModifiedForModification_List:
10415                         {
10416                            actionsModified = &ricSubsModResponse->protocolIEs.list.array[ieIdx]->value.choice.RICactions_ModifiedForModification_List;
10417                            if(actionsModified->list.array)
10418                            {
10419                               for(elementIdx = 0; elementIdx < actionsModified->list.count; elementIdx++)
10420                               {
10421                                  DU_FREE(actionsModified->list.array[elementIdx], sizeof(RICaction_ModifiedForModification_ItemIEs_t));
10422                               }
10423                               DU_FREE(actionsModified->list.array, actionsModified->list.size);
10424                            }
10425                            break;
10426                         }
10427                      case ProtocolIE_IDE2_id_RICactionsFailedToBeModifiedForModification_List:
10428                         {
10429                            actionsFailedToBeModified = &ricSubsModResponse->protocolIEs.list.array[ieIdx]->value.choice.RICactions_FailedToBeModifiedForModification_List;
10430                            if(actionsFailedToBeModified->list.array)
10431                            {
10432                               for(elementIdx = 0; elementIdx < actionsFailedToBeModified->list.count; elementIdx++)
10433                               {
10434                                  DU_FREE(actionsFailedToBeModified->list.array[elementIdx], sizeof(RICaction_FailedToBeModifiedForModification_ItemIEs_t));
10435                               }
10436                               DU_FREE(actionsFailedToBeModified->list.array, actionsFailedToBeModified->list.size);
10437                            }
10438                            break;
10439                         }
10440                      case ProtocolIE_IDE2_id_RICactionsAddedForModification_List:
10441                         {
10442                            actionsAdded = &ricSubsModResponse->protocolIEs.list.array[ieIdx]->value.choice.RICactions_AddedForModification_List;
10443                            if(actionsAdded->list.array)
10444                            {
10445                               for(elementIdx = 0; elementIdx < actionsAdded->list.count; elementIdx++)
10446                               {
10447                                  DU_FREE(actionsAdded->list.array[elementIdx], sizeof(RICaction_AddedForModification_ItemIEs_t));
10448                               }
10449                               DU_FREE(actionsAdded->list.array, actionsAdded->list.size);
10450                            }
10451                            break;
10452                         }
10453                      case ProtocolIE_IDE2_id_RICactionsFailedToBeAddedForModification_List:
10454                         {
10455                            actionsFailedToBeAdded = &ricSubsModResponse->protocolIEs.list.array[ieIdx]->value.choice.RICactions_FailedToBeAddedForModification_List;
10456                            if(actionsFailedToBeAdded->list.array)
10457                            {
10458                               for(elementIdx = 0; elementIdx < actionsFailedToBeAdded->list.count; elementIdx++)
10459                               {
10460                                  DU_FREE(actionsFailedToBeAdded->list.array[elementIdx], sizeof(RICaction_FailedToBeAddedForModification_ItemIEs_t));
10461                               }
10462                               DU_FREE(actionsFailedToBeAdded->list.array, actionsFailedToBeAdded->list.size);
10463                            }
10464                            break;
10465                         }
10466                   }
10467                   DU_FREE(ricSubsModResponse->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationResponse_IEs_t));
10468                }
10469             }
10470             DU_FREE(ricSubsModResponse->protocolIEs.list.array, ricSubsModResponse->protocolIEs.list.size);
10471          }
10472          DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
10473       }
10474       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));;
10475    }
10476 }
10477
10478 /*******************************************************************
10479 *
10480 * @brief Build Ric subscription action removed list
10481 *
10482 * @details
10483 *
10484 *    Function : BuildActionRemovedList
10485 *
10486 *    Functionality: Build Ric subs action removed list
10487 *
10488 * @params[in]
10489 *    RICactions_RemovedForModification_List_t to be filled
10490 *    Num Of Action removed
10491 *    Action removed list
10492 *
10493 * @return ROK     - success
10494 *         RFAILED - failure
10495 *
10496 ******************************************************************/
10497
10498 uint8_t BuildActionRemovedList(RICactions_RemovedForModification_List_t *removedActionList, uint8_t numOfActionRemoved, uint8_t *actionRemoved)
10499 {
10500    uint8_t arrIdx=0;
10501    RICaction_RemovedForModification_ItemIEs_t *removedActionItemIe =NULLP;
10502
10503    removedActionList->list.count = numOfActionRemoved;
10504    removedActionList->list.size = removedActionList->list.count *  sizeof(RICaction_RemovedForModification_ItemIEs_t*);
10505    DU_ALLOC(removedActionList->list.array, removedActionList->list.size);
10506    if(!removedActionList->list.array)
10507    {
10508       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
10509       return RFAILED;
10510    }
10511
10512    for(arrIdx = 0; arrIdx< removedActionList->list.count; arrIdx++)
10513    {
10514       DU_ALLOC(removedActionList->list.array[arrIdx], sizeof(RICaction_RemovedForModification_ItemIEs_t));
10515       if(!removedActionList->list.array[arrIdx])
10516       {
10517          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
10518          return RFAILED;
10519       }
10520       removedActionItemIe = (RICaction_RemovedForModification_ItemIEs_t*)removedActionList->list.array[arrIdx];
10521       removedActionItemIe->id = ProtocolIE_IDE2_id_RICaction_RemovedForModification_Item;
10522       removedActionItemIe->criticality = CriticalityE2_ignore;
10523       removedActionItemIe->value.present = RICaction_RemovedForModification_ItemIEs__value_PR_RICaction_RemovedForModification_Item;
10524       removedActionItemIe->value.choice.RICaction_RemovedForModification_Item.ricActionID = actionRemoved[arrIdx];
10525    }
10526    return ROK;
10527 }
10528
10529 /*******************************************************************
10530 *
10531 * @brief Build Ric subscription action added list
10532 *
10533 * @details
10534 *
10535 *    Function : BuildActionAddedList
10536 *
10537 *    Functionality: Build Ric subs action added list
10538 *
10539 * @params[in]
10540 *    RICactions_AddedForModification_List_t to be filled
10541 *    Num Of Action added
10542 *    Action added list
10543 *
10544 * @return ROK     - success
10545 *         RFAILED - failure
10546 *
10547 ******************************************************************/
10548
10549 uint8_t BuildActionAddedList(RICactions_AddedForModification_List_t *addedActionList, uint8_t numOfActionAdded, uint8_t *actionAdded)
10550 {
10551    uint8_t arrIdx=0;
10552    RICaction_AddedForModification_ItemIEs_t *addedActionItemIe =NULLP;
10553
10554    addedActionList->list.count = numOfActionAdded;
10555    addedActionList->list.size = addedActionList->list.count *  sizeof(RICaction_AddedForModification_ItemIEs_t*);
10556    DU_ALLOC(addedActionList->list.array, addedActionList->list.size);
10557    if(!addedActionList->list.array)
10558    {
10559       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
10560       return RFAILED;
10561    }
10562
10563    for(arrIdx = 0; arrIdx< addedActionList->list.count; arrIdx++)
10564    {
10565       DU_ALLOC(addedActionList->list.array[arrIdx], sizeof(RICaction_AddedForModification_ItemIEs_t));
10566       if(!addedActionList->list.array[arrIdx])
10567       {
10568          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
10569          return RFAILED;
10570       }
10571       addedActionItemIe = (RICaction_AddedForModification_ItemIEs_t*)addedActionList->list.array[arrIdx];
10572       addedActionItemIe->id = ProtocolIE_IDE2_id_RICaction_AddedForModification_Item;
10573       addedActionItemIe->criticality = CriticalityE2_ignore;
10574       addedActionItemIe->value.present = RICaction_AddedForModification_ItemIEs__value_PR_RICaction_AddedForModification_Item;
10575       addedActionItemIe->value.choice.RICaction_AddedForModification_Item.ricActionID = actionAdded[arrIdx];
10576    }
10577    return ROK;
10578 }
10579
10580 /*******************************************************************
10581 *
10582 * @brief Build Ric subscription action modified list
10583 *
10584 * @details
10585 *
10586 *    Function : BuildActionModifiedList
10587 *
10588 *    Functionality: Build Ric subs action modified list
10589 *
10590 * @params[in]
10591 *    RICactions_ModifiedForModification_List_t to be filled
10592 *    Num Of Action modified
10593 *    Action modified list
10594 *
10595 * @return ROK     - success
10596 *         RFAILED - failure
10597 *
10598 ******************************************************************/
10599
10600 uint8_t BuildActionModifiedList(RICactions_ModifiedForModification_List_t *modifiedActionList, uint8_t numOfActionModified, uint8_t *actionModified)
10601 {
10602    uint8_t arrIdx=0;
10603    RICaction_ModifiedForModification_ItemIEs_t *modifiedActionItemIe =NULLP;
10604
10605    modifiedActionList->list.count = numOfActionModified;
10606    modifiedActionList->list.size = modifiedActionList->list.count *  sizeof(RICaction_ModifiedForModification_ItemIEs_t*);
10607    DU_ALLOC(modifiedActionList->list.array, modifiedActionList->list.size);
10608    if(!modifiedActionList->list.array)
10609    {
10610       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
10611       return RFAILED;
10612    }
10613
10614    for(arrIdx = 0; arrIdx< modifiedActionList->list.count; arrIdx++)
10615    {
10616       DU_ALLOC(modifiedActionList->list.array[arrIdx], sizeof(RICaction_ModifiedForModification_ItemIEs_t));
10617       if(!modifiedActionList->list.array[arrIdx])
10618       {
10619          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
10620          return RFAILED;
10621       }
10622       modifiedActionItemIe = (RICaction_ModifiedForModification_ItemIEs_t*)modifiedActionList->list.array[arrIdx];
10623       modifiedActionItemIe->id = ProtocolIE_IDE2_id_RICaction_ModifiedForModification_Item;
10624       modifiedActionItemIe->criticality = CriticalityE2_ignore;
10625       modifiedActionItemIe->value.present = RICaction_ModifiedForModification_ItemIEs__value_PR_RICaction_ModifiedForModification_Item;
10626       modifiedActionItemIe->value.choice.RICaction_ModifiedForModification_Item.ricActionID = actionModified[arrIdx];
10627    }
10628    return ROK;
10629 }
10630
10631 /*******************************************************************
10632  *
10633  * @brief Build Ric subscription action failed to be removed list
10634  *
10635  * @details
10636  *
10637  *    Function : BuildActionFailedToBeRemovedList
10638  *
10639  *    Functionality: Build Ric subs action failed to be removed list
10640  *
10641  * @params[in]
10642  *    RICactions_FailedToBeRemovedForModification_List_t to be filled
10643  *    Num Of Action failed to be removed
10644  *    Action failed to be removed list
10645  *
10646  * @return ROK     - success
10647  *         RFAILED - failure
10648  *
10649  ******************************************************************/
10650
10651 uint8_t BuildActionFailedToBeRemovedList(RICactions_FailedToBeRemovedForModification_List_t *failedToBeRemovedActionList,\
10652 uint8_t numOfActionFailedToBeRemoved, RejectedAction *actionFailedToBeRemoved)
10653 {
10654    uint8_t arrIdx=0;
10655    RICaction_FailedToBeRemovedForModification_ItemIEs_t *failedToBeRemovedActionItemIe =NULLP;
10656
10657    failedToBeRemovedActionList->list.count = numOfActionFailedToBeRemoved;
10658    failedToBeRemovedActionList->list.size = failedToBeRemovedActionList->list.count *  sizeof(RICaction_FailedToBeRemovedForModification_ItemIEs_t*);
10659    DU_ALLOC(failedToBeRemovedActionList->list.array, failedToBeRemovedActionList->list.size);
10660    if(!failedToBeRemovedActionList->list.array)
10661    {
10662       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
10663       return RFAILED;
10664    }
10665
10666    for(arrIdx = 0; arrIdx< failedToBeRemovedActionList->list.count; arrIdx++)
10667    {
10668       DU_ALLOC(failedToBeRemovedActionList->list.array[arrIdx], sizeof(RICaction_FailedToBeRemovedForModification_ItemIEs_t));
10669       if(!failedToBeRemovedActionList->list.array[arrIdx])
10670       {
10671          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
10672          return RFAILED;
10673       }
10674       failedToBeRemovedActionItemIe = (RICaction_FailedToBeRemovedForModification_ItemIEs_t*)failedToBeRemovedActionList->list.array[arrIdx];
10675       failedToBeRemovedActionItemIe->id = ProtocolIE_IDE2_id_RICaction_FailedToBeRemovedForModification_Item;
10676       failedToBeRemovedActionItemIe->criticality = CriticalityE2_ignore;
10677       failedToBeRemovedActionItemIe->value.present = RICaction_FailedToBeRemovedForModification_ItemIEs__value_PR_RICaction_FailedToBeRemovedForModification_Item;
10678       failedToBeRemovedActionItemIe->value.choice.RICaction_FailedToBeRemovedForModification_Item.ricActionID = actionFailedToBeRemoved[arrIdx].id;
10679       fillE2Cause(&failedToBeRemovedActionItemIe->value.choice.RICaction_FailedToBeRemovedForModification_Item.cause, actionFailedToBeRemoved[arrIdx].failureCause);
10680    }
10681    return ROK;
10682 }
10683
10684 /*******************************************************************
10685  *
10686  * @brief Build Ric subscription action failed to be modified list
10687  *
10688  * @details
10689  *
10690  *    Function : BuildActionFailedToBeModifiedList
10691  *
10692  *    Functionality: Build Ric subs action failed to be modified list
10693  *
10694  * @params[in]
10695  *    RICactions_FailedToBeModifiedForModification_List_t to be filled
10696  *    Num Of Action failed to be modified
10697  *    Action failed to be modified list
10698  *
10699  * @return ROK     - success
10700  *         RFAILED - failure
10701  *
10702  ******************************************************************/
10703
10704 uint8_t BuildActionFailedToBeModifiedList(RICactions_FailedToBeModifiedForModification_List_t *failedToBeModifiedActionList,\
10705 uint8_t numOfActionFailedToBeModified, RejectedAction *actionFailedToBeModified)
10706 {
10707    uint8_t arrIdx=0;
10708    RICaction_FailedToBeModifiedForModification_ItemIEs_t *failedToBeModifiedActionItemIe =NULLP;
10709
10710    failedToBeModifiedActionList->list.count = numOfActionFailedToBeModified;
10711    failedToBeModifiedActionList->list.size = failedToBeModifiedActionList->list.count *  sizeof(RICaction_FailedToBeModifiedForModification_ItemIEs_t*);
10712    DU_ALLOC(failedToBeModifiedActionList->list.array, failedToBeModifiedActionList->list.size);
10713    if(!failedToBeModifiedActionList->list.array)
10714    {
10715       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
10716       return RFAILED;
10717    }
10718
10719    for(arrIdx = 0; arrIdx< failedToBeModifiedActionList->list.count; arrIdx++)
10720    {
10721       DU_ALLOC(failedToBeModifiedActionList->list.array[arrIdx], sizeof(RICaction_FailedToBeModifiedForModification_ItemIEs_t));
10722       if(!failedToBeModifiedActionList->list.array[arrIdx])
10723       {
10724          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
10725          return RFAILED;
10726       }
10727       failedToBeModifiedActionItemIe = (RICaction_FailedToBeModifiedForModification_ItemIEs_t*)failedToBeModifiedActionList->list.array[arrIdx];
10728       failedToBeModifiedActionItemIe->id = ProtocolIE_IDE2_id_RICaction_FailedToBeModifiedForModification_Item;
10729       failedToBeModifiedActionItemIe->criticality = CriticalityE2_ignore;
10730       failedToBeModifiedActionItemIe->value.present = RICaction_FailedToBeModifiedForModification_ItemIEs__value_PR_RICaction_FailedToBeModifiedForModification_Item;
10731       failedToBeModifiedActionItemIe->value.choice.RICaction_FailedToBeModifiedForModification_Item.ricActionID = actionFailedToBeModified[arrIdx].id;
10732       fillE2Cause(&failedToBeModifiedActionItemIe->value.choice.RICaction_FailedToBeModifiedForModification_Item.cause, actionFailedToBeModified[arrIdx].failureCause);
10733    }
10734    return ROK;
10735 }
10736
10737 /*******************************************************************
10738  *
10739  * @brief Build Ric subscription action failed to be added list
10740  *
10741  * @details
10742  *
10743  *    Function : BuildActionFailedToBeAddedList
10744  *
10745  *    Functionality: Build Ric subs action failed to be added list
10746  *
10747  * @params[in]
10748  *    RICactions_FailedToBeAddedForModification_List_t to be filled
10749  *    Num Of Action failed to be added
10750  *    Action failed to be added list
10751  *
10752  * @return ROK     - success
10753  *         RFAILED - failure
10754  *
10755  ******************************************************************/
10756
10757 uint8_t BuildActionFailedToBeAddedList(RICactions_FailedToBeAddedForModification_List_t *failedToBeAddedActionList, uint8_t numOfActionFailedToBeAdded, RejectedAction *actionFailedToBeAdded)
10758 {
10759    uint8_t arrIdx=0;
10760    RICaction_FailedToBeAddedForModification_ItemIEs_t *failedToBeAddedActionItemIe =NULLP;
10761
10762    failedToBeAddedActionList->list.count = numOfActionFailedToBeAdded;
10763    failedToBeAddedActionList->list.size = failedToBeAddedActionList->list.count *  sizeof(RICaction_FailedToBeAddedForModification_ItemIEs_t*);
10764    DU_ALLOC(failedToBeAddedActionList->list.array, failedToBeAddedActionList->list.size);
10765    if(!failedToBeAddedActionList->list.array)
10766    {
10767       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
10768       return RFAILED;
10769    }
10770
10771    for(arrIdx = 0; arrIdx< failedToBeAddedActionList->list.count; arrIdx++)
10772    {
10773       DU_ALLOC(failedToBeAddedActionList->list.array[arrIdx], sizeof(RICaction_FailedToBeAddedForModification_ItemIEs_t));
10774       if(!failedToBeAddedActionList->list.array[arrIdx])
10775       {
10776          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
10777          return RFAILED;
10778       }
10779       failedToBeAddedActionItemIe = (RICaction_FailedToBeAddedForModification_ItemIEs_t*)failedToBeAddedActionList->list.array[arrIdx];
10780       failedToBeAddedActionItemIe->id = ProtocolIE_IDE2_id_RICaction_FailedToBeAddedForModification_Item;
10781       failedToBeAddedActionItemIe->criticality = CriticalityE2_ignore;
10782       failedToBeAddedActionItemIe->value.present = RICaction_FailedToBeAddedForModification_ItemIEs__value_PR_RICaction_FailedToBeAddedForModification_Item;
10783       failedToBeAddedActionItemIe->value.choice.RICaction_FailedToBeAddedForModification_Item.ricActionID = actionFailedToBeAdded[arrIdx].id;
10784       fillE2Cause(&failedToBeAddedActionItemIe->value.choice.RICaction_FailedToBeAddedForModification_Item.cause, actionFailedToBeAdded[arrIdx].failureCause);
10785    }
10786    return ROK;
10787 }
10788
10789 /*******************************************************************
10790  *
10791  * @brief Builds and Send RIC Subscription Modification Response
10792  *
10793  * @details
10794  *
10795  *    Function : BuildAndSendRicSubscriptionModificationResponse
10796  *
10797  * Functionality: Build and send RIC Subscription Modification Response.
10798  *
10799  * @params[in]
10800  *          PendingSubsModRspInfo
10801  * @return ROK     - success
10802  *         RFAILED - failure
10803  *
10804  ******************************************************************/
10805 uint8_t BuildAndSendRicSubscriptionModificationResponse(PendingSubsModRspInfo *pendingSubsModRsp)
10806 {
10807    uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED;
10808    E2AP_PDU_t         *e2apMsg = NULLP;
10809    RICsubscriptionModificationResponse_t *ricSubsModResponse = NULLP;
10810    RICsubscriptionModificationResponse_IEs_t *ricSubsModResponseIe = NULLP;
10811    asn_enc_rval_t     encRetVal;        /* Encoder return value */
10812
10813    while(true)
10814    {
10815       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Response Message\n");
10816
10817       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
10818       if(e2apMsg == NULLP)
10819       {
10820          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
10821          break;
10822       }
10823
10824       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
10825       DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
10826       if(e2apMsg->choice.successfulOutcome == NULLP)
10827       {
10828          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
10829          break;
10830       }
10831       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionModification;
10832       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
10833       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICsubscriptionModificationResponse;
10834
10835
10836       ricSubsModResponse = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationResponse;
10837
10838       elementCnt = 2;
10839       if(pendingSubsModRsp->removeActionStatus.numOfAcceptedActions)
10840          elementCnt++;
10841       if(pendingSubsModRsp->addActionStatus.numOfAcceptedActions)
10842          elementCnt++;
10843       if(pendingSubsModRsp->modActionStatus.numOfAcceptedActions)
10844          elementCnt++;
10845       if(pendingSubsModRsp->removeActionStatus.numOfRejectedActions)
10846          elementCnt++;
10847       if(pendingSubsModRsp->addActionStatus.numOfRejectedActions)
10848          elementCnt++;
10849       if(pendingSubsModRsp->modActionStatus.numOfRejectedActions)
10850          elementCnt++;
10851
10852       ricSubsModResponse->protocolIEs.list.count = elementCnt;
10853       ricSubsModResponse->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationResponse_IEs_t *);
10854
10855       DU_ALLOC(ricSubsModResponse->protocolIEs.list.array, ricSubsModResponse->protocolIEs.list.size);
10856       if(ricSubsModResponse->protocolIEs.list.array == NULLP)
10857       {
10858          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
10859          break;
10860       }
10861
10862       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
10863       {
10864          DU_ALLOC(ricSubsModResponse->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationResponse_IEs_t));
10865          if(ricSubsModResponse->protocolIEs.list.array[ieIdx] == NULLP)
10866          {
10867             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
10868             break;
10869          }
10870       }
10871       if(ieIdx < elementCnt)
10872          break;
10873
10874       ieIdx = 0;
10875       ricSubsModResponseIe = ricSubsModResponse->protocolIEs.list.array[ieIdx];
10876       ricSubsModResponseIe->id = ProtocolIE_IDE2_id_RICrequestID;
10877       ricSubsModResponseIe->criticality = CriticalityE2_reject;
10878       ricSubsModResponseIe->value.present = RICsubscriptionModificationResponse_IEs__value_PR_RICrequestID;
10879       ricSubsModResponseIe->value.choice.RICrequestID.ricRequestorID= pendingSubsModRsp->requestId.requestorId;
10880       ricSubsModResponseIe->value.choice.RICrequestID.ricInstanceID = pendingSubsModRsp->requestId.instanceId;
10881
10882       ieIdx++;
10883       ricSubsModResponseIe = ricSubsModResponse->protocolIEs.list.array[ieIdx];
10884       ricSubsModResponseIe->id = ProtocolIE_IDE2_id_RANfunctionID;
10885       ricSubsModResponseIe->criticality = CriticalityE2_reject;
10886       ricSubsModResponseIe->value.present = RICsubscriptionModificationResponse_IEs__value_PR_RANfunctionID;
10887       ricSubsModResponseIe->value.choice.RANfunctionID = pendingSubsModRsp->ranFuncId;
10888
10889       if(pendingSubsModRsp->removeActionStatus.numOfAcceptedActions)
10890       {
10891          ieIdx++;
10892          ricSubsModResponseIe = ricSubsModResponse->protocolIEs.list.array[ieIdx];
10893          ricSubsModResponseIe->id = ProtocolIE_IDE2_id_RICactionsRemovedForModification_List;
10894          ricSubsModResponseIe->criticality = CriticalityE2_ignore;
10895          ricSubsModResponseIe->value.present = RICsubscriptionModificationResponse_IEs__value_PR_RICactions_RemovedForModification_List;
10896          if(BuildActionRemovedList(&ricSubsModResponseIe->value.choice.RICactions_RemovedForModification_List,\
10897          pendingSubsModRsp->removeActionStatus.numOfAcceptedActions, pendingSubsModRsp->removeActionStatus.acceptedActionList) != ROK)
10898          {
10899             DU_LOG("\nERROR  -->  E2AP : failed at [%s] : line [%d]", __func__, __LINE__);
10900             break;
10901          }
10902       }
10903
10904       if(pendingSubsModRsp->removeActionStatus.numOfRejectedActions)
10905       {
10906          ieIdx++;
10907          ricSubsModResponseIe = ricSubsModResponse->protocolIEs.list.array[ieIdx];
10908          ricSubsModResponseIe->id = ProtocolIE_IDE2_id_RICactionsFailedToBeRemovedForModification_List;
10909          ricSubsModResponseIe->criticality = CriticalityE2_ignore;
10910          ricSubsModResponseIe->value.present = RICsubscriptionModificationResponse_IEs__value_PR_RICactions_FailedToBeRemovedForModification_List;
10911          if(BuildActionFailedToBeRemovedList(&ricSubsModResponseIe->value.choice.RICactions_FailedToBeRemovedForModification_List,\
10912          pendingSubsModRsp->removeActionStatus.numOfRejectedActions, pendingSubsModRsp->removeActionStatus.rejectedActionList) != ROK)
10913          {
10914             DU_LOG("\nERROR  -->  E2AP : failed at [%s] : line [%d]", __func__, __LINE__);
10915             break;
10916          }
10917       }
10918  
10919       if(pendingSubsModRsp->modActionStatus.numOfAcceptedActions)
10920       {
10921          ieIdx++;
10922          ricSubsModResponseIe = ricSubsModResponse->protocolIEs.list.array[ieIdx];
10923          ricSubsModResponseIe->id = ProtocolIE_IDE2_id_RICactionsModifiedForModification_List;
10924          ricSubsModResponseIe->criticality = CriticalityE2_ignore;
10925          ricSubsModResponseIe->value.present = RICsubscriptionModificationResponse_IEs__value_PR_RICactions_ModifiedForModification_List;
10926          if(BuildActionModifiedList(&ricSubsModResponseIe->value.choice.RICactions_ModifiedForModification_List,\
10927          pendingSubsModRsp->modActionStatus.numOfAcceptedActions, pendingSubsModRsp->modActionStatus.acceptedActionList) != ROK)
10928          {
10929             DU_LOG("\nERROR  -->  E2AP : failed at [%s] : line [%d]", __func__, __LINE__);
10930             break;
10931          }
10932       }
10933
10934       if(pendingSubsModRsp->modActionStatus.numOfRejectedActions)
10935       {
10936          ieIdx++;
10937          ricSubsModResponseIe = ricSubsModResponse->protocolIEs.list.array[ieIdx];
10938          ricSubsModResponseIe->id = ProtocolIE_IDE2_id_RICactionsFailedToBeModifiedForModification_List;
10939          ricSubsModResponseIe->criticality = CriticalityE2_ignore;
10940          ricSubsModResponseIe->value.present = RICsubscriptionModificationResponse_IEs__value_PR_RICactions_FailedToBeModifiedForModification_List;
10941          if(BuildActionFailedToBeModifiedList(&ricSubsModResponseIe->value.choice.RICactions_FailedToBeModifiedForModification_List,\
10942          pendingSubsModRsp->modActionStatus.numOfRejectedActions, pendingSubsModRsp->modActionStatus.rejectedActionList) != ROK)
10943          {
10944             DU_LOG("\nERROR  -->  E2AP : failed at [%s] : line [%d]", __func__, __LINE__);
10945             break;
10946          }
10947       }
10948
10949       if(pendingSubsModRsp->addActionStatus.numOfAcceptedActions)
10950       {
10951          ieIdx++;
10952          ricSubsModResponseIe = ricSubsModResponse->protocolIEs.list.array[ieIdx];
10953          ricSubsModResponseIe->id = ProtocolIE_IDE2_id_RICactionsAddedForModification_List;
10954          ricSubsModResponseIe->criticality = CriticalityE2_ignore;
10955          ricSubsModResponseIe->value.present = RICsubscriptionModificationResponse_IEs__value_PR_RICactions_AddedForModification_List;
10956          if(BuildActionAddedList(&ricSubsModResponseIe->value.choice.RICactions_AddedForModification_List,\
10957          pendingSubsModRsp->addActionStatus.numOfAcceptedActions, pendingSubsModRsp->addActionStatus.acceptedActionList) != ROK)
10958          {
10959             DU_LOG("\nERROR  -->  E2AP : failed at [%s] : line [%d]", __func__, __LINE__);
10960             break;
10961          }
10962       }
10963
10964       if(pendingSubsModRsp->addActionStatus.numOfRejectedActions)
10965       {
10966          ieIdx++;
10967          ricSubsModResponseIe = ricSubsModResponse->protocolIEs.list.array[ieIdx];
10968          ricSubsModResponseIe->id = ProtocolIE_IDE2_id_RICactionsFailedToBeAddedForModification_List;
10969          ricSubsModResponseIe->criticality = CriticalityE2_ignore;
10970          ricSubsModResponseIe->value.present = RICsubscriptionModificationResponse_IEs__value_PR_RICactions_FailedToBeAddedForModification_List;
10971          if(BuildActionFailedToBeAddedList(&ricSubsModResponseIe->value.choice.RICactions_FailedToBeAddedForModification_List,\
10972          pendingSubsModRsp->addActionStatus.numOfRejectedActions, pendingSubsModRsp->addActionStatus.rejectedActionList) != ROK)
10973          {
10974             DU_LOG("\nERROR  -->  E2AP : failed at [%s] : line [%d]", __func__, __LINE__);
10975             break;
10976          }
10977       }
10978
10979       /* Prints the Msg formed */
10980       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
10981       memset(encBuf, 0, ENC_BUF_MAX_LEN);
10982       encBufSize = 0;
10983       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
10984       if(encRetVal.encoded == ENCODE_FAIL)
10985       {
10986          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Modification Response Message (at %s)\n",\
10987                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
10988          break;
10989       }
10990       else
10991       {
10992          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Modification Response Message \n");
10993 #ifdef DEBUG_ASN_PRINT
10994          for(int i=0; i< encBufSize; i++)
10995          {
10996             printf("%x",encBuf[i]);
10997          }
10998 #endif
10999       }
11000
11001       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
11002       {
11003          DU_LOG("\nERROR   -->  E2AP : Failed to send RIC Susbcription Modification Response Message");
11004          break;
11005       }
11006
11007       ret = ROK;
11008       break;
11009    }
11010
11011    FreeRicSubscriptionModificationResponse(e2apMsg);
11012    return ret;
11013 }
11014
11015 /*******************************************************************
11016  *
11017  * @brief Handles received E2AP message and sends back response  
11018  *
11019  * @details
11020  *
11021  *    Function : E2APMsgHdlr
11022  *
11023  *    Functionality:
11024  *         - Decodes received E2AP control message
11025  *         - Prepares response message, encodes and sends to SCTP
11026  *
11027  * @params[in] 
11028  * @return ROK     - success
11029  *         RFAILED - failure
11030  *
11031  * ****************************************************************/
11032 void E2APMsgHdlr(Buffer *mBuf)
11033 {
11034    int i =0;
11035    char *recvBuf = NULLP;
11036    MsgLen copyCnt =0;
11037    MsgLen recvBufLen =0;
11038    E2AP_PDU_t *e2apMsg = NULLP;
11039    asn_dec_rval_t rval ={0}; /* Decoder return value */
11040    E2AP_PDU_t e2apasnmsg={0} ;
11041
11042    DU_LOG("\nDEBUG   -->  E2AP : Received E2AP message buffer");
11043    ODU_PRINT_MSG(mBuf, 0,0);
11044
11045    /* Copy mBuf into char array to decode it */
11046    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
11047    DU_ALLOC(recvBuf, (Size)recvBufLen);
11048
11049    if(recvBuf == NULLP)
11050    {
11051       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
11052       return;
11053    }
11054    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
11055    {
11056       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
11057       return;
11058    }
11059
11060 #ifdef DEBUG_ASN_PRINT
11061    printf("\nDEBUG   -->  E2AP : Received flat buffer to be decoded : ");
11062    for(i=0; i< recvBufLen; i++)
11063    {
11064       printf("%x",recvBuf[i]);
11065    }
11066 #endif
11067
11068    /* Decoding flat buffer into E2AP messsage */
11069    e2apMsg = &e2apasnmsg;
11070    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
11071
11072    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
11073    DU_FREE(recvBuf, (Size)recvBufLen);
11074
11075    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
11076    {
11077       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
11078       return;
11079    }
11080    printf("\n");
11081    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
11082
11083    switch(e2apMsg->present)
11084    {
11085       case E2AP_PDU_PR_unsuccessfulOutcome:
11086          {
11087             switch(e2apMsg->choice.unsuccessfulOutcome->value.present)
11088             {
11089                case UnsuccessfulOutcomeE2__value_PR_E2setupFailure:
11090                   {
11091                      procE2SetupFailure(e2apMsg);
11092                      break;
11093                   }
11094                case UnsuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateFailure:
11095                   {
11096                      procE2NodeConfigUpdateFailure(e2apMsg);
11097                      break;
11098                   }
11099                case UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure:
11100                   {
11101                      procRicServiceUpdateFailure(e2apMsg);
11102                      break;
11103                   }
11104                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionModificationRefuse:
11105                   {
11106                      procRicSubscriptionModificationRefuse(e2apMsg);
11107                      break;
11108                   }
11109                case UnsuccessfulOutcomeE2__value_PR_E2RemovalFailure:
11110                   {
11111                      ProcE2RemovalFailure(e2apMsg);
11112                      break;
11113                   }
11114                default:
11115                   {
11116                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome  [%d]",\
11117                            e2apMsg->choice.unsuccessfulOutcome->value.present);
11118                      return;
11119                   }
11120             }
11121             free(e2apMsg->choice.unsuccessfulOutcome);
11122             break;
11123          }
11124       case E2AP_PDU_PR_successfulOutcome:
11125          {
11126             switch(e2apMsg->choice.successfulOutcome->value.present)
11127             {
11128                case SuccessfulOutcomeE2__value_PR_E2setupResponse:
11129                   {
11130                      if(!duCb.e2Status)
11131                      {
11132                         procE2SetupRsp(e2apMsg);
11133                      }
11134                      break;
11135                   }
11136                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
11137                   {
11138                      procResetResponse(e2apMsg);
11139                      break;
11140                   }
11141                case SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge:
11142                   {
11143                      procRicServiceUpdateAck(e2apMsg);
11144                      break;
11145                   }
11146                case SuccessfulOutcomeE2__value_PR_RICsubscriptionModificationConfirm:
11147                   {
11148                      procRicSubscriptionModificationConfirm(e2apMsg);
11149                      break;
11150                   }
11151                case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge:
11152                   {
11153                      procE2NodeConfigUpdateAck(e2apMsg);
11154                      break;
11155                   }
11156                case SuccessfulOutcomeE2__value_PR_E2RemovalResponse:
11157                   {
11158                      ProcE2RemovalResponse(e2apMsg);
11159                      break;
11160                   }
11161                default:
11162                   {
11163                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome  [%d]",\
11164                            e2apMsg->choice.successfulOutcome->value.present);
11165                      return;
11166                   }
11167             }/* End of switch(successfulOutcome) */
11168             free(e2apMsg->choice.successfulOutcome);
11169             break;
11170          }
11171
11172       case E2AP_PDU_PR_initiatingMessage:
11173          {
11174             switch(e2apMsg->choice.initiatingMessage->value.present)
11175             {
11176                case InitiatingMessageE2__value_PR_RICsubscriptionRequest: 
11177                   {
11178                      procRicSubscriptionRequest(e2apMsg);
11179                      break;
11180                   }
11181                case InitiatingMessageE2__value_PR_RICserviceQuery:
11182                   {
11183                      procRicServiceQuery(e2apMsg);
11184                      break;
11185                   }
11186                case InitiatingMessageE2__value_PR_ErrorIndicationE2:
11187                   {
11188                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
11189                      break;
11190                   }
11191                case InitiatingMessageE2__value_PR_ResetRequestE2:
11192                   {
11193                      DU_LOG("\nINFO  -->  E2AP : Reset request received");
11194                      procE2ResetRequest(e2apMsg);
11195                      break;
11196                   }
11197                case InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequest:
11198                   {
11199                      DU_LOG("\nINFO  -->  E2AP : RIC Subscription Delete Request received");
11200                      procRicSubscriptionDeleteRequest(e2apMsg);
11201                      break;
11202                   }
11203                case InitiatingMessageE2__value_PR_E2RemovalRequest:
11204                   {
11205                      DU_LOG("\nINFO  -->  E2AP : E2 Removal request received");
11206                      procE2RemovalRequest(e2apMsg);
11207                      break;
11208                   }
11209                case InitiatingMessageE2__value_PR_E2connectionUpdate:
11210                   {
11211                      DU_LOG("\nINFO  -->  E2AP : E2 coneection update received");
11212                      procE2ConnectionUpdate(e2apMsg);
11213                      break;
11214                   }
11215                case InitiatingMessageE2__value_PR_RICsubscriptionModificationRequest:
11216                   {
11217                      DU_LOG("\nINFO  -->  E2AP : RIC Subscription Modification Request received");
11218                      procRicSubscriptionModificationRequest(e2apMsg);
11219                      break;
11220                   }
11221                default:
11222                   {
11223                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\
11224                            e2apMsg->choice.initiatingMessage->value.present);
11225                      return;
11226                   }
11227             }/* End of switch(initiatingMessage) */
11228             free(e2apMsg->choice.initiatingMessage);
11229             break;
11230          }
11231       default:
11232          {
11233             DU_LOG("\nERROR  -->  E2AP : Invalid type of e2apMsg->present [%d]",e2apMsg->present);
11234             return;
11235          }
11236          free(e2apMsg);
11237
11238    }/* End of switch(e2apMsg->present) */
11239
11240 } /* End of E2APMsgHdlr */
11241
11242 /**********************************************************************
11243   End of file
11244  **********************************************************************/