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