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