bddc73b8161e1216ed08b26191f4a3c4c1fb2b2a
[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 Extract RIC Action to be setup
3250  *
3251  * @details
3252  *
3253  *    Function : extractRicActionToBeSetup
3254  *
3255  * Functionality : This function :
3256  *     - Validates that each action-to-be-setup is supported by E2 node
3257  *     - Stores event trigger details in local DB
3258  *
3259  * @params[in] RAN Function Database structure
3260  *             RIC Subscription Info to be added to RAN function
3261  *             RIC Action To Be Setup List received from RIC
3262  * @return ROK     - success
3263  *         RFAILED - failure
3264  *
3265  ******************************************************************/
3266 uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \
3267    RICactions_ToBeSetup_List_t *actionList, E2FailureCause *failureCause, PendingSubsRspInfo *subsRsp)
3268 {
3269    uint8_t actionIdx = 0;
3270    uint8_t ricActionId = 0;
3271    RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
3272
3273    if(actionList->list.array)
3274    {
3275       for(actionIdx = 0; actionIdx < actionList->list.count; actionIdx++)
3276       {
3277          actionItem =(RICaction_ToBeSetup_ItemIEs_t *)actionList->list.array[actionIdx];
3278          switch(actionItem->id)
3279          {
3280             case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item:
3281                {
3282                   /* If Action type is REPORT and 
3283                    * If RIC action definition's extraction and validation passes, 
3284                    * Then : 
3285                    * This action is added to action sequence list of subscription info */
3286                   ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
3287
3288                   if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType == RICactionType_report)
3289                   {
3290                      ricSubscriptionInfo->actionSequence[ricActionId].actionId = ricActionId;
3291                      ricSubscriptionInfo->actionSequence[ricActionId].type = REPORT;
3292
3293                      if(extractRicActionDef(ranFuncDb, &ricSubscriptionInfo->actionSequence[ricActionId].definition, \
3294                         actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, failureCause) == ROK)
3295                      {
3296                         ricSubscriptionInfo->actionSequence[ricActionId].action = CONFIG_ADD;
3297                         ricSubscriptionInfo->numOfActions++;
3298                         break;
3299                      }
3300                   }
3301
3302                   /* In case of any failure, action is rejected
3303                    * Added to rejected-action-list in subscription response */
3304                   deleteActionSequence(&ricSubscriptionInfo->actionSequence[ricActionId]);
3305
3306                   subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].id = ricActionId;
3307                   if(failureCause->causeType == E2_NOTHING)
3308                   {
3309                      failureCause->causeType = E2_RIC_REQUEST;
3310                      failureCause->cause = E2_ACTION_NOT_SUPPORTED;
3311                   }
3312                   memcpy(&subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].failureCause, \
3313                         failureCause, sizeof(E2FailureCause));
3314                   subsRsp->numOfRejectedActions++;
3315                   break;
3316                }
3317             default:
3318                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id);
3319                break;
3320          }
3321       }
3322    }
3323
3324    /* If there is even 1 action that can be added, return ROK */
3325    if(ricSubscriptionInfo->numOfActions)
3326       return ROK;
3327
3328    if(failureCause->causeType == E2_NOTHING)
3329    {
3330       failureCause->causeType = E2_RIC_REQUEST;
3331       failureCause->cause = E2_ACTION_NOT_SUPPORTED;
3332    }
3333    return RFAILED;
3334 }
3335
3336 /******************************************************************
3337  *
3338  * @brief Processes RIC Subscription Req sent by RIC
3339  *
3340  * @details
3341  *
3342  *    Function : procRicSubscriptionRequest
3343  *
3344  *    Functionality: Processes RIC Subscription Request from RIC
3345  *
3346  * @params[in] E2AP_PDU_t ASN decoded E2AP message
3347  * @return ROK     - success
3348  *         RFAILED - failure
3349  *
3350  * ****************************************************************/
3351 uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg)
3352 {
3353    uint8_t idx = 0, actionIdx = 0; 
3354    uint8_t ret = ROK;
3355    uint16_t ranFuncId = 0;
3356    RicRequestId ricReqId;
3357    CmLList  *ricSubscriptionNode = NULLP;
3358    RanFunction *ranFuncDb = NULLP;
3359    RICsubscriptionRequest_t *ricSubsReq = NULLP;
3360    RICsubscriptionDetails_t *subsDetails = NULLP;
3361    RicSubscription *ricSubscriptionInfo = NULLP;
3362    E2FailureCause failureCause;
3363
3364    DU_LOG("\nINFO   -->  E2AP : RIC Subscription request received"); 
3365
3366    memset(&failureCause, 0, sizeof(E2FailureCause));
3367    memset(&ricReqId, 0, sizeof(RicRequestId));
3368
3369    ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
3370    for(idx=0; idx<ricSubsReq->protocolIEs.list.count; idx++)
3371    {
3372       if(ricSubsReq->protocolIEs.list.array[idx])
3373       {
3374          switch(ricSubsReq->protocolIEs.list.array[idx]->id)
3375          {
3376             case ProtocolIE_IDE2_id_RICrequestID:
3377                {
3378                   ricReqId.requestorId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID;
3379                   ricReqId.instanceId  = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID;
3380
3381                   break;
3382                }
3383
3384             case ProtocolIE_IDE2_id_RANfunctionID:
3385                {
3386                   ranFuncId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID; 
3387
3388                   /* Validating RAN Function id */
3389                   ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
3390
3391                   if(!ranFuncDb)
3392                   {
3393                      failureCause.causeType = E2_RIC_REQUEST;
3394                      failureCause.cause = E2_RAN_FUNCTION_ID_INVALID;
3395                      ret = RFAILED;
3396                      break;
3397                   }
3398
3399                   if(ranFuncDb->numPendingSubsRsp >= MAX_PENDING_SUBSCRIPTION_RSP)
3400                   {
3401                      failureCause.causeType = E2_RIC_REQUEST;
3402                      failureCause.cause = E2_FUNCTION_RESOURCE_LIMIT; 
3403                      ret = RFAILED;
3404                      break;
3405                   }
3406
3407                   DU_ALLOC(ricSubscriptionInfo, sizeof(RicSubscription));
3408                   if(!ricSubscriptionInfo)
3409                   {
3410                      DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for ricSubscriptionInfo");
3411                      failureCause.causeType = E2_MISCELLANEOUS;
3412                      failureCause.cause = E2_MISCELLANEOUS_CAUSE_UNSPECIFIED;
3413                      ret = RFAILED;
3414                      break;
3415                   }
3416                   ricSubscriptionInfo->requestId.requestorId = ricReqId.requestorId;
3417                   ricSubscriptionInfo->requestId.instanceId = ricReqId.instanceId;
3418                   ricSubscriptionInfo->ranFuncId = ranFuncId;
3419
3420                   for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
3421                   {
3422                      ricSubscriptionInfo->actionSequence[actionIdx].actionId = -1;
3423                   }
3424
3425                   memset(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp], 0, sizeof(PendingSubsRspInfo));
3426                   memcpy(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp].requestId, 
3427                         &ricReqId, sizeof(RicRequestId));
3428                   ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp].ranFuncId = ranFuncId;
3429                   break;
3430                }
3431
3432             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
3433                {
3434                   subsDetails = &ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails;
3435
3436                   /* Decode, Validate and record Event Trigger Definition */
3437                   if(extractEventTriggerDef(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricEventTriggerDefinition, \
3438                      &failureCause) != ROK)
3439                   {
3440                      ret = RFAILED;
3441                      break;
3442                   }
3443
3444                   /* Decode, Validate and record RIC actions */
3445                   if(extractRicActionToBeSetup(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricAction_ToBeSetup_List, \
3446                      &failureCause, &ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp]) != ROK)
3447                   {
3448                      ret = RFAILED;
3449                      break;
3450                   }
3451                }
3452                break;
3453
3454             default:
3455                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RIC SubsReq:%ld",
3456                      ricSubsReq->protocolIEs.list.array[idx]->id);
3457                break;
3458          }
3459
3460          if(ret == RFAILED)
3461             break;
3462       }
3463    }
3464
3465    freeAperDecodingOfRicSubsReq(ricSubsReq);
3466
3467    if(ret == ROK)
3468    {
3469       cmInitTimers(&(ricSubscriptionInfo->ricSubsReportTimer), 1);
3470       ricSubscriptionInfo->action = CONFIG_ADD;
3471
3472       /* Add RAN subcription detail to RAN function */
3473       DU_ALLOC(ricSubscriptionNode, sizeof(CmLList));
3474       if(ricSubscriptionNode)
3475       {
3476          ricSubscriptionNode->node = (PTR) ricSubscriptionInfo;
3477          cmLListAdd2Tail(&ranFuncDb->subscriptionList, ricSubscriptionNode);
3478       }
3479
3480       ranFuncDb->numPendingSubsRsp++;
3481
3482 #ifdef KPI_CALCULATION
3483       /* Send statistics request to other DU entities */
3484       BuildAndSendStatsReq(ricSubscriptionInfo);
3485 #endif      
3486    }
3487    else
3488    {
3489       DU_FREE(ricSubscriptionInfo, sizeof(RicSubscription));
3490
3491       if(ranFuncDb)
3492       {
3493          memset(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp], 0, sizeof(PendingSubsRspInfo));
3494       }
3495
3496       /* Send RIC Subcription Failure */
3497       BuildAndSendRicSubscriptionFailure(ricReqId, ranFuncId, failureCause);
3498    }
3499    return ret;
3500 }
3501
3502 /******************************************************************
3503  *
3504  * @brief Free RIC Subscription Failure
3505  *
3506  * @details
3507  *
3508  *    Function : FreeRicSubscriptionFailure
3509  *
3510  *    Functionality: Free RIC Subscription Failure
3511  *
3512  * @params[in] E2AP PDU
3513  * @return void
3514  *
3515  * ****************************************************************/
3516 void FreeRicSubscriptionFailure(E2AP_PDU_t *e2apMsg)
3517 {
3518    uint8_t elemIdx = 0;
3519    RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP;
3520
3521    if(e2apMsg)
3522    {
3523       if(e2apMsg->choice.unsuccessfulOutcome)
3524       {
3525          ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
3526          if(ricSubscriptionFailure->protocolIEs.list.array)
3527          {
3528             for(elemIdx = 0; elemIdx < ricSubscriptionFailure->protocolIEs.list.count; elemIdx++)
3529             {
3530                DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t));
3531             }
3532             DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size);
3533          }
3534          DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
3535       }
3536       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3537    }
3538 }
3539
3540 /******************************************************************
3541  *
3542  * @brief Fill and Send RIC Subscription Failure to RIC
3543  *
3544  * @details
3545  *
3546  *    Function : BuildAndSendRicSubscriptionFailure
3547  *
3548  *    Functionality: Fill and Send RIC Subscription Failure to RIC
3549  *
3550  * @params[in] RIC Request ID
3551  *             RAN Function ID
3552  *             Cause of Failure
3553  * @return ROK     - success
3554  *         RFAILED - failure
3555  *
3556  * ****************************************************************/
3557 uint8_t BuildAndSendRicSubscriptionFailure(RicRequestId ricReqId, uint16_t ranFuncId, E2FailureCause failureCause)
3558 {
3559    uint8_t          ret = RFAILED;
3560    uint8_t          elementCnt = 0, elemIdx = 0;
3561    E2AP_PDU_t       *e2apMsg = NULLP;
3562    asn_enc_rval_t   encRetVal;        /* Encoder return value */
3563    RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP;
3564    RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
3565
3566    while(true)
3567    {
3568       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Failure\n");
3569
3570       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3571       if(e2apMsg == NULLP)
3572       {
3573          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
3574          break;
3575       }
3576
3577       e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome;
3578       DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
3579       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
3580       {
3581          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
3582          break;
3583       }
3584       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
3585       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
3586       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure;
3587
3588       ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
3589
3590       elementCnt = 3;
3591       ricSubscriptionFailure->protocolIEs.list.count = elementCnt;
3592       ricSubscriptionFailure->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionFailure_IEs_t *);
3593       DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size);
3594       if(!ricSubscriptionFailure->protocolIEs.list.array)
3595       {
3596          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
3597          break;
3598       }
3599
3600       for(elemIdx = 0; elemIdx < elementCnt; elemIdx++)
3601       {
3602          DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t));
3603          if(!ricSubscriptionFailure->protocolIEs.list.array[elemIdx])
3604          {
3605             DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d] for IE at index [%d]", \
3606                __func__, __LINE__, elemIdx);
3607             break;
3608          }
3609       }
3610       if(elemIdx < elementCnt)
3611          break;
3612
3613       elemIdx = 0;
3614
3615       /* RIC Request ID */
3616       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
3617       ricSubsFailIe->id = ProtocolIE_IDE2_id_RICrequestID;
3618       ricSubsFailIe->criticality = CriticalityE2_reject;
3619       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RICrequestID;
3620       ricSubsFailIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
3621       ricSubsFailIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
3622
3623       /* RAN Function ID */
3624       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
3625       ricSubsFailIe->id = ProtocolIE_IDE2_id_RANfunctionID;
3626       ricSubsFailIe->criticality = CriticalityE2_reject;
3627       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RANfunctionID;
3628       ricSubsFailIe->value.choice.RANfunctionID = ranFuncId;
3629
3630       /* Cause */
3631       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
3632       ricSubsFailIe->id = ProtocolIE_IDE2_id_CauseE2;
3633       ricSubsFailIe->criticality = CriticalityE2_reject;
3634       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_CauseE2;
3635       fillE2Cause(&ricSubsFailIe->value.choice.CauseE2, failureCause);
3636
3637       /* Prints the Msg formed */
3638       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3639       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3640       encBufSize = 0;
3641       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3642       if(encRetVal.encoded == ENCODE_FAIL)
3643       {
3644          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Failure Message (at %s)\n",\
3645                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3646          break;
3647       }
3648       else
3649       {
3650          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Failure Message \n");
3651 #ifdef DEBUG_ASN_PRINT
3652          for(int i=0; i< encBufSize; i++)
3653          {
3654             printf("%x",encBuf[i]);
3655          }
3656 #endif
3657       }
3658
3659       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
3660       {
3661          DU_LOG("\nINFO   -->  E2AP : Sending RIC Subscription Failure");
3662
3663       }
3664       ret = ROK;
3665       break;
3666    }
3667    FreeRicSubscriptionFailure(e2apMsg);
3668    return ret;
3669 }
3670
3671 /*******************************************************************
3672  *
3673  * @brief Free the RicIndication Message
3674  *
3675  * @details
3676  *
3677  *    Function : FreeRicIndication
3678  *
3679  * Functionality: Free the RicIndication Message
3680  *
3681  * @return void
3682  *         
3683  *
3684  ******************************************************************/
3685 void FreeRicIndication(E2AP_PDU_t  *e2apMsg) 
3686 {
3687    uint8_t idx = 0;
3688    RICindication_t *ricIndicationMsg= NULLP;
3689
3690    if(e2apMsg != NULLP)
3691    {
3692       if(e2apMsg->choice.initiatingMessage != NULLP)
3693       {
3694          ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
3695          if(ricIndicationMsg!= NULLP)
3696          {
3697             if(ricIndicationMsg->protocolIEs.list.array != NULLP)
3698             {
3699                for(idx=0; idx<ricIndicationMsg->protocolIEs.list.count; idx++)
3700                {
3701                   if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP)
3702                   {
3703                      switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
3704                      {
3705                         case ProtocolIE_IDE2_id_RICrequestID:
3706                         case ProtocolIE_IDE2_id_RANfunctionID:
3707                         case ProtocolIE_IDE2_id_RICactionID:
3708                         case ProtocolIE_IDE2_id_RICindicationType:
3709                            break;
3710
3711                         case ProtocolIE_IDE2_id_RICindicationHeader:
3712                            {
3713                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\
3714                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
3715                               break;
3716                            }
3717                         case ProtocolIE_IDE2_id_RICindicationMessage:
3718                            {
3719                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\
3720                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
3721                               break;
3722                            }
3723                         default:
3724                            break;
3725                      }
3726                      DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t));
3727                   }
3728                }
3729                DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size);
3730             }
3731          }
3732          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3733       }
3734       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3735    }
3736 }
3737
3738 /*******************************************************************
3739  *
3740  * @brief Free measurement record
3741  *
3742  * @details
3743  *
3744  *    Function : freeMeasRecord
3745  *
3746  * Functionality: Free all measurement recorded for a measurement
3747  *    within an action in a RIC subscription
3748  *
3749  * @param  Measurement data to be freed
3750  * @return void
3751  *
3752  ******************************************************************/
3753 void freeMeasData(MeasurementData_t *measData)
3754 {
3755    uint8_t measIdx = 0, measRecIdx = 0;
3756    MeasurementRecord_t *measRecord = NULLP;
3757
3758    if(measData->list.array)
3759    {
3760       for(measIdx = 0; measIdx < measData->list.count; measIdx++)
3761       {
3762          if(measData->list.array[measIdx])
3763          {
3764             measRecord = &measData->list.array[measIdx]->measRecord;
3765             if(measRecord->list.array)
3766             {
3767                for(measRecIdx = 0; measRecIdx < measRecord->list.count; measRecIdx++)
3768                {
3769                   DU_FREE(measRecord->list.array[measRecIdx], sizeof(MeasurementRecordItem_t));
3770                }
3771                DU_FREE(measRecord->list.array, measRecord->list.size);
3772             }
3773             DU_FREE(measData->list.array[measIdx], sizeof(MeasurementDataItem_t));
3774          }
3775       }
3776       DU_FREE(measData->list.array, measData->list.size);
3777    }
3778 }
3779
3780 /*******************************************************************
3781  *
3782  * @brief Fill measurement info list
3783  *
3784  * @details
3785  *
3786  *    Function : freeMeasInfoList
3787  *
3788  * Functionality: Fills all measurement info within an action 
3789  *    in a RIC subscription
3790  *
3791  * @param  Measurement Info list to be freed
3792  * @return void
3793  *
3794  ******************************************************************/
3795 void freeMeasInfoList(MeasurementInfoList_t *measInfoList)
3796 {
3797    uint8_t measInfoIdx = 0;
3798
3799    if(measInfoList->list.array)
3800    {
3801       for(measInfoIdx = 0; measInfoIdx < measInfoList->list.count; measInfoIdx++)
3802       {
3803          if(measInfoList->list.array[measInfoIdx])
3804          {
3805             DU_FREE(measInfoList->list.array[measInfoIdx]->measType.choice.measName.buf, \
3806                   measInfoList->list.array[measInfoIdx]->measType.choice.measName.size);
3807
3808             DU_FREE(measInfoList->list.array[measInfoIdx], measInfoList->list.size);
3809          }
3810       }
3811       DU_FREE(measInfoList->list.array, measInfoList->list.size);
3812    }
3813 }
3814
3815 /*******************************************************************
3816  *
3817  * @brief Free E2SM-KPM Indication Message
3818  *
3819  * @details
3820  *
3821  *    Function : FreeE2smKpmIndicationMessage
3822  *
3823  * Functionality: Free E2SM-KPM Indication Message
3824  *
3825  * @param  E2SM-KPM Indication message to be freed
3826  * @return void
3827  *
3828  ******************************************************************/
3829 void FreeE2smKpmIndicationMessage(E2SM_KPM_IndicationMessage_t *e2smKpmIndMsg)
3830 {
3831    E2SM_KPM_IndicationMessage_Format1_t *format1Msg = NULLP;
3832
3833    switch(e2smKpmIndMsg->indicationMessage_formats.present)
3834    {
3835       case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format1:
3836          {
3837             if(e2smKpmIndMsg->indicationMessage_formats.choice.indicationMessage_Format1)
3838             {
3839                format1Msg = e2smKpmIndMsg->indicationMessage_formats.choice.indicationMessage_Format1;
3840                
3841                /* Measurement Data */
3842                freeMeasData(&format1Msg->measData);
3843
3844                /* Measurement Info List */
3845                if(format1Msg->measInfoList)
3846                {
3847                   freeMeasInfoList(format1Msg->measInfoList);
3848                   DU_FREE(format1Msg->measInfoList, sizeof(MeasurementInfoList_t));
3849                }
3850
3851                /* Granularity Period */
3852                DU_FREE(format1Msg->granulPeriod, sizeof(GranularityPeriod_t));
3853
3854                DU_FREE(format1Msg, sizeof(E2SM_KPM_IndicationMessage_Format1_t));
3855             }
3856             break;
3857          }
3858
3859       case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_NOTHING:
3860       case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format2:
3861       default:
3862          break;
3863    }
3864 }
3865
3866 /*******************************************************************
3867  *
3868  * @brief Fill measurement record
3869  *
3870  * @details
3871  *
3872  *    Function : fillMeasRecord
3873  *
3874  * Functionality: Fills all measurement value for a measurement
3875  *    within an action in a RIC subscription
3876  *
3877  * @param  Measurement record to be filled
3878  *         Measurement database with measurement records
3879  * @return ROK     - success
3880  *         RFAILED - failure
3881  *
3882  ******************************************************************/
3883 uint8_t fillMeasRecord(MeasurementRecord_t *measRecord, MeasurementInfo *measInfoDb)
3884 {
3885    uint8_t measRecIdx = 0;
3886    CmLList *measValNode = NULLP;
3887    double  measVal = 0;
3888
3889    measRecord->list.count = measInfoDb->measuredValue.count;
3890    measRecord->list.size = measRecord->list.count * sizeof(MeasurementRecordItem_t *);
3891
3892    DU_ALLOC(measRecord->list.array, measRecord->list.size);
3893    if(!measRecord->list.array)
3894    {
3895       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3896       return RFAILED;
3897    }
3898
3899    for(measRecIdx = 0; measRecIdx < measRecord->list.count; measRecIdx++)
3900    {
3901       DU_ALLOC(measRecord->list.array[measRecIdx], sizeof(MeasurementRecordItem_t));
3902       if(!measRecord->list.array[measRecIdx])
3903       {
3904          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3905          return RFAILED;
3906       }
3907    }
3908
3909    measRecIdx = 0;
3910    CM_LLIST_FIRST_NODE(&measInfoDb->measuredValue, measValNode);
3911    while(measValNode)
3912    {
3913      measVal = *(double *)measValNode->node;
3914      if(measVal == (int)measVal)
3915      {
3916         measRecord->list.array[measRecIdx]->present = MeasurementRecordItem_PR_integer;
3917         measRecord->list.array[measRecIdx]->choice.integer = (int)measVal;
3918      }
3919      else
3920      {
3921          measRecord->list.array[measRecIdx]->present = MeasurementRecordItem_PR_real;
3922          measRecord->list.array[measRecIdx]->choice.real = measVal;
3923      }
3924      measRecIdx++;
3925      measValNode= measValNode->next;  
3926      /* Once the measurement record is added to the message, delete it from DB */
3927      measVal = 0;
3928    }
3929    deleteMeasuredValueList(&measInfoDb->measuredValue);
3930    return ROK;
3931 }
3932
3933 /*******************************************************************
3934  *
3935  * @brief Fills measuerement data
3936  *
3937  * @details
3938  *
3939  *    Function : fillMeasData
3940  *
3941  * Functionality: Fill all measurement recorded for all measurements
3942  *    in an action in a RIC subscription
3943  *
3944  * @param  Measurement data to be filled
3945  *         Measurement info list from an action DB
3946  * @return ROK     - success
3947  *         RFAILED - failure
3948  *
3949  ******************************************************************/
3950 uint8_t fillMeasData(MeasurementData_t *measData, CmLListCp *measInfoListDb)
3951 {
3952   uint8_t measIdx = 0;
3953   CmLList *measInfoNode = NULLP;
3954   MeasurementInfo *measInfoDb = NULLP;
3955   MeasurementRecord_t *measRecord = NULLP;
3956
3957   measData->list.count = measInfoListDb->count;
3958   measData->list.size = measData->list.count * sizeof(MeasurementDataItem_t *);
3959
3960   DU_ALLOC(measData->list.array, measData->list.size);
3961   if(!measData->list.array)
3962   {
3963      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3964      return RFAILED;
3965   }
3966
3967   measIdx = 0;
3968   CM_LLIST_FIRST_NODE(measInfoListDb, measInfoNode);
3969   while(measInfoNode)
3970   {
3971      measInfoDb = (MeasurementInfo *)measInfoNode->node;
3972      if(measInfoDb)
3973      {
3974         DU_ALLOC(measData->list.array[measIdx], sizeof(MeasurementDataItem_t));
3975         if(!measData->list.array[measIdx])
3976         {
3977            DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3978            return RFAILED;
3979         }
3980
3981         measRecord = &measData->list.array[measIdx]->measRecord;
3982         if(fillMeasRecord(measRecord, measInfoDb) != ROK)
3983         {
3984            DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement record");
3985            return RFAILED;
3986         }
3987         measIdx++;
3988      }
3989      measInfoNode = measInfoNode->next;
3990   }
3991
3992   return ROK;
3993 }
3994
3995 /*******************************************************************
3996  *
3997  * @brief Fill all measurement info
3998  *
3999  * @details
4000  *
4001  *    Function : fillMeasInfoList
4002  *
4003  * Functionality: Fills all measurement info belonging to an action
4004  *  in a RIC subscription
4005  *
4006  * @param   Measurement Info list to be filled
4007  *          Measurement Info list from E2AP DB
4008  * @return ROK     - success
4009  *         RFAILED - failure
4010  *
4011  ******************************************************************/
4012 uint8_t fillMeasInfoList(MeasurementInfoList_t *measInfoList, CmLListCp *measInfoListDb)
4013 {
4014    uint8_t measInfoIdx = 0;
4015    CmLList *measInfoNode = NULLP;
4016    MeasurementInfo *measInfoDb = NULLP;
4017    MeasurementInfoItem_t *measInfoItem = NULLP;
4018
4019    measInfoList->list.count = measInfoListDb->count;
4020    measInfoList->list.size = measInfoList->list.count * sizeof(MeasurementInfoItem_t *);
4021
4022    DU_ALLOC(measInfoList->list.array, measInfoList->list.size);
4023    if(!measInfoList->list.array)
4024    {
4025       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4026       return RFAILED;
4027    }
4028
4029    measInfoIdx = 0;
4030    CM_LLIST_FIRST_NODE(measInfoListDb, measInfoNode);
4031    while(measInfoNode)
4032    {
4033       DU_ALLOC(measInfoList->list.array[measInfoIdx], sizeof(MeasurementInfoItem_t));
4034       if(!measInfoList->list.array[measInfoIdx])
4035       {
4036          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4037          return RFAILED;
4038       }
4039
4040       measInfoItem = measInfoList->list.array[measInfoIdx];
4041       measInfoDb = (MeasurementInfo *)measInfoNode->node;
4042       if(measInfoDb)
4043       {
4044          /* Measurement Type */
4045          measInfoItem->measType.present = MeasurementType_PR_measName;
4046          measInfoItem->measType.choice.measName.size = strlen(measInfoDb->measurementTypeName);
4047
4048          DU_ALLOC(measInfoItem->measType.choice.measName.buf, measInfoItem->measType.choice.measName.size);
4049          if(!measInfoItem->measType.choice.measName.buf)
4050          {
4051             DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4052             return RFAILED;
4053          }
4054
4055          memcpy(measInfoItem->measType.choice.measName.buf, measInfoDb->measurementTypeName,\
4056             measInfoItem->measType.choice.measName.size);
4057
4058          measInfoIdx++;
4059       }
4060       measInfoNode = measInfoNode->next;
4061       measInfoDb = NULLP;
4062    }
4063
4064    return ROK;
4065 }
4066
4067  /*******************************************************************
4068  *
4069  * @brief Fill E2SM-KPM Indication Message Format 1
4070  *
4071  * @details
4072  *
4073  *    Function : fillE2smKpmIndMsgFormat1
4074  *
4075  * Functionality: Fill E2SM-KPM Indication Message Format 1
4076  *
4077  * @param  Format 1 Message to be filled
4078  *         Action Definition format 1 from E2AP DB
4079  * @return ROK     - success
4080  *         RFAILED - failure
4081  *
4082  ******************************************************************/
4083 uint8_t fillE2smKpmIndMsgFormat1(E2SM_KPM_IndicationMessage_Format1_t *format1Msg, ActionDefFormat1 *format1)
4084 {
4085   /* Measurement Data */
4086   if(fillMeasData(&format1Msg->measData, &format1->measurementInfoList) != ROK)
4087   {
4088      DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement data");
4089      return RFAILED;
4090   }
4091
4092   /* Measurement Information */
4093   DU_ALLOC(format1Msg->measInfoList, sizeof(MeasurementInfoList_t));
4094   if(!format1Msg->measInfoList)
4095   {
4096      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4097      return RFAILED;
4098   }
4099
4100   if(fillMeasInfoList(format1Msg->measInfoList, &format1->measurementInfoList) != ROK)
4101   {
4102      DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement information list");
4103      return RFAILED;
4104   }
4105
4106   /* Granularity Period */
4107   DU_ALLOC(format1Msg->granulPeriod, sizeof(GranularityPeriod_t));
4108   if(!format1Msg->granulPeriod)
4109   {
4110      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4111      return RFAILED;
4112   }
4113   *(format1Msg->granulPeriod) = format1->granularityPeriod;
4114
4115   return ROK;
4116 }
4117
4118 /*******************************************************************
4119  *
4120  * @brief Fill RIC Indication Message buffer
4121  *
4122  * @details
4123  *
4124  *    Function : fillRicIndMsgBuf
4125  *
4126  * Functionality: Fill E2SM-KPM Indication Message
4127  *    Encode this message and copy to RIC Indication Message buffer
4128  * 
4129  * @param  RIC Indication Message buffer to be filled
4130  *         Source action info from E2AP DB
4131  * @return ROK     - success
4132  *         RFAILED - failure
4133  *
4134  ******************************************************************/
4135 uint8_t fillRicIndMsgBuf(RICindicationMessage_t *ricIndMsgBuf, ActionInfo *actionInfo)
4136 {
4137    uint8_t ret = RFAILED;
4138    bool failedInFormat = false;
4139    E2SM_KPM_IndicationMessage_t e2smKpmIndMsg;
4140    asn_enc_rval_t   encRetVal;        /* Encoder return value */
4141
4142    memset(&e2smKpmIndMsg, 0, sizeof(E2SM_KPM_IndicationMessage_t));
4143
4144    while(true)
4145    {
4146       /* E2SM-KPM Indication message format type */
4147       e2smKpmIndMsg.indicationMessage_formats.present = actionInfo->definition.formatType;
4148       switch(e2smKpmIndMsg.indicationMessage_formats.present)
4149       {
4150          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format1:
4151             {
4152                /* E2SM-KPM Indication message format 1 */
4153                DU_ALLOC(e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1, \
4154                      sizeof(E2SM_KPM_IndicationMessage_Format1_t));
4155                if(!e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1)
4156                {
4157                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4158                   failedInFormat = true;
4159                   break;
4160                }
4161
4162                if(fillE2smKpmIndMsgFormat1(e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1, \
4163                   &actionInfo->definition.choice.format1) != ROK)
4164                {
4165                   DU_LOG("\nERROR  -->  E2AP : Failed to fill E2SM-KPM Indication message format 1");
4166                   failedInFormat = true;
4167                   break;
4168                }
4169                break;
4170             }
4171
4172          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_NOTHING:
4173          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format2:
4174          default:
4175             {
4176                DU_LOG("\nERROR  -->  E2AP : fillRicIndMsgBuf: Only Format 1 supported");
4177                failedInFormat = true;
4178                break;
4179             }
4180       }
4181
4182       if(failedInFormat)
4183          break;
4184
4185       /* Encode E2SM-KPM Indication Message */
4186       xer_fprint(stdout, &asn_DEF_E2SM_KPM_IndicationMessage, &e2smKpmIndMsg);
4187       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4188       encBufSize = 0;
4189       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_IndicationMessage, 0, &e2smKpmIndMsg, PrepFinalEncBuf, encBuf);
4190       if(encRetVal.encoded == ENCODE_FAIL)
4191       {
4192          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM Indication Message (at %s)\n",\
4193                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4194          break;
4195       }
4196       else
4197       {
4198          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SM-KPM Indication Message \n");
4199 #ifdef DEBUG_ASN_PRINT
4200          for(int i=0; i< encBufSize; i++)
4201          {
4202             printf("%x",encBuf[i]);
4203          } 
4204 #endif
4205       }
4206
4207       /* Copy encoded string to RIC Indication Message buffer */
4208       ricIndMsgBuf->size = encBufSize;
4209       DU_ALLOC(ricIndMsgBuf->buf, ricIndMsgBuf->size);
4210       if(!ricIndMsgBuf->buf)
4211       {
4212          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4213          break;
4214       }
4215       memset(ricIndMsgBuf->buf, 0, ricIndMsgBuf->size);
4216       memcpy(ricIndMsgBuf->buf, encBuf, encBufSize);
4217
4218       ret = ROK;
4219       break;
4220    }
4221
4222    /* Free E2SM-KPM Indication Message */
4223    FreeE2smKpmIndicationMessage(&e2smKpmIndMsg);
4224
4225    return ret;
4226 }
4227
4228 /*******************************************************************
4229  *
4230  * @brief Free E2SM-KPM Indication Header
4231  *
4232  * @details
4233  *
4234  *    Function : FreeE2smKpmIndicationHeader
4235  *
4236  * Functionality: Free E2SM-KPM Indication Header
4237  * 
4238  * @param  E2SM-KPM Indication Header to be free
4239  * @return void
4240  *
4241  ******************************************************************/
4242 void FreeE2smKpmIndicationHeader(E2SM_KPM_IndicationHeader_t *e2smKpmIndHdr)
4243 {
4244    E2SM_KPM_IndicationHeader_Format1_t *format1 = NULLP;
4245
4246    if(e2smKpmIndHdr)
4247    {
4248       switch(e2smKpmIndHdr->indicationHeader_formats.present)
4249       {
4250          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_indicationHeader_Format1:
4251             {
4252                if(e2smKpmIndHdr->indicationHeader_formats.choice.indicationHeader_Format1)
4253                {
4254                   format1 = e2smKpmIndHdr->indicationHeader_formats.choice.indicationHeader_Format1;
4255
4256                   DU_FREE(format1->colletStartTime.buf, format1->colletStartTime.size);
4257                   DU_FREE(format1, sizeof(E2SM_KPM_IndicationHeader_Format1_t));
4258                }
4259                break;
4260             }
4261          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_NOTHING:
4262          default:
4263             break;
4264       }
4265    }
4266 }
4267
4268 /*******************************************************************
4269  *
4270  * @brief Fill RIC Indication Header buffer
4271  *
4272  * @details
4273  *
4274  *    Function : fillRicIndHeader
4275  *
4276  * Functionality: Fill E2SM-KPM Indication Header
4277  *    Encode this message and copy to RIC Indication Header buffer
4278  * 
4279  * @param  RIC Indication Header buffer to be filled
4280  *         Source RIC subscription info from E2AP DB
4281  * @return ROK     - success
4282  *         RFAILED - failure
4283  *
4284  ******************************************************************/
4285 uint8_t fillRicIndHeader(RICindicationHeader_t *ricIndHdr, RicSubscription *ricSubsInfo)
4286 {
4287    uint8_t ret = RFAILED;
4288    uint8_t secBufIdx = 0, milliSecBufIdx = 0;
4289    int8_t byteIdx = 0;
4290    bool formatFailure = false;
4291    RanFunction *ranFunc = NULLP;
4292    ReportStartTime *startTime = NULLP;
4293    E2SM_KPM_IndicationHeader_t e2smKpmIndHdr;
4294    E2SM_KPM_IndicationHeader_Format1_t *format1 = NULLP;
4295    asn_enc_rval_t   encRetVal;        /* Encoder return value */
4296
4297    while(true)
4298    {
4299       ranFunc = fetchRanFuncFromRanFuncId(ricSubsInfo->ranFuncId);
4300       if(ranFunc == NULLP)
4301       {
4302          DU_LOG("\nERROR  -->  E2AP : RAN Function ID [%d] not found", ricSubsInfo->ranFuncId);
4303          break;
4304       }
4305
4306       memset(&e2smKpmIndHdr, 0, sizeof(E2SM_KPM_IndicationHeader_t));
4307
4308       e2smKpmIndHdr.indicationHeader_formats.present = ranFunc->ricIndicationHeaderFormat;
4309       switch(e2smKpmIndHdr.indicationHeader_formats.present)
4310       {
4311          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_indicationHeader_Format1:
4312             {
4313                DU_ALLOC(e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1, \
4314                      sizeof(E2SM_KPM_IndicationHeader_Format1_t));
4315                if(!e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1)
4316                {
4317                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4318                   formatFailure = true;
4319                   break;
4320                }
4321                format1 = e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1;
4322
4323                /* Fetch reporting period start time from DB */
4324                switch(ricSubsInfo->eventTriggerDefinition.formatType)
4325                {
4326                   case 1:
4327                   {
4328                      startTime = &ricSubsInfo->eventTriggerDefinition.choice.format1.startTime;
4329                   }
4330                }
4331
4332                format1->colletStartTime.size = 8 * sizeof(uint8_t);
4333                DU_ALLOC(format1->colletStartTime.buf, format1->colletStartTime.size);
4334                if(!format1->colletStartTime.buf)
4335                {
4336                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4337                   formatFailure = true;
4338                   break;
4339                }
4340
4341                /* As per O-RAN.WG3.E2SM-KPM-R003-v03.00, section 8.3.12 and
4342                 * RFC 5905, section 6 :
4343                 * Time stamp has a 64-bit format where first 32-bit is seconds
4344                 * and next 32-bit is fraction in picosecond-level.
4345                 * This fraction has been rounded in microseconds.
4346                 *
4347                 * Hence,
4348                 * Storing 32-bit seconds at MSB 0-3 and
4349                 * 32-bit milliseconds at next 4 bytes i.e. bytes 4-7
4350                 */
4351                secBufIdx = 0;
4352                milliSecBufIdx = 4;
4353                for(byteIdx = 3; byteIdx >= 0; byteIdx--)
4354                {
4355                   format1->colletStartTime.buf[secBufIdx++] = startTime->timeInSec >> (8*byteIdx);
4356                   format1->colletStartTime.buf[milliSecBufIdx++] = startTime->timeInMilliSec >> (8*byteIdx);
4357                }
4358                break;
4359             }
4360
4361          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_NOTHING:
4362          default:
4363          {
4364              DU_LOG("\nERROR  -->  E2AP : Only E2SM-KPM Indication Header Format 1 supported");
4365              formatFailure = true;
4366              break;
4367          }
4368       }
4369
4370       if(formatFailure)
4371          break;
4372
4373       /* Encode E2SM-KPM Indication Header */
4374       xer_fprint(stdout, &asn_DEF_E2SM_KPM_IndicationHeader, &e2smKpmIndHdr);
4375       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4376       encBufSize = 0;
4377       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_IndicationHeader, 0, &e2smKpmIndHdr, PrepFinalEncBuf, encBuf);
4378       if(encRetVal.encoded == ENCODE_FAIL)
4379       {
4380          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM Indication Header (at %s)\n",\
4381                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4382          break;
4383       }
4384       else
4385       {
4386          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SM-KPM Indication Header \n");
4387 #ifdef DEBUG_ASN_PRINT
4388          for(int i=0; i< encBufSize; i++)
4389          {
4390             printf("%x",encBuf[i]);
4391          } 
4392 #endif
4393       }
4394
4395       /* Copy encoded string to RIC Indication Header buffer */
4396       ricIndHdr->size = encBufSize;
4397       DU_ALLOC(ricIndHdr->buf, ricIndHdr->size);
4398       if(!ricIndHdr->buf)
4399       {
4400          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4401          break;
4402       }
4403       memset(ricIndHdr->buf, 0, ricIndHdr->size);
4404       memcpy(ricIndHdr->buf, encBuf, encBufSize);
4405       ret = ROK;
4406       break;
4407    }
4408
4409    /* Free E2SM-KPM Indication Header */
4410    FreeE2smKpmIndicationHeader(&e2smKpmIndHdr);
4411
4412    return ret;
4413 }
4414
4415 /*******************************************************************
4416  *
4417  * brief Fill the RIC Indication Message
4418  *
4419  * @details
4420  *
4421  *    Function : fillRicIndication
4422  *
4423  * Functionality: Fills the RIC Indication Message
4424  *
4425  * @param  RIC Indication Message to be filled
4426  *         RIC Subscription DB
4427  *         Action DB
4428  * @return ROK     - success
4429  *         RFAILED - failure
4430  *
4431  ******************************************************************/
4432 uint8_t fillRicIndication(RICindication_t *ricIndicationMsg, RicSubscription *ricSubscriptionInfo, ActionInfo *actionInfo)
4433 {
4434    uint8_t elementCnt = 0, idx = 0;
4435    uint8_t ret = ROK;
4436
4437    elementCnt = 6;
4438
4439    ricIndicationMsg->protocolIEs.list.count = elementCnt;
4440    ricIndicationMsg->protocolIEs.list.size  = elementCnt * sizeof(RICindication_IEs_t *);
4441
4442    /* Initialize the Ric Indication members */
4443    DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, ricIndicationMsg->protocolIEs.list.size);
4444    if(ricIndicationMsg->protocolIEs.list.array == NULLP)
4445    {
4446       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4447       return RFAILED;
4448    }
4449
4450    for(idx=0; idx<elementCnt; idx++)
4451    {
4452       DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx], sizeof(RICindication_IEs_t));
4453       if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
4454       {
4455          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4456          return RFAILED;
4457       }
4458    }
4459
4460    /* RIC Request ID */
4461    idx = 0;
4462    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
4463    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4464    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICrequestID;
4465    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID = \
4466       ricSubscriptionInfo->requestId.requestorId;
4467    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID = \
4468       ricSubscriptionInfo->requestId.instanceId;
4469
4470    /* RAN Function ID */
4471    idx++;
4472    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
4473    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4474    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RANfunctionID;
4475    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ricSubscriptionInfo->ranFuncId;
4476
4477    /* RIC Action ID */
4478    idx++;
4479    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
4480    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4481    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICactionID;
4482    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = actionInfo->actionId;
4483
4484    /* RIC Indication Type */
4485    idx++;
4486    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
4487    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4488    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationType;
4489    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = actionInfo->type;
4490
4491    /* RIC Indication Header */
4492    idx++;
4493    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
4494    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4495    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationHeader;
4496    if(fillRicIndHeader(&ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader, \
4497       ricSubscriptionInfo) != ROK)
4498    {
4499       DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication header");
4500       return RFAILED;
4501    }
4502
4503    /* RIC Indication Message */
4504    idx++;
4505    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
4506    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4507    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationMessage;
4508    if(fillRicIndMsgBuf(&ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage, \
4509       actionInfo) != ROK)
4510    {
4511       DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication Message");
4512       return RFAILED;
4513    }
4514
4515    return ret;
4516 }
4517
4518 /*******************************************************************
4519  *
4520  * @brief Builds and Send the RicIndication Message
4521  *
4522  * @details
4523  *
4524  *    Function : BuildAndSendRicIndication
4525  *
4526  * Functionality:Fills the RicIndication Message
4527  *
4528  * @return ROK     - success
4529  *         RFAILED - failure
4530  *
4531  ******************************************************************/
4532
4533 uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo, ActionInfo *actionInfo)
4534 {
4535    uint8_t          ret = RFAILED; 
4536    E2AP_PDU_t       *e2apMsg = NULLP;
4537    RICindication_t  *ricIndicationMsg = NULLP;
4538    asn_enc_rval_t   encRetVal;        /* Encoder return value */
4539
4540    while(true)
4541    {
4542       DU_LOG("\nINFO   -->  E2AP : Building RIC Indication Message\n");
4543
4544       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4545       if(e2apMsg == NULLP)
4546       {
4547          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4548          break;
4549       }
4550
4551       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4552       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4553       if(e2apMsg->choice.initiatingMessage == NULLP)
4554       {
4555          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4556          break;
4557       }
4558       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
4559       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4560       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication;
4561
4562       ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
4563
4564       if(fillRicIndication(ricIndicationMsg, ricSubscriptionInfo, actionInfo) != ROK)
4565       {
4566          DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication message");
4567          break;
4568       }
4569
4570       /* Prints the Msg formed */
4571       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4572       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4573       encBufSize = 0;
4574       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4575             encBuf);
4576       if(encRetVal.encoded == ENCODE_FAIL)
4577       {
4578          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Indication Message (at %s)\n",\
4579                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4580          break;
4581       }
4582       else
4583       {
4584          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Indication Message \n");
4585 #ifdef DEBUG_ASN_PRINT
4586          for(int i=0; i< encBufSize; i++)
4587          {
4588             printf("%x",encBuf[i]);
4589          } 
4590 #endif
4591       }
4592
4593       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
4594       {
4595          DU_LOG("\nINFO   -->  E2AP : Sending RIC Indication Message");      
4596
4597       }
4598       ret = ROK;
4599       break;
4600    }
4601    FreeRicIndication(e2apMsg);  
4602    return ret;
4603 }
4604
4605 /*******************************************************************
4606  *
4607  * @brief free e2 node component configuration req and rsp
4608  *
4609  * @details
4610  *
4611  *    Function : freeE2NodeComponentConfiguration 
4612  *
4613  *    Functionality:
4614  *       - free e2 node component configuration req and rsp
4615  *
4616  * @params[in] E2nodeComponentConfiguration_t *e2nodeComponentConfiguration
4617  * @return ROK     - success
4618  *         RFAILED - failure
4619  *
4620  * ****************************************************************/
4621
4622 void freeE2NodeComponentConfiguration(E2nodeComponentConfiguration_t *e2nodeComponentConfiguration)
4623 {
4624    /* Free E2 Node Component Request Part */
4625    DU_FREE(e2nodeComponentConfiguration->e2nodeComponentRequestPart.buf, e2nodeComponentConfiguration->e2nodeComponentRequestPart.size);
4626
4627    /* Free E2 Node Component Response Part */
4628    DU_FREE(e2nodeComponentConfiguration->e2nodeComponentResponsePart.buf, e2nodeComponentConfiguration->e2nodeComponentResponsePart.size);
4629                                  
4630 }
4631
4632 /*******************************************************************
4633  *
4634  * @brief free e2 node component component identifier
4635  *
4636  * @details
4637  *
4638  *    Function : freeE2NodeComponentIdentifier
4639  *
4640  *    Functionality:
4641  *       - free e2 node component component identifier
4642  *
4643  * @params[in] E2nodeComponentID_t  *componentID 
4644  * @return ROK     - success
4645  *         RFAILED - failure
4646  *
4647  * ****************************************************************/
4648
4649 void freeE2NodeComponentIdentifier(E2nodeComponentID_t *componentID)
4650 {
4651    if(componentID->choice.e2nodeComponentInterfaceTypeF1)
4652    {
4653       DU_FREE(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf, componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
4654       DU_FREE(componentID->choice.e2nodeComponentInterfaceTypeF1, sizeof(E2nodeComponentInterfaceF1_t));
4655    }
4656                                  
4657 }
4658
4659 /*******************************************************************
4660  *
4661  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
4662  *
4663  * @details
4664  *
4665  *    Function : FreeE2NodeConfigUpdate 
4666  *
4667  *    Functionality:
4668  *       - freeing the memory allocated for E2nodeConfigurationUpdate
4669  *
4670  * @params[in] E2AP_PDU_t *e2apMsg 
4671  * @return ROK     - success
4672  *         RFAILED - failure
4673  *
4674  * ****************************************************************/
4675
4676 void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg)
4677 {
4678    uint8_t arrIdx =0, e2NodeUpdateListIdx=0, e2NodeRemovalListIdx=0, e2NodeAddListIdx=0;
4679    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate =NULL;
4680    E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList  =NULL;
4681    E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItem =NULL;
4682    E2nodeComponentConfigRemoval_List_t *e2NodeRemovalList =NULL;
4683    E2nodeComponentConfigRemoval_ItemIEs_t *e2NodeRemovalItem =NULL;
4684    E2nodeComponentConfigAddition_List_t *e2NodeAddList =NULL;
4685    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem =NULL;
4686
4687    if(e2apMsg != NULLP)
4688    {
4689       if(e2apMsg->choice.initiatingMessage != NULLP)
4690       {
4691          e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
4692          if(e2NodeConfigUpdate->protocolIEs.list.array != NULLP)
4693          {
4694             for(arrIdx = 0; arrIdx < e2NodeConfigUpdate->protocolIEs.list.count; arrIdx++)
4695             {
4696                if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx])
4697                {
4698
4699                   switch(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id)
4700                   {
4701                      case ProtocolIE_IDE2_id_TransactionID:
4702                         break;
4703
4704                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
4705                      {
4706                          e2NodeAddList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;
4707                          if(e2NodeAddList->list.array)
4708                          {
4709                              for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
4710                              {
4711                                 e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
4712                                  
4713                                 freeE2NodeComponentConfiguration(&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration);
4714                                 freeE2NodeComponentIdentifier(&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID);
4715                                 DU_FREE(e2NodeAddItem, sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
4716                              }
4717                              DU_FREE(e2NodeAddList->list.array, e2NodeAddList->list.size);
4718                          }
4719                          break;
4720                      }
4721                      case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate:
4722                         {
4723                            e2NodeUpdateList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdate_List;
4724                            if(e2NodeUpdateList->list.array)
4725                            {
4726                               for(e2NodeUpdateListIdx = 0; e2NodeUpdateListIdx< e2NodeUpdateList->list.count; e2NodeUpdateListIdx++)
4727                               {
4728                                  e2NodeUpdateItem = (E2nodeComponentConfigUpdate_ItemIEs_t *) e2NodeUpdateList->list.array[e2NodeUpdateListIdx];
4729                                  
4730                                  freeE2NodeComponentConfiguration(&e2NodeUpdateItem->value.choice.E2nodeComponentConfigUpdate_Item.e2nodeComponentConfiguration);
4731                                  freeE2NodeComponentIdentifier(&e2NodeUpdateItem->value.choice.E2nodeComponentConfigUpdate_Item.e2nodeComponentID);
4732                                  DU_FREE(e2NodeUpdateItem, sizeof(E2nodeComponentConfigUpdate_ItemIEs_t));
4733                               }
4734                               DU_FREE(e2NodeUpdateList->list.array, e2NodeUpdateList->list.size);
4735                            }
4736                            break;
4737                         }
4738                      case ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval:
4739                         {
4740                            e2NodeRemovalList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemoval_List;
4741                            if(e2NodeRemovalList->list.array)
4742                            {
4743                               for(e2NodeRemovalListIdx = 0; e2NodeRemovalListIdx< e2NodeRemovalList->list.count; e2NodeRemovalListIdx++)
4744                               {
4745                                  e2NodeRemovalItem = (E2nodeComponentConfigRemoval_ItemIEs_t *) e2NodeRemovalList->list.array[e2NodeRemovalListIdx];
4746
4747                                  freeE2NodeComponentIdentifier(&e2NodeRemovalItem->value.choice.E2nodeComponentConfigRemoval_Item.e2nodeComponentID);
4748                                  DU_FREE(e2NodeRemovalItem, sizeof(E2nodeComponentConfigRemoval_ItemIEs_t));
4749                               }
4750                               DU_FREE(e2NodeRemovalList->list.array, e2NodeRemovalList->list.size);
4751                            }
4752                            break;
4753                         }
4754                            
4755                      default:
4756                         break;
4757                   }
4758                   DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
4759                }
4760             }
4761             DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
4762          }
4763          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4764       }
4765       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4766    }
4767 }
4768
4769 /*******************************************************************
4770  *
4771  * @brief Buld and send the E2 node config update msg 
4772  *
4773  * @details
4774  *
4775  *    Function : BuildAndSendE2NodeConfigUpdate
4776  *
4777  *    Functionality:
4778  *         - Buld and send the E2 node config update msg
4779  *
4780  * @params[in] 
4781  * @return ROK     - success
4782  *         RFAILED - failure
4783  *
4784  * ****************************************************************/
4785
4786 uint8_t BuildAndSendE2NodeConfigUpdate(E2NodeConfigList *e2NodeList)
4787 {
4788    uint8_t ret = RFAILED;
4789    uint8_t arrIdx = 0,elementCnt = 0, transId=0;
4790    E2AP_PDU_t  *e2apMsg = NULLP;
4791    asn_enc_rval_t     encRetVal;       /* Encoder return value */
4792    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate = NULLP;
4793
4794    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update\n");
4795    do
4796    {
4797       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4798       if(e2apMsg == NULLP)
4799       {
4800          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4801          break;
4802       }
4803
4804       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4805       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4806       if(e2apMsg->choice.initiatingMessage == NULLP)
4807       {
4808          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4809          break;
4810       }
4811       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4812       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
4813       e2apMsg->choice.initiatingMessage->value.present = \
4814       InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate;
4815       e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
4816       
4817       elementCnt =1;
4818       if(e2NodeList->addE2NodeCount)
4819          elementCnt++;
4820       if(e2NodeList->updateE2NodeCount)
4821          elementCnt++;
4822       if(e2NodeList->removeE2NodeCount)
4823          elementCnt++;
4824
4825       e2NodeConfigUpdate->protocolIEs.list.count = elementCnt;
4826       e2NodeConfigUpdate->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdate_IEs_t*);
4827       DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
4828       if(e2NodeConfigUpdate->protocolIEs.list.array == NULLP)
4829       {
4830          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
4831          break;
4832       }
4833       
4834       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
4835       {
4836          DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
4837          if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx] == NULLP)
4838          {
4839             
4840             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
4841             break;
4842          }
4843       }
4844       
4845       if(arrIdx<elementCnt)
4846          break;
4847
4848       arrIdx = 0;
4849       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4850       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4851       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_TransactionID;
4852       transId = assignTransactionId();
4853       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
4854
4855       if(e2NodeList->addE2NodeCount)
4856       {
4857          arrIdx++;
4858          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition;
4859          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4860          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigAddition_List;
4861          if(BuildE2NodeConfigAddList(&(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List),\
4862          ProcedureCodeE2_id_E2nodeConfigurationUpdate, e2NodeList->addE2NodeCount, e2NodeList->addE2Node)!=ROK)
4863          {
4864             DU_LOG("\nERROR  -->  E2AP : Failed to create E2 Node config list");
4865             break;
4866          }
4867       }
4868       
4869       if(e2NodeList->updateE2NodeCount)
4870       {
4871          arrIdx++;
4872          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate;
4873          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4874          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigUpdate_List;
4875          if(BuildE2NodeConfigUpdateList(&e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdate_List,\
4876          e2NodeList->updateE2NodeCount, e2NodeList->updateE2Node) != ROK)
4877          {
4878
4879             DU_LOG("\nERROR  -->  E2AP : Failed to update the E2 node configuration");
4880             break;
4881          }
4882       }
4883       
4884       if(e2NodeList->removeE2NodeCount)
4885       {
4886          arrIdx++;
4887          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval;
4888          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4889          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigRemoval_List;
4890          if(BuildE2NodeConfigRemoveList(&e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemoval_List,\
4891          e2NodeList->removeE2NodeCount, e2NodeList->removeE2Node) != ROK)
4892          {
4893
4894             DU_LOG("\nERROR  -->  E2AP : Failed to remove the E2 node configuration");
4895             break;
4896          }
4897       }
4898
4899       /* Prints the Msg formed */
4900       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4901
4902       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4903       encBufSize = 0;
4904       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
4905       if(encRetVal.encoded == ENCODE_FAIL)
4906       {
4907          DU_LOG("\nERROR  -->  E2AP : Could not encode E2nodeConfigurationUpdate structure (at %s)\n",\
4908                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4909          break;
4910       }
4911       else
4912       {
4913          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2nodeConfigurationUpdate\n");
4914 #ifdef DEBUG_ASN_PRINT
4915          for(int i=0; i< encBufSize; i++)
4916          {
4917             printf("%x",encBuf[i]);
4918          }
4919 #endif
4920       }
4921       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize))
4922       {
4923          DU_LOG("\nERROR  -->  E2AP : Sending E2 node config update failed");
4924          break;
4925       }
4926
4927       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
4928       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
4929       memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.e2NodeConfigUpdate.configList, e2NodeList, sizeof(E2NodeConfigList));
4930       ret = ROK;
4931       break;
4932    }while(true);
4933    
4934    FreeE2NodeConfigUpdate(e2apMsg);
4935    return ret;
4936 }
4937
4938 /*******************************************************************
4939  *
4940  * @brief Deallocate the memory allocated for E2ResetRequest msg
4941  *
4942  * @details
4943  *
4944  *    Function : FreeE2ResetRequest
4945  *
4946  *    Functionality:
4947  *       - freeing the memory allocated for E2ResetRequest
4948  *
4949  * @params[in] E2AP_PDU_t *e2apMsg
4950  * @return ROK     - success
4951  *         RFAILED - failure
4952  *
4953  * ****************************************************************/
4954 void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg)
4955 {
4956    uint8_t ieIdx =0;
4957    ResetRequestE2_t  *resetReq = NULLP;
4958
4959    if(e2apMsg != NULLP)
4960    {
4961       if(e2apMsg->choice.initiatingMessage != NULLP)
4962       {
4963          resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4964          if(resetReq->protocolIEs.list.array)
4965          {
4966             for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
4967             {
4968                DU_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4969             }
4970             DU_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4971          }
4972          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4973       }
4974       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4975    }
4976 }
4977
4978 /*******************************************************************
4979  *
4980  * @brief Build and send the E2 reset request msg
4981  *
4982  * @details
4983  *
4984  *    Function : BuildAndSendE2ResetRequest
4985  *
4986  *    Functionality:
4987  *         - Buld and send the E2 reset request msg to RIC
4988  *
4989  * @params[in]
4990  *    Reset cause
4991  * @return ROK     - success
4992  *         RFAILED - failure
4993  *
4994  * ****************************************************************/
4995 uint8_t BuildAndSendE2ResetRequest(E2FailureCause resetCause)
4996 {
4997    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
4998    uint8_t ret = RFAILED;
4999    E2AP_PDU_t        *e2apMsg = NULLP;
5000    ResetRequestE2_t  *resetReq = NULLP;
5001    asn_enc_rval_t     encRetVal;       /* Encoder return value */
5002
5003    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Request\n");
5004
5005    do
5006    {
5007       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
5008       if(e2apMsg == NULLP)
5009       {
5010          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for E2AP-PDU failed");
5011          break;
5012       }
5013
5014       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
5015       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5016       if(e2apMsg->choice.initiatingMessage == NULLP)
5017       {
5018          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for initiatingMessage");
5019          break;
5020       }
5021
5022       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
5023       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
5024       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
5025       resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
5026
5027       elementCnt = 2;
5028       resetReq->protocolIEs.list.count = elementCnt;
5029       resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
5030
5031       DU_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
5032       if(!resetReq->protocolIEs.list.array)
5033       {
5034          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
5035             Reset Request IE array");
5036          break;
5037       }
5038
5039       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
5040       {
5041          DU_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
5042          if(!resetReq->protocolIEs.list.array[ieIdx])
5043          {
5044             DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
5045             Reset Request IE array element");
5046             break;
5047          }
5048       }
5049
5050       /* In case of failure */
5051       if(ieIdx < elementCnt)
5052          break;
5053
5054       ieIdx = 0;
5055       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
5056       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
5057       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
5058       transId = assignTransactionId();
5059       resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
5060
5061       ieIdx++;
5062       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
5063       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
5064       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
5065       fillE2Cause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, resetCause);
5066
5067       /* Prints the Msg formed */
5068       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5069
5070       memset(encBuf, 0, ENC_BUF_MAX_LEN);
5071       encBufSize = 0;
5072       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
5073             encBuf);
5074       if(encRetVal.encoded == ENCODE_FAIL)
5075       {
5076          DU_LOG("\nERROR  -->  E2AP : Could not encode reset request structure (at %s)\n",\
5077                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
5078          break;
5079       }
5080       else
5081       {
5082          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for reset request\n");
5083 #ifdef DEBUG_ASN_PRINT
5084          for(int i=0; i< encBufSize; i++)
5085          {
5086             printf("%x",encBuf[i]);
5087          }
5088 #endif
5089       }
5090       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
5091       {
5092          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
5093          break;
5094       }
5095
5096       /* In case the message is sent successfully, store the transaction info to
5097        * be used when response is received */
5098       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
5099       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5100
5101       ret = ROK;
5102       break;
5103    }while(true);
5104
5105    /* Free all memory */
5106    FreeE2ResetRequest(e2apMsg);
5107    return ret;
5108 }
5109
5110 /*******************************************************************
5111  *
5112  * @brief Deallocate the memory allocated for Reset Response msg
5113  *
5114  * @details
5115  *
5116  *    Function : freeAperDecodingOfE2ResetRsp
5117  *
5118  *    Functionality:
5119  *       - freeing the memory allocated for Reset response
5120  *
5121  * @params[in] ResetResponseE2_t *resetResponse
5122  * @return void
5123  *
5124  * ****************************************************************/
5125 void freeAperDecodingOfE2ResetRsp(ResetResponseE2_t *resetResponse)
5126 {
5127    uint8_t ieIdx;
5128
5129    if(resetResponse)
5130    {
5131       if(resetResponse->protocolIEs.list.array)
5132       {
5133          for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
5134          {
5135             if(resetResponse->protocolIEs.list.array[ieIdx])
5136             {
5137                switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
5138                {
5139                   case ProtocolIE_IDE2_id_TransactionID:
5140                      break;
5141
5142                   case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
5143                      break;
5144                }
5145                free(resetResponse->protocolIEs.list.array[ieIdx]);
5146             }
5147          }
5148          free(resetResponse->protocolIEs.list.array);
5149       }
5150    }
5151 }
5152
5153 /******************************************************************
5154  *
5155  * @brief Processes E2 Reset Response sent by RIC
5156  *
5157  * @details
5158  *
5159  *    Function : procResetResponse
5160  *
5161  *    Functionality: Processes E2 Reset Response sent by RIC
5162  *
5163  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5164  * @return void
5165  *
5166  * ****************************************************************/
5167 void procResetResponse(E2AP_PDU_t *e2apMsg)
5168 {
5169    bool invalidTransId=false;
5170    uint8_t ieIdx =0, transId =0;
5171    uint16_t ranFuncIdx=0;
5172    ResetResponseE2_t *resetResponse =NULLP;
5173
5174    DU_LOG("\nINFO   -->  E2AP : E2 Reset Response received");
5175    resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;;
5176
5177    for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
5178    {
5179       switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
5180       {
5181          case ProtocolIE_IDE2_id_TransactionID:
5182             {
5183                transId = resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
5184                if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) && \
5185                      (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
5186                {
5187                   memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
5188                }
5189                else
5190                {
5191                   DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
5192                   invalidTransId = true;
5193                }
5194                break;
5195             }
5196          case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
5197             {
5198                for(ranFuncIdx=0; ranFuncIdx<MAX_RAN_FUNCTION; ranFuncIdx++)
5199                {
5200                   if(duCb.e2apDb.ranFunction[ranFuncIdx].id >0)
5201                   {
5202                      deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList));
5203                      memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo));
5204                   }
5205                }
5206                break;
5207             }
5208          default:
5209             {
5210                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2 Reset Response : %ld",
5211                      resetResponse->protocolIEs.list.array[ieIdx]->id);
5212                break;
5213             }
5214       }
5215
5216       if(invalidTransId == true)
5217       {
5218          break;
5219       }
5220    }
5221
5222    freeAperDecodingOfE2ResetRsp(resetResponse);
5223 }
5224
5225 /******************************************************************
5226  *
5227  * @brief Deallocation of memory allocated by aper decoder for e2 setup Failure
5228  *
5229  * @details
5230  *
5231  *    Function : freeAperDecodingOfE2SetupFailure
5232  *
5233  *    Functionality: Deallocation of memory allocated by aper decoder for e2
5234  *    setup Failure
5235  *
5236  * @params[in] E2setupFailure_t *e2SetupFailure;
5237  * @return void
5238  *
5239  * ****************************************************************/
5240 void freeAperDecodingOfE2SetupFailure(E2setupFailure_t *e2SetupFailure)
5241 {
5242    uint8_t arrIdx;
5243
5244    if(e2SetupFailure)
5245    {
5246       if(e2SetupFailure->protocolIEs.list.array)
5247       {
5248          for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
5249          {
5250             if(e2SetupFailure->protocolIEs.list.array[arrIdx])
5251             {
5252                free(e2SetupFailure->protocolIEs.list.array[arrIdx]);  
5253             }
5254          }
5255          free(e2SetupFailure->protocolIEs.list.array);
5256       }
5257    }
5258 }
5259 /******************************************************************
5260  *
5261  * @brief Processes E2 Setup Failure sent by RIC
5262  *
5263  * @details
5264  *
5265  *    Function : procE2SetupFailure
5266  *
5267  *    Functionality: Processes E2 Setup failure sent by RIC
5268  *
5269  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5270  * @return ROK     - success
5271  *         RFAILED - failure
5272  *
5273  * ****************************************************************/
5274 void procE2SetupFailure(E2AP_PDU_t *e2apMsg)
5275 {
5276    uint8_t arrIdx =0, transId =0, timerValue=0; 
5277    E2setupFailure_t *e2SetupFailure;
5278
5279    DU_LOG("\nINFO   -->  E2AP : E2 Setup failure received"); 
5280    e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
5281
5282    for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
5283    {
5284       switch(e2SetupFailure->protocolIEs.list.array[arrIdx]->id)
5285       {
5286          case ProtocolIE_IDE2_id_TransactionID:
5287          {
5288             transId = e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
5289             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
5290                   (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
5291             {
5292                memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
5293             }
5294             else
5295             {
5296                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
5297                return ;
5298             }
5299             break;
5300          }
5301          case ProtocolIE_IDE2_id_TimeToWaitE2:
5302             {
5303                timerValue = convertE2WaitTimerEnumToValue(e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
5304                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR)) == FALSE)
5305                {
5306                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR, timerValue);
5307                }
5308                else
5309                {
5310                   DU_LOG("\nERROR   -->  E2AP : EVENT_E2_SETUP_TMR timer is already running");
5311                   return;
5312                }
5313                break; 
5314             }
5315       }
5316    }
5317
5318    freeAperDecodingOfE2SetupFailure(e2SetupFailure);
5319 }
5320 /******************************************************************
5321  *
5322  * @brief Deallocation of memory allocated by aper decoder for RIC service Query
5323  *
5324  * @details
5325  *
5326  *    Function : freeAperDecodingOfRicServiceQuery
5327  *
5328  *    Functionality: Deallocation of memory allocated by aper decoder for RIC
5329  *    service Query
5330  *
5331  * @params[in] RICserviceQuery_t *ricServiceQuery;
5332  * @return void
5333  *
5334  * ****************************************************************/
5335
5336 void freeAperDecodingOfRicServiceQuery(RICserviceQuery_t *ricServiceQuery)
5337 {
5338    uint8_t arrIdx,ranFuncIdx;
5339     RANfunctionsID_List_t *ranFuncAddedList;
5340
5341    if(ricServiceQuery)
5342    {
5343       if(ricServiceQuery->protocolIEs.list.array)
5344       {
5345          for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
5346          {
5347             if(ricServiceQuery->protocolIEs.list.array[arrIdx])
5348             {
5349                switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
5350                {
5351                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5352                   {
5353                      ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5354                      if(ranFuncAddedList->list.array)
5355                      {
5356                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
5357                         {
5358                            free(ranFuncAddedList->list.array[ranFuncIdx]);
5359                         }
5360                         free(ranFuncAddedList->list.array);;
5361                      }
5362                      break;
5363                   }
5364                   default:
5365                      break;
5366                }
5367                free(ricServiceQuery->protocolIEs.list.array[arrIdx]);
5368             }
5369          }
5370          free(ricServiceQuery->protocolIEs.list.array);
5371       }
5372    }
5373 }
5374 /*******************************************************************
5375  *
5376  * @brief Build RanFunction Delete List
5377  *
5378  * @details
5379  *
5380  *    Function : BuildRanFunctionDeleteList
5381  *
5382  * Functionality:  Build RanFunction Delete List
5383  *
5384  * @params[in]
5385  *    RANfunctionsID List
5386  *    Count of the RAN function
5387  *    Received RAN function list
5388  *
5389  * @return ROK     - success
5390  *         RFAILED - failure
5391  *
5392  ******************************************************************/
5393
5394 uint8_t BuildRanFunctionDeleteList(RANfunctionsID_List_t *deleteList, uint8_t count, RanFuncInfo *recvdRanFunc)
5395 {
5396    uint8_t ranFuncIdx=0;
5397    RANfunctionID_ItemIEs_t *delRanFuncItem;
5398
5399    if(count)
5400    {
5401       deleteList->list.count = count;
5402       deleteList->list.size = deleteList->list.count * sizeof(RANfunctionID_ItemIEs_t*);
5403       DU_ALLOC(deleteList->list.array, deleteList->list.size);
5404       if(deleteList->list.array == NULLP)
5405       {
5406          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
5407          return RFAILED;
5408       }
5409       for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
5410       {
5411          DU_ALLOC(deleteList->list.array[ranFuncIdx], sizeof(RANfunctionID_ItemIEs_t));
5412          if(deleteList->list.array[ranFuncIdx] == NULLP)
5413          {
5414             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
5415             return RFAILED;
5416          }
5417          delRanFuncItem= (RANfunctionID_ItemIEs_t *) deleteList->list.array[ranFuncIdx];
5418          delRanFuncItem->id = ProtocolIE_IDE2_id_RANfunctionID_Item;
5419          delRanFuncItem->criticality = CriticalityE2_ignore;
5420          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionID = recvdRanFunc[ranFuncIdx].id;
5421          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionRevision = recvdRanFunc[ranFuncIdx].revisionCounter;
5422
5423       }
5424    }
5425    return ROK;
5426 }
5427 /*******************************************************************
5428  *
5429  * @brief De Allocate  Ric Service Update message
5430  *
5431  * @details
5432  *
5433  *    Function : FreeRicServiceUpdate
5434  *
5435  *    Functionality: De-Allocating Ric Service Update message
5436  *
5437  * @params[in] E2AP_PDU_t *e2apMsg
5438
5439  * @return void
5440  *
5441  * ****************************************************************/
5442
5443 void FreeRicServiceUpdate(E2AP_PDU_t *e2apMsg)
5444 {
5445    uint8_t arrIdx = 0;
5446    uint8_t ranFuncAddListIdx=0, ranFuncDelIdx=0;
5447    RICserviceUpdate_t *ricServiceUpdate;
5448    RANfunctions_List_t *ranFunctionsList;
5449    RANfunction_ItemIEs_t *ranFuncItemIe;
5450    RANfunction_Item_t  *ranFunItem;
5451    RANfunctionsID_List_t *deleteList;
5452
5453    /* De-allocating Memory */
5454    if(e2apMsg != NULLP)
5455    {
5456       if(e2apMsg->choice.initiatingMessage != NULLP)
5457       {
5458          ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
5459          if(ricServiceUpdate->protocolIEs.list.array != NULLP)
5460          {
5461             for(arrIdx = 0; arrIdx < ricServiceUpdate->protocolIEs.list.count; arrIdx++)
5462             {
5463                if(ricServiceUpdate->protocolIEs.list.array[arrIdx] != NULLP)
5464                {
5465                   switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
5466                   {
5467                      case ProtocolIE_IDE2_id_TransactionID:
5468                         break;
5469
5470                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
5471                      case ProtocolIE_IDE2_id_RANfunctionsModified:
5472                         {
5473                            ranFunctionsList = &(ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List);
5474                            if(ranFunctionsList->list.array)
5475                            {
5476                               for(ranFuncAddListIdx= 0; ranFuncAddListIdx< ranFunctionsList->list.count; ranFuncAddListIdx++)
5477                               {
5478                                  if(ranFunctionsList->list.array[ranFuncAddListIdx])
5479                                  {
5480                                     ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncAddListIdx];
5481                                     ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
5482                                     DU_FREE(ranFunItem->ranFunctionOID.buf, ranFunItem->ranFunctionOID.size);
5483                                     DU_FREE(ranFunItem->ranFunctionDefinition.buf, ranFunItem->ranFunctionDefinition.size);
5484                                     DU_FREE(ranFunctionsList->list.array[ranFuncAddListIdx], sizeof(RANfunction_ItemIEs_t));
5485                                  }
5486                               }
5487                               DU_FREE(ranFunctionsList->list.array, ranFunctionsList->list.size);
5488                            }
5489                            break;
5490                         }
5491                      case ProtocolIE_IDE2_id_RANfunctionsDeleted:
5492                         {
5493                            deleteList= &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5494                            if(deleteList->list.array)
5495                            {
5496                               for(ranFuncDelIdx = 0; ranFuncDelIdx< deleteList->list.count; ranFuncDelIdx++)
5497                               {
5498                                  DU_FREE(deleteList->list.array[ranFuncDelIdx], sizeof(RANfunctionID_ItemIEs_t));
5499                               }
5500                               DU_FREE(deleteList->list.array, deleteList->list.size);
5501   
5502                            }
5503                            break;
5504                         }
5505                      default:
5506                         DU_LOG("\nERROR  --> E2AP: Invalid event at ricServiceUpdate %ld ",\
5507                               (ricServiceUpdate->protocolIEs.list.array[arrIdx]->id));
5508                         break;
5509                   }
5510                   DU_FREE(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
5511                }
5512             }
5513             DU_FREE(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
5514          }
5515          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5516       }
5517       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
5518    }
5519 }
5520
5521 /*******************************************************************
5522  *
5523  * @brief Builds and Send the RicServiceUpdateuest
5524  *
5525  * @details
5526  *
5527  *    Function : BuildAndSendRicServiceUpdate
5528  *
5529  * Functionality:Fills the RicServiceUpdateuest
5530  *
5531  * @return ROK     - success
5532  *         RFAILED - failure
5533  *
5534  ******************************************************************/
5535
5536 uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate)
5537 {
5538    uint8_t arrIdx = 0, elementCnt=0;
5539    uint8_t transId = 0, ret = RFAILED;
5540    bool memAllocFailed =false;
5541    E2AP_PDU_t        *e2apMsg = NULLP;
5542    RICserviceUpdate_t  *ricServiceUpdate = NULLP;
5543    asn_enc_rval_t     encRetVal;       /* Encoder return value */
5544
5545    DU_LOG("\nINFO   -->  E2AP : Building Ric Service Update\n");
5546    do
5547    {
5548       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
5549       if(e2apMsg == NULLP)
5550       {
5551          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
5552          break;
5553       }
5554       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
5555       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5556       if(e2apMsg->choice.initiatingMessage == NULLP)
5557       {
5558          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
5559          break;
5560       }
5561       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
5562       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
5563       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceUpdate;
5564       ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
5565       
5566       /* For TransId IE, set elementCnt to 1.
5567       If there is any item in the RAN function add list, RAN function modification list, or RAN function delete list, increment the elementCnt.*/
5568
5569       elementCnt =1;
5570       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5571         elementCnt++;
5572       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
5573          elementCnt++;
5574       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
5575          elementCnt++;
5576        
5577       ricServiceUpdate->protocolIEs.list.count = elementCnt;
5578       ricServiceUpdate->protocolIEs.list.size = elementCnt * sizeof(RICserviceUpdate_IEs_t*);
5579
5580       /* Initialize the E2Setup members */
5581       DU_ALLOC(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
5582       if(ricServiceUpdate->protocolIEs.list.array == NULLP)
5583       {
5584          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
5585          break;
5586       }
5587       
5588       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
5589       {
5590          DU_ALLOC(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
5591          if(ricServiceUpdate->protocolIEs.list.array[arrIdx] == NULLP)
5592          {
5593             memAllocFailed = true;
5594             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayIdx [%d]", arrIdx);
5595             break;
5596          }
5597       }
5598       if(memAllocFailed == true)
5599          break;
5600
5601       arrIdx = 0;
5602
5603       /* TransactionID */
5604       ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
5605       ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5606       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
5607       if(serviceUpdate.dir == E2_NODE_INITIATED)
5608          transId = assignTransactionId();
5609       else
5610         transId = serviceUpdate.transId;
5611       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
5612
5613       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5614       {
5615          arrIdx++;
5616          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAdded;
5617          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5618          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
5619          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,\
5620          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded, serviceUpdate.recvRanFuncList.ranFunToBeAdded) !=ROK)
5621          {
5622             break;
5623          }
5624       }
5625
5626       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
5627       {
5628          arrIdx++;
5629          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsModified;
5630          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5631          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
5632          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,
5633          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeModified, serviceUpdate.recvRanFuncList.ranFunToBeModified) !=ROK)
5634          {
5635             break;
5636          }
5637       }
5638
5639       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
5640       {
5641          arrIdx++;
5642          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsDeleted;
5643          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5644          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctionsID_List;
5645          if(BuildRanFunctionDeleteList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List,\
5646          serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted, serviceUpdate.recvRanFuncList.ranFunToBeDeleted) != ROK)
5647          {
5648             break;
5649          }
5650       }
5651       /* Prints the Msg formed */
5652       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5653
5654       memset(encBuf, 0, ENC_BUF_MAX_LEN);
5655       encBufSize = 0;
5656       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
5657       if(encRetVal.encoded == ENCODE_FAIL)
5658       {
5659          DU_LOG("\nERROR  -->  E2AP : Could not encode RicServiceUpdateuest structure (at %s)\n",\
5660                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
5661          break;
5662       }
5663       else
5664       {
5665          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RicServiceUpdateuest\n");
5666 #ifdef DEBUG_ASN_PRINT
5667          for(int i=0; i< encBufSize; i++)
5668          {
5669             printf("%x",encBuf[i]);
5670          }
5671 #endif
5672       }
5673       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
5674       {
5675          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
5676          break;
5677       }
5678       ret = ROK;
5679       break;
5680    }while(true);
5681    
5682    if(ret == ROK)
5683    {
5684       if(serviceUpdate.dir == E2_NODE_INITIATED)
5685       {
5686          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
5687          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5688       }
5689       else
5690       {
5691          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId = transId;
5692          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5693       }
5694       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.dir = serviceUpdate.dir;
5695       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.transId =transId;
5696       memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.recvRanFuncList, &serviceUpdate.recvRanFuncList, sizeof(E2TmpRanFunList));
5697    }
5698    FreeRicServiceUpdate(e2apMsg);
5699    return ret;
5700 }
5701 /******************************************************************
5702  *
5703  * @brief Processes RIC service Query sent by RIC
5704  *
5705  * @details
5706  *
5707  *    Function : procRicServiceQuery
5708  *
5709  *    Functionality: Processes RIC service Query sent by RIC
5710  *
5711  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5712  * @return ROK     - success
5713  *         RFAILED - failure
5714  *
5715  * ****************************************************************/
5716
5717 void procRicServiceQuery(E2AP_PDU_t *e2apMsg)
5718 {
5719    ConfigType action;
5720    uint16_t arrIdx =0, ranFuncIdx=0,tmpIdx=0;
5721    uint16_t id,revisionCcounter;
5722    bool tmpArray[MAX_RAN_FUNCTION] = {false};
5723    RICserviceQuery_t *ricServiceQuery=NULL;
5724    RicServiceUpdate ricUpdate;
5725    RANfunctionID_ItemIEs_t *ranFuncAddedItemIe;
5726    RANfunctionsID_List_t *ranFuncAddedList;
5727
5728    DU_LOG("\nINFO   -->  E2AP : RIC Service Query received");
5729    memset(&ricUpdate, 0, sizeof(RicServiceUpdate));
5730    ricUpdate.dir = RIC_INITIATED;
5731    ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
5732
5733    for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
5734    {
5735       switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
5736       {
5737          /* TODO completing in next patch/gerrit */
5738          case ProtocolIE_IDE2_id_TransactionID:
5739          {
5740             ricUpdate.transId = ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
5741             break;
5742          }
5743
5744          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5745          {
5746             ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5747             if(ranFuncAddedList->list.array)
5748             {
5749                for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
5750                {
5751                   if(ranFuncAddedList->list.array[ranFuncIdx])
5752                   {
5753                      /* Using the RAN function Id, identify the RAN function to be modified or deleted.  */
5754                      
5755                      ranFuncAddedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAddedList->list.array[ranFuncIdx];
5756                      id = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionID;
5757                      revisionCcounter = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision;
5758                      
5759                      if((id != duCb.e2apDb.ranFunction[id-1].id))
5760                      {
5761                         action = CONFIG_DEL;
5762                      }
5763                      else if((id == duCb.e2apDb.ranFunction[id-1].id)&&(revisionCcounter!=duCb.e2apDb.ranFunction[id-1].revisionCounter))
5764                      {
5765                         action = CONFIG_MOD;
5766                      }
5767
5768                      if(action == CONFIG_DEL)
5769                      {
5770                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].id = id;
5771                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].revisionCounter = revisionCcounter;
5772                         ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted++;
5773                      }
5774                      else if(action == CONFIG_MOD)
5775                      {
5776                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].id = id;
5777                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].revisionCounter = revisionCcounter;
5778                         ricUpdate.recvRanFuncList.numOfRanFunToBeModified++;
5779                      }
5780
5781                      /* If any ID is set to true, it means that the ID has been used in either modification or deletion list. 
5782                       * Else we will add the IDs into the added list */
5783                      tmpArray[id-1] = true;
5784                   }
5785                }
5786             }
5787             break;
5788          }
5789       }
5790    }
5791
5792    /*  Traversing the whole RAN function list in ducb to check if any new Ran function ids have been added. */
5793    for(arrIdx =0; arrIdx<MAX_RAN_FUNCTION; arrIdx++)
5794    {
5795       tmpIdx= ricUpdate.recvRanFuncList.numOfRanFunToBeAdded;
5796       if((duCb.e2apDb.ranFunction[arrIdx].id >0)&&(!tmpArray[arrIdx]))
5797       {
5798          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[arrIdx].id;
5799          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[arrIdx].revisionCounter;
5800          ricUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
5801       }
5802    }
5803
5804    if(BuildAndSendRicServiceUpdate(ricUpdate)!= ROK)
5805    {
5806       DU_LOG("\nERROR  -->  E2AP : Failed to build and send ric service update message");
5807    }
5808
5809    freeAperDecodingOfRicServiceQuery(ricServiceQuery);
5810 }
5811
5812 /******************************************************************
5813  *
5814  * @brief Deallocation of memory allocated by aper decoder for 
5815  *    RIC service update ack
5816  *
5817  * @details
5818  *
5819  *    Function : freeAperDecodingOfRicServiceUpdateAck
5820  *
5821  *    Functionality: Deallocation of memory allocated by aper decoder 
5822  *    for RIC service update ack
5823  *
5824  * @params[in] RICserviceUpdateAck_t *ricServiceAck;
5825  * @return void
5826  *
5827  * ****************************************************************/
5828
5829 void freeAperDecodingOfRicServiceUpdateAck(RICserviceUpdateAcknowledge_t *ricServiceAck)
5830 {
5831    uint8_t arrIdx=0,ranFuncIdx=0;
5832    RANfunctionsID_List_t *ranFuncAddedList=NULL;
5833
5834    if(ricServiceAck)
5835    {
5836       if(ricServiceAck->protocolIEs.list.array)
5837       {
5838          for(arrIdx=0; arrIdx<ricServiceAck->protocolIEs.list.count; arrIdx++)
5839          {
5840             if(ricServiceAck->protocolIEs.list.array[arrIdx])
5841             {
5842                switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id)
5843                {
5844                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5845                   {
5846                      ranFuncAddedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5847                      if(ranFuncAddedList->list.array)
5848                      {
5849                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
5850                         {
5851                            free(ranFuncAddedList->list.array[ranFuncIdx]);
5852                         }
5853                         free(ranFuncAddedList->list.array);
5854                      }
5855                      break;
5856                   }
5857                   default:
5858                      break;
5859                }
5860                free(ricServiceAck->protocolIEs.list.array[arrIdx]);  
5861             }
5862          }
5863          free(ricServiceAck->protocolIEs.list.array);
5864       }
5865    }
5866 }
5867
5868 /******************************************************************
5869  *
5870  * @brief Processes RIC service update ack sent by RIC
5871  *
5872  * @details
5873  *
5874  *    Function : procRicServiceUpdateAck
5875  *
5876  *    Functionality: Processes RIC service update ack sent by RIC
5877  *
5878  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5879  * @return ROK     - success
5880  *         RFAILED - failure
5881  *
5882  * ****************************************************************/
5883
5884 void procRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
5885 {
5886    uint8_t arrIdx =0, transId =0; 
5887    uint16_t id =0, tmpIdx=0, ranFuncIdx=0;
5888    RicServiceUpdate serviceUpdate;
5889    RANfunctionsIDcause_List_t *rejectedList=NULL;
5890    RICserviceUpdateAcknowledge_t *ricServiceAck=NULL;
5891    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
5892    
5893    DU_LOG("\nINFO   -->  E2AP : RIC service update ack received"); 
5894    memset(&serviceUpdate, 0, sizeof(RicServiceUpdate));
5895    ricServiceAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
5896    
5897    for(arrIdx=0; arrIdx<ricServiceAck->protocolIEs.list.count; arrIdx++)
5898    {
5899       switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id)
5900       {
5901          case ProtocolIE_IDE2_id_TransactionID:
5902          {
5903             transId = ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
5904             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
5905             (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
5906             {
5907               memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
5908             }
5909             else if((duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId == transId) &&\
5910             (duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
5911             {
5912               memset(&duCb.e2apDb.e2TransInfo.ricInitTransaction[transId], 0, sizeof(E2TransInfo));
5913             }
5914             else
5915             {
5916                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
5917                return ;
5918             }
5919             break;
5920          }
5921          
5922          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5923             break;
5924
5925          case ProtocolIE_IDE2_id_RANfunctionsRejected:
5926          {
5927             rejectedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
5928             if(rejectedList->list.array)
5929             {
5930                for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
5931                {
5932                   ranFuncRejectedItemIe =  (RANfunctionIDcause_ItemIEs_t*)rejectedList->list.array[ranFuncIdx];
5933                   id = ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID;
5934                   tmpIdx= serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded;
5935                   serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[id-1].id;
5936                   serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[id-1].revisionCounter;
5937                   serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
5938                }
5939             }
5940             break;
5941          }
5942
5943       }
5944    }
5945
5946    if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5947    {
5948       serviceUpdate.dir = E2_NODE_INITIATED;
5949       BuildAndSendRicServiceUpdate(serviceUpdate);
5950    }
5951    freeAperDecodingOfRicServiceUpdateAck(ricServiceAck);
5952 }
5953
5954 /******************************************************************
5955  *
5956  * @brief Deallocation of memory allocated by aper decoder for 
5957  *       RIC service update failure
5958  *
5959  * @details
5960  *
5961  *    Function : freeAperDecodingOfRicServiceUpdateFailure
5962  *
5963  *    Functionality: Deallocation of memory allocated by aper decoder 
5964  *    for RIC service update failure
5965  *
5966  * @params[in] RICserviceUpdateFailure_t *ricServiceFailure;
5967  * @return void
5968  *
5969  * ****************************************************************/
5970
5971 void freeAperDecodingOfRicServiceUpdateFailure(RICserviceUpdateFailure_t *ricServiceFailure)
5972 {
5973    uint8_t arrIdx=0;
5974
5975    if(ricServiceFailure)
5976    {
5977       if(ricServiceFailure->protocolIEs.list.array)
5978       {
5979          for(arrIdx=0; arrIdx<ricServiceFailure->protocolIEs.list.count; arrIdx++)
5980          {
5981             if(ricServiceFailure->protocolIEs.list.array[arrIdx])
5982             {
5983                free(ricServiceFailure->protocolIEs.list.array[arrIdx]);  
5984             }
5985          }
5986          free(ricServiceFailure->protocolIEs.list.array);
5987       }
5988    }
5989 }
5990
5991 /******************************************************************
5992  *
5993  * @brief Processes RIC service update failure sent by RIC
5994  *
5995  * @details
5996  *
5997  *    Function : procRicServiceUpdateFailure
5998  *
5999  *    Functionality: Processes RIC service update failure sent by RIC
6000  *
6001  * @params[in] E2AP_PDU_t ASN decoded E2AP message
6002  * @return ROK     - success
6003  *         RFAILED - failure
6004  *
6005  * ****************************************************************/
6006
6007 void procRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
6008 {
6009    uint8_t arrIdx =0, timerValue=0; 
6010    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
6011
6012    DU_LOG("\nINFO   -->  E2AP : RIC service update failure received"); 
6013    ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
6014
6015    for(arrIdx=0; arrIdx<ricServiceFailure->protocolIEs.list.count; arrIdx++)
6016    {
6017       switch(ricServiceFailure->protocolIEs.list.array[arrIdx]->id)
6018       {
6019          case ProtocolIE_IDE2_id_TransactionID:
6020             {
6021                break;
6022             }
6023          case ProtocolIE_IDE2_id_TimeToWaitE2:
6024             {
6025                timerValue = convertE2WaitTimerEnumToValue(ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
6026                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR)) == FALSE)
6027                {
6028                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR, timerValue);
6029                }
6030                else
6031                {
6032                   DU_LOG("\nERROR   -->  E2AP : EVENT_RIC_SERVICE_UPDATE_TMR  timer is already running");
6033                   return;
6034                }
6035                break; 
6036             }
6037          case ProtocolIE_IDE2_id_CauseE2:
6038             {
6039                break;
6040             }
6041       }
6042    }
6043
6044    freeAperDecodingOfRicServiceUpdateFailure(ricServiceFailure);
6045 }
6046
6047 /******************************************************************
6048  *
6049  * @brief DU Send E2 Node Configuration Update
6050  *
6051  * @details
6052  *
6053  *    Function : duSendE2NodeConfigurationUpdate 
6054  *
6055  *    Functionality: DU Send E2 Node Configuration Update
6056  *
6057  * @return ROK     - success
6058  *         RFAILED - failure
6059  *
6060  * ****************************************************************/
6061
6062 uint8_t duSendE2NodeConfigurationUpdate()
6063 {
6064    E2NodeConfigList e2NodeList;
6065    CmLList *node =NULL;
6066    E2NodeComponent *e2NodeComponentInfo=NULL;
6067
6068    memset(&e2NodeList, 0, sizeof(E2NodeConfigList));
6069    CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node);
6070    while(node)
6071    {
6072       e2NodeComponentInfo = (E2NodeComponent*)node->node;
6073
6074       if(e2NodeComponentInfo->addConfiguration)
6075       {
6076          e2NodeList.addE2Node[e2NodeList.addE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
6077          e2NodeList.addE2Node[e2NodeList.addE2NodeCount].componentId= e2NodeComponentInfo->componentId;
6078          e2NodeList.addE2NodeCount++;
6079          break;
6080       }
6081       if(e2NodeComponentInfo->updateConfiguration)
6082       {
6083          e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
6084          e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].componentId= e2NodeComponentInfo->componentId;
6085          e2NodeList.updateE2NodeCount++;
6086          break;
6087       }
6088       if(e2NodeComponentInfo->deleteConfiguration == true)
6089       {
6090          e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
6091          e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].componentId = e2NodeComponentInfo->componentId;
6092          e2NodeList.removeE2NodeCount++;
6093          break;
6094       }
6095       node = node->next;
6096    }
6097
6098    if(BuildAndSendE2NodeConfigUpdate(&e2NodeList) !=ROK)
6099    {
6100       DU_LOG("\nERROR  -->  E2AP : Failed to build and send e2 node config update message to RIC_stub");
6101       return RFAILED;
6102    }
6103    return ROK;
6104 }
6105
6106 /*******************************************************************
6107  *
6108  * @brief Free RIC Subscription Modification Required
6109  *
6110  * @details
6111  *
6112  *    Function : FreeRicSubsModRequired
6113  *
6114  * Functionality: Freqq RIC Subscription Modification required
6115  *
6116  * @param  E2AP Message PDU to be freed
6117  * @return void
6118  *
6119  ******************************************************************/
6120 void FreeRicSubsModRequired(E2AP_PDU_t *e2apMsg)
6121 {
6122    uint8_t ieIdx = 0, arrIdx = 0;
6123    RICsubscriptionModificationRequired_t  *ricSubsModReqd = NULLP;
6124    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
6125    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
6126    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
6127
6128    if(e2apMsg)
6129    {
6130       if(e2apMsg->choice.initiatingMessage)
6131       {
6132          ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired;
6133          if(ricSubsModReqd->protocolIEs.list.array)
6134          {
6135             for(ieIdx = 0; ieIdx < ricSubsModReqd->protocolIEs.list.count; ieIdx++)
6136             {
6137                if(ricSubsModReqd->protocolIEs.list.array[ieIdx])
6138                {
6139                   ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6140                   switch(ricSubsModReqdIe->id)
6141                   {
6142                      case ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List:
6143                         {
6144                            actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
6145                            if(actionToBeModList->list.array)
6146                            {
6147                               for(arrIdx = 0; arrIdx < actionToBeModList->list.count; arrIdx++)
6148                               { 
6149                                  DU_FREE(actionToBeModList->list.array[arrIdx], \
6150                                     sizeof(RICaction_RequiredToBeModified_ItemIEs_t));
6151                               }
6152                               DU_FREE(actionToBeModList->list.array, actionToBeModList->list.size);
6153                            }
6154                            break;
6155                         }
6156
6157                      case ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List:
6158                         {
6159                            actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
6160                            if(actionToBeRmvList->list.array)
6161                            {
6162                               for(arrIdx = 0; arrIdx < actionToBeRmvList->list.count; arrIdx++)
6163                               { 
6164                                  DU_FREE(actionToBeRmvList->list.array[arrIdx], \
6165                                     sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t));
6166                               }
6167                               DU_FREE(actionToBeRmvList->list.array, actionToBeRmvList->list.size);
6168                            }
6169                            break;
6170                         }
6171
6172                      default:
6173                         break;
6174                   }
6175                   DU_FREE(ricSubsModReqd->protocolIEs.list.array[ieIdx], \
6176                         sizeof(RICsubscriptionModificationRequired_IEs_t));
6177                }
6178             }
6179             DU_FREE(ricSubsModReqd->protocolIEs.list.array, ricSubsModReqd->protocolIEs.list.size);
6180          }
6181          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
6182       }
6183       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
6184    }
6185 }
6186
6187 /* A RIC Subscription includes RIC subsequent action only for RIC Insert service.
6188  * However, E2SM-KPM supports only RIC Report service.
6189  * Hence there is no subsequent action in RIC subscription that may require modification.
6190  * So commenting the action-modification IEs for the time being
6191  */
6192 #if 0
6193 /*******************************************************************
6194  *
6195  * @brief Fill Action required to be modified list
6196  *
6197  * @details
6198  *
6199  *    Function : FillActionReqdToBeModList
6200  *
6201  * Functionality: Fill Action required to be modified list
6202  *
6203  * @param  RIC Actions Required To Be Modified List to be filled
6204  *         Number of actions to be modified
6205  *         RIC Subscription DB
6206  * @return ROK     - success
6207  *         RFAILED - failure
6208  *
6209  ******************************************************************/
6210 uint8_t FillActionReqdToBeModList(RICactions_RequiredToBeModified_List_t *actionToBeModList, uint8_t numActionsMod, \
6211    RicSubscription *ricSubscription)
6212 {
6213    uint8_t arrIdx = 0, actionIdx = 0;
6214    RICaction_RequiredToBeModified_ItemIEs_t *actionToBeMod = NULL;
6215
6216    actionToBeModList->list.count = numActionsMod;
6217    actionToBeModList->list.size = numActionsMod * sizeof(RICaction_RequiredToBeModified_ItemIEs_t *);
6218    DU_ALLOC(actionToBeModList->list.array, actionToBeModList->list.size);
6219    if(!actionToBeModList->list.array)
6220    {
6221       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6222       return RFAILED;
6223    }
6224
6225    arrIdx = 0;
6226    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
6227    {
6228       if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD)
6229       {
6230          DU_ALLOC(actionToBeModList->list.array[arrIdx], sizeof(RICaction_RequiredToBeModified_ItemIEs_t));
6231          if(!actionToBeModList->list.array[arrIdx])
6232          {
6233             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6234             return RFAILED;
6235          }
6236          actionToBeMod = (RICaction_RequiredToBeModified_ItemIEs_t *)actionToBeModList->list.array[arrIdx];
6237
6238          actionToBeMod->id = ProtocolIE_IDE2_id_RICaction_RequiredToBeModified_Item;
6239          actionToBeMod->criticality = CriticalityE2_reject;
6240          actionToBeMod->value.present = \
6241             RICaction_RequiredToBeModified_ItemIEs__value_PR_RICaction_RequiredToBeModified_Item;
6242          actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricActionID = \
6243             ricSubscription->actionSequence[actionIdx].actionId;
6244          actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricTimeToWait = RICtimeToWait_w5ms;
6245
6246          arrIdx++;
6247       }
6248    }
6249
6250    return ROK;
6251 }
6252 #endif
6253
6254 /*******************************************************************
6255  *
6256  * @brief Fill Action required to be removed list
6257  *
6258  * @details
6259  *
6260  *    Function : FillActionReqdToBeRmvList
6261  *
6262  * Functionality: Fill Action required to be removed list
6263  *
6264  * @param  RIC Actions Required To Be Removed List to be filled
6265  *         Number of actions to be removed
6266  *         RIC Subscription DB
6267  * @return ROK     - success
6268  *         RFAILED - failure
6269  *
6270  ******************************************************************/
6271 uint8_t FillActionReqdToBeRmvList(RICactions_RequiredToBeRemoved_List_t *actionToBeRmvList, uint8_t numActionsRmv, \
6272    RicSubscription *ricSubscription)
6273 {
6274    uint8_t arrIdx = 0, actionIdx = 0;
6275    RICaction_RequiredToBeRemoved_ItemIEs_t *actionToBeRmv = NULL;
6276
6277    actionToBeRmvList->list.count = numActionsRmv;
6278    actionToBeRmvList->list.size = numActionsRmv * sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t *);
6279    DU_ALLOC(actionToBeRmvList->list.array, actionToBeRmvList->list.size);
6280    if(!actionToBeRmvList->list.array)
6281    {
6282       DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6283       return RFAILED;
6284    }
6285
6286    arrIdx = 0;
6287    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
6288    {
6289       if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL)
6290       {
6291          DU_ALLOC(actionToBeRmvList->list.array[arrIdx], sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t));
6292          if(!actionToBeRmvList->list.array[arrIdx])
6293          {
6294             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6295             return RFAILED;
6296          }
6297          actionToBeRmv = (RICaction_RequiredToBeRemoved_ItemIEs_t *)actionToBeRmvList->list.array[arrIdx];
6298
6299          actionToBeRmv->id = ProtocolIE_IDE2_id_RICaction_RequiredToBeRemoved_Item;
6300          actionToBeRmv->criticality = CriticalityE2_reject;
6301          actionToBeRmv->value.present = \
6302             RICaction_RequiredToBeRemoved_ItemIEs__value_PR_RICaction_RequiredToBeRemoved_Item;
6303          actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.ricActionID = \
6304             ricSubscription->actionSequence[actionIdx].actionId;
6305          fillE2Cause(&actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.cause, \
6306             ricSubscription->actionSequence[actionIdx].failureCause);
6307
6308          arrIdx++;
6309       }
6310    }
6311
6312    return ROK;
6313 }
6314
6315 /*******************************************************************
6316  *
6317  * @brief Fill RIC Subscription Modification Required IEs
6318  *
6319  * @details
6320  *
6321  *    Function : FillRicSubsModRequired
6322  *
6323  * Functionality: Fill RIC Subscription Modification Required IEs
6324  *
6325  * @param  RIC Subscription Modification Required IEs to be filled
6326  *         RIC Subscription DB
6327  * @return ROK     - success
6328  *         RFAILED - failure
6329  *
6330  ******************************************************************/
6331 uint8_t FillRicSubsModRequired(RICsubscriptionModificationRequired_t *ricSubsModReqd, RicSubscription *ricSubscription)
6332 {
6333    uint8_t ieIdx = 0, elementCnt=0, actionIdx = 0;
6334    uint8_t numActionsMod = 0, numActionsRmv = 0;
6335    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
6336    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
6337
6338 /* Unused in case of E2SM-KPM */
6339 #if 0
6340    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
6341 #endif
6342
6343    /* Count number of Actions to be modified or deleted */
6344    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
6345    {
6346       if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD)
6347          numActionsMod++;
6348       else if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL)
6349          numActionsRmv++;
6350    }
6351
6352    /* Count number of IEs to be added to messages */
6353    elementCnt = 2;
6354    if(numActionsMod)
6355       elementCnt++;
6356    if(numActionsRmv)
6357       elementCnt++;
6358
6359    ricSubsModReqd->protocolIEs.list.count = elementCnt;
6360    ricSubsModReqd->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationRequired_IEs_t *);
6361    DU_ALLOC(ricSubsModReqd->protocolIEs.list.array, ricSubsModReqd->protocolIEs.list.size);
6362    if(!ricSubsModReqd->protocolIEs.list.array)
6363    {
6364       DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6365       return RFAILED;
6366    }
6367
6368    for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
6369    {
6370       DU_ALLOC(ricSubsModReqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRequired_IEs_t));
6371       if(!ricSubsModReqd->protocolIEs.list.array[ieIdx])
6372       {
6373          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6374          return RFAILED;
6375       }
6376    }
6377
6378    /* RIC Request ID */
6379    ieIdx = 0;
6380    ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6381    ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICrequestID;
6382    ricSubsModReqdIe->criticality = CriticalityE2_reject;
6383    ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RICrequestID;
6384    ricSubsModReqdIe->value.choice.RICrequestID.ricRequestorID = ricSubscription->requestId.requestorId;
6385    ricSubsModReqdIe->value.choice.RICrequestID.ricInstanceID = ricSubscription->requestId.instanceId;
6386
6387    /* RAN Function ID */
6388    ieIdx++;
6389    ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6390    ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RANfunctionID;
6391    ricSubsModReqdIe->criticality = CriticalityE2_reject;
6392    ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RANfunctionID;
6393    ricSubsModReqdIe->value.choice.RANfunctionID = ricSubscription->ranFuncId;
6394
6395 /* A RIC Subscription includes RIC subsequent action only for RIC Insert service.
6396  * However, E2SM-KPM supports only RIC Report service.
6397  * Hence there is no subsequent action in RIC subscription that may require modification.
6398  * So commenting the action-modification IEs for the time being
6399  */
6400 #if 0
6401    /* RIC Actions Required to be Modified */
6402    if(numActionsMod)
6403    {
6404       ieIdx++;
6405       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6406       ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List;
6407       ricSubsModReqdIe->criticality = CriticalityE2_reject;
6408       ricSubsModReqdIe->value.present = \
6409          RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeModified_List;
6410       actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
6411
6412       if(FillActionReqdToBeModList(actionToBeModList, numActionsMod, ricSubscription) != ROK)
6413       {
6414          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill actions required to be modified list", __func__);
6415          return RFAILED;
6416       }
6417    }
6418 #endif
6419
6420    /* RIC Actions Required to be removed */
6421    if(numActionsRmv)
6422    {
6423       ieIdx++;
6424       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6425       ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List;
6426       ricSubsModReqdIe->criticality = CriticalityE2_reject;
6427       ricSubsModReqdIe->value.present = \
6428          RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeRemoved_List;
6429       actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
6430
6431       if(FillActionReqdToBeRmvList(actionToBeRmvList, numActionsRmv, ricSubscription) != ROK)
6432       {
6433          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill actions required to be removed list", __func__);
6434          return RFAILED;
6435       }
6436    }
6437
6438    return ROK;
6439 }
6440
6441 /*******************************************************************
6442  *
6443  * @brief Builds and Send RIC Subscription Modification Required
6444  *        message
6445  *
6446  * @details
6447  *
6448  *    Function : BuildAndSendRicSubsModRequired
6449  *
6450  * Functionality:  Builds and Send RIC Subscription Modification 
6451  *    Required message
6452  *
6453  * @param  RIC Subscription DB
6454  * @return ROK     - success
6455  *         RFAILED - failure
6456  *
6457  ******************************************************************/
6458 uint8_t BuildAndSendRicSubsModRequired(RicSubscription *ricSubscription)
6459 {
6460    uint8_t ret = RFAILED;
6461    E2AP_PDU_t        *e2apMsg = NULLP;
6462    RICsubscriptionModificationRequired_t  *ricSubsModReqd = NULLP;
6463    asn_enc_rval_t     encRetVal;       /* Encoder return value */
6464
6465    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Required \n");
6466    while(true)
6467    {
6468       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
6469       if(e2apMsg == NULLP)
6470       {
6471          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6472          break;
6473       }
6474
6475       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
6476       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
6477       if(e2apMsg->choice.initiatingMessage == NULLP)
6478       {
6479          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6480          break;
6481       }
6482       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
6483       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired;
6484       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionModificationRequired;
6485
6486       ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired;
6487
6488       if(FillRicSubsModRequired(ricSubsModReqd, ricSubscription) != ROK)
6489       {
6490          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Subscription Modification Required IEs", __func__);
6491          break;
6492       }
6493       
6494       /* Encode */
6495       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6496
6497       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6498       encBufSize = 0;
6499       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6500       if(encRetVal.encoded == ENCODE_FAIL)
6501       {
6502          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Modifiction Required structure (at %s)\n",\
6503                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6504          break;
6505       }
6506       else
6507       {
6508          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RIC Subscription Modification Required \n");
6509 #ifdef DEBUG_ASN_PRINT
6510          for(int i=0; i< encBufSize; i++)
6511          {
6512             printf("%x",encBuf[i]);
6513          }
6514 #endif
6515       }
6516       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
6517       {
6518          DU_LOG("\nERROR  -->  E2AP : Sending RIC Subscription Modification Required failed");
6519       }
6520
6521       ret = ROK;
6522       break;
6523    }
6524
6525    /* Free RIC Subscription modification required */
6526    FreeRicSubsModRequired(e2apMsg);
6527    return ret;
6528 }
6529
6530 /*******************************************************************
6531  *
6532  * @brief Free APER decoding of RIC Subscription Modification Confirm
6533  *
6534  * @details
6535  *
6536  *    Function : freeAperDecodingOfRicSubsModConfirm
6537  *
6538  * Functionality:  Free APER decoding of RIC Subscription 
6539  *   Modification Confirm
6540  *
6541  * @param  E2AP Message PDU
6542  * @return void
6543  *
6544  ******************************************************************/
6545 void freeAperDecodingOfRicSubsModConfirm(E2AP_PDU_t *e2apMsg)
6546 {
6547    uint8_t ieIdx = 0, arrIdx=0;
6548    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
6549    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
6550    RICactions_ConfirmedForModification_List_t *modCfmList = NULLP;
6551    RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP;
6552    RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP;
6553    RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP;
6554
6555    if(e2apMsg && e2apMsg->choice.successfulOutcome)
6556    {
6557       ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
6558       if(ricSubsModCfm->protocolIEs.list.array)
6559       {
6560          for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++)
6561          {
6562             if(ricSubsModCfm->protocolIEs.list.array[ieIdx])
6563             {
6564                ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
6565                switch(ricSubsModCfmIe->id)
6566                {
6567                   case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List:
6568                      {
6569                         modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List;
6570                         if(modCfmList->list.array)
6571                         {
6572                            for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
6573                            {
6574                               if(modCfmList->list.array[arrIdx])
6575                                  free(modCfmList->list.array[arrIdx]);
6576                            }
6577                            free(modCfmList->list.array);
6578                         }
6579                         break;
6580                      }
6581
6582                   case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List:
6583                      {
6584                         modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List;
6585                         if(modRefusedList->list.array)
6586                         {
6587                            for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
6588                            {
6589                               if(modRefusedList->list.array[arrIdx])
6590                                  free(modRefusedList->list.array[arrIdx]);
6591                            }
6592                            free(modRefusedList->list.array);
6593                         }
6594                         break;
6595                      }
6596
6597                   case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List:
6598                      {
6599                         rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List;
6600                         if(rmvCfmList->list.array)
6601                         {
6602                            for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
6603                            {
6604                               if(rmvCfmList->list.array[arrIdx])
6605                                  free(rmvCfmList->list.array[arrIdx]);
6606                            }
6607                            free(rmvCfmList->list.array);
6608                         }
6609                         break;
6610                      }
6611
6612                   case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List:
6613                      {
6614                         rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List;
6615                         if(rmvFailList->list.array)
6616                         {
6617                            for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
6618                            {
6619                               if(rmvFailList->list.array[arrIdx])
6620                                  free(rmvFailList->list.array[arrIdx]);
6621                            }
6622                            free(rmvFailList->list.array);
6623                         }
6624                         break;
6625                      }
6626
6627                   default:
6628                      break;
6629
6630                }
6631                free(ricSubsModCfmIe);
6632             }
6633          }
6634          free(ricSubsModCfm->protocolIEs.list.array);
6635       }
6636    }
6637 }
6638
6639 /*******************************************************************
6640  *
6641  * @brief Process RIC Subscription Modification Confirm Message
6642  *
6643  * @details
6644  *
6645  *    Function : procRicSubscriptionModificationConfirm
6646  *
6647  * Functionality:  Process RIC Subscription Modification Confirm
6648  *    Message received from RIC. 
6649  *
6650  * @param  E2AP Message PDU
6651  * @return void
6652  *
6653  ******************************************************************/
6654 void procRicSubscriptionModificationConfirm(E2AP_PDU_t *e2apMsg)
6655 {
6656    uint8_t actionId = 0, ieIdx = 0, arrIdx = 0;
6657    uint16_t ranFuncId = 0;
6658    bool procFailure = false;
6659    RicRequestId ricReqId;
6660    RanFunction *ranFuncDb = NULLP;
6661    CmLList *ricSubsNode = NULLP;
6662    RicSubscription *ricSubsDb = NULLP;
6663    ActionInfo *actionDb = NULLP;
6664
6665    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
6666    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
6667
6668 /* Not used in case of E2SM-KPM */
6669 #if 0
6670    RICactions_ConfirmedForModification_List_t *modCfmList = NULLP;
6671    RICaction_ConfirmedForModification_ItemIEs_t *modCfmListItem = NULLP;
6672
6673    RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP;
6674    RICaction_RefusedToBeModified_ItemIEs_t *modRefusedListItem = NULLP;
6675 #endif
6676
6677    RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP;
6678    RICaction_ConfirmedForRemoval_ItemIEs_t *rmvCfmListItem = NULLP;
6679
6680    RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP;
6681    RICaction_RefusedToBeRemoved_ItemIEs_t *rmvFailListItem = NULLP;
6682
6683    DU_LOG("\nINFO   -->  E2AP : %s: Received RIC Subscription Modification Confirm", __func__);
6684
6685    do{
6686       if(!e2apMsg)
6687       {
6688          DU_LOG("\nERROR  -->  E2AP : %s: E2AP Message is NULL", __func__);
6689          break;
6690       }
6691
6692       if(!e2apMsg->choice.successfulOutcome)
6693       {
6694          DU_LOG("\nERROR  -->  E2AP : %s: Successful Outcome in E2AP message is NULL", __func__);
6695          break;
6696       }
6697
6698       ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
6699       if(!ricSubsModCfm->protocolIEs.list.array)
6700       {
6701          DU_LOG("\nERROR  -->  E2AP : %s: Array conatining E2AP message IEs is null", __func__);
6702          break;
6703       }
6704
6705       for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++)
6706       {
6707          if(!ricSubsModCfm->protocolIEs.list.array[ieIdx])
6708          {
6709             DU_LOG("\nERROR  -->  E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx);
6710             break;
6711          }
6712
6713          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
6714          switch(ricSubsModCfmIe->id)
6715          {
6716             case ProtocolIE_IDE2_id_RICrequestID:
6717                {
6718                   memset(&ricReqId, 0, sizeof(RicRequestId));
6719                   ricReqId.requestorId = ricSubsModCfmIe->value.choice.RICrequestID.ricRequestorID;
6720                   ricReqId.instanceId = ricSubsModCfmIe->value.choice.RICrequestID.ricInstanceID;
6721                   break;
6722                }
6723
6724             case ProtocolIE_IDE2_id_RANfunctionID:
6725                {
6726                   ranFuncId = ricSubsModCfmIe->value.choice.RANfunctionID;
6727                   ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
6728                   if(!ranFuncDb)
6729                   {
6730                      DU_LOG("\nERROR  -->  E2AP : %s: RAN Function ID [%d] not found", __func__, ranFuncId);
6731                      procFailure = true;
6732                      break;
6733                   }
6734
6735                   ricSubsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode); 
6736                   if(!ricSubsDb)
6737                   {
6738                      DU_LOG("\nERROR  -->  E2AP : %s: RIC Subscription not found for Requestor_ID [%d] Instance_ID [%d]",\
6739                            __func__, ricReqId.requestorId, ricReqId.instanceId);
6740                      procFailure = true;
6741                      break;
6742                   }
6743
6744                   break;
6745                }
6746
6747 /* A RIC Subscription includes RIC subsequent action only for RIC Insert service. 
6748  * However, E2SM-KPM supports only RIC Report service. 
6749  * Hence there is no subsequent action in RIC subscription that may require modification. 
6750  * So commenting the action-modification IEs for the time being 
6751  */
6752 #if 0
6753             case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List:
6754                {
6755                   modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List;
6756                   for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
6757                   {
6758                      modCfmListItem = (RICaction_ConfirmedForModification_ItemIEs_t *)modCfmList->list.array[arrIdx];
6759                      actionId = modCfmListItem->value.choice.RICaction_ConfirmedForModification_Item.ricActionID;
6760
6761                      actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6762                      if(!actionDb)
6763                      {
6764                         DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6765                      }
6766                      else
6767                      {
6768                         actionDb->action = CONFIG_UNKNOWN;
6769                         /* Further handling can be added here in future once the
6770                          * use case of this procedure is identified */
6771                      }
6772                      actionDb = NULLP;
6773                   }
6774                   break;
6775                }
6776
6777             case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List:
6778                {
6779                   modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List;
6780                   for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
6781                   {
6782                     modRefusedListItem = (RICaction_RefusedToBeModified_ItemIEs_t *)modRefusedList->list.array[arrIdx];
6783                     actionId = modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.ricActionID;
6784                     actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6785                     if(!actionDb)
6786                     {
6787                        DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6788                     }
6789                     else
6790                     {
6791                        /* Spec doesnt mention if in case of failure, DU should retry for modify action 
6792                         * Hence, chaging the action from CONFIG_MOD to CONFIG_UNKNOWN
6793                         */
6794                         actionDb->action = CONFIG_UNKNOWN;
6795                     }
6796                     actionDb = NULLP;
6797                   }
6798                   break;
6799                }
6800 #endif
6801
6802             case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List:
6803                {
6804                   rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List;
6805                   for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
6806                   {
6807                      rmvCfmListItem = (RICaction_ConfirmedForRemoval_ItemIEs_t *)rmvCfmList->list.array[arrIdx];
6808                      actionId = rmvCfmListItem->value.choice.RICaction_ConfirmedForRemoval_Item.ricActionID;
6809                      actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6810                      if(!actionDb)
6811                      {
6812                         DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6813                      }
6814                      else
6815                      {
6816                         deleteActionSequence(actionDb);
6817                         actionDb =NULLP;
6818                         ricSubsDb->numOfActions--;
6819                         /* Further handling can include :
6820                          * Deletion of this action from all DU layers 
6821                          */
6822                      }
6823                      actionDb = NULLP;
6824                   }
6825                   break;
6826                }
6827
6828             case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List:
6829                {
6830                   rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List;
6831                   for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
6832                   {
6833                      rmvFailListItem = (RICaction_RefusedToBeRemoved_ItemIEs_t *)rmvFailList->list.array[arrIdx];
6834                      actionId = rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.ricActionID;
6835                      actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6836                      if(!actionDb)
6837                      {
6838                         DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6839                      }
6840                      else
6841                      {
6842                         actionDb->action = CONFIG_UNKNOWN;
6843                      }
6844                      actionDb = NULLP;
6845                   }
6846                   break;
6847                }
6848
6849             default:
6850                break;
6851          } /* End of switch for Protocol IE Id */
6852
6853          if(procFailure)
6854             break;
6855       } /* End of for loop for Protocol IE list */
6856
6857       break;
6858    }while(true);
6859
6860    freeAperDecodingOfRicSubsModConfirm(e2apMsg);
6861    return;
6862 }
6863
6864 /******************************************************************
6865 * @brief Deallocate the memory allocated for E2 Reset Response
6866 *
6867 * @details
6868 *
6869 *    Function : FreeE2ResetResponse
6870 *
6871 *    Functionality:
6872 *       - freeing the memory allocated for E2ResetResponse
6873 *
6874 * @params[in] E2AP_PDU_t *e2apMsg
6875 * @return ROK     - success
6876 *         RFAILED - failure
6877 *
6878 * ****************************************************************/
6879 void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg)
6880 {
6881    uint8_t ieIdx =0;
6882    ResetResponseE2_t *resetResponse;
6883
6884    if(e2apMsg != NULLP)
6885    {
6886       if(e2apMsg->choice.successfulOutcome != NULLP)
6887       {
6888          resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
6889          if(resetResponse->protocolIEs.list.array)
6890          {
6891             for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
6892             {
6893                if(resetResponse->protocolIEs.list.array[ieIdx])
6894                {
6895                   DU_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
6896                }
6897             }
6898             DU_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
6899          }
6900
6901          DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
6902       }
6903       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
6904    }
6905 }
6906
6907 /*******************************************************************
6908  *
6909  * @brief Buld and send the E2 Reset Response msg
6910  *
6911  * @details
6912  *
6913  *    Function : BuildAndSendE2ResetResponse
6914  *
6915  *    Functionality:
6916  *         - Buld and send the E2 Reset Response Message
6917  *
6918  * @params[in] Trans Id
6919  * @return ROK     - success
6920  *         RFAILED - failure
6921  *
6922  * ****************************************************************/
6923 uint8_t BuildAndSendResetResponse(uint8_t transId)
6924 {
6925    uint8_t           ieIdx = 0, elementCnt = 0;
6926    uint8_t           ret = RFAILED;
6927    E2AP_PDU_t        *e2apMsg = NULLP;
6928    ResetResponseE2_t *resetResponse;
6929    asn_enc_rval_t    encRetVal;       /* Encoder return value */
6930
6931    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
6932    do
6933    {
6934       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
6935       if(e2apMsg == NULLP)
6936       {
6937          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
6938          break;
6939       }
6940       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
6941
6942       DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
6943       if(e2apMsg->choice.successfulOutcome == NULLP)
6944       {
6945          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
6946          break;
6947       }
6948
6949       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
6950       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
6951       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
6952       resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
6953
6954       elementCnt = 1;
6955       resetResponse->protocolIEs.list.count = elementCnt;
6956       resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
6957       DU_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
6958       if(!resetResponse->protocolIEs.list.array)
6959       {
6960          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
6961          break;
6962       }
6963
6964       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
6965       {
6966          DU_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
6967          if(!resetResponse->protocolIEs.list.array[ieIdx])
6968          {
6969             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
6970             break;
6971          }
6972       }
6973       if(ieIdx < elementCnt)
6974          break;
6975
6976       ieIdx = 0;
6977       resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
6978       resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6979       resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
6980       resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
6981
6982       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6983
6984       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6985       encBufSize = 0;
6986       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6987       if(encRetVal.encoded == ENCODE_FAIL)
6988       {
6989          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
6990                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6991          break;
6992       }
6993       else
6994       {
6995          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
6996          for(int i=0; i< encBufSize; i++)
6997          {
6998             DU_LOG("%x",encBuf[i]);
6999          }
7000       }
7001
7002       /* Sending msg */
7003       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
7004       {
7005          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
7006          break;
7007       }
7008
7009       ret = ROK;
7010       break;
7011    }while(true);
7012
7013    FreeE2ResetResponse(e2apMsg);
7014    return ret;
7015 }
7016
7017 /******************************************************************
7018  *
7019  * @brief Deallocation of memory allocated by aper decoder for reset req
7020  *
7021  * @details
7022  *
7023  *    Function : freeAperDecodingOfE2ResetReq
7024  *
7025  *    Functionality: Deallocation of memory allocated by aper decoder for
7026  *    reset req
7027  *
7028  * @params[in] Pointer to resetReq
7029  * @return void
7030  *
7031  * ****************************************************************/
7032 void freeAperDecodingOfE2ResetReq(ResetRequestE2_t *resetReq)
7033 {
7034    uint8_t arrIdx=0;
7035
7036    if(resetReq)
7037    {
7038       if(resetReq->protocolIEs.list.array)
7039       {
7040          for(arrIdx=0; arrIdx<resetReq->protocolIEs.list.count; arrIdx++)
7041          {
7042             if(resetReq->protocolIEs.list.array[arrIdx])
7043             {
7044                free(resetReq->protocolIEs.list.array[arrIdx]);
7045             }
7046          }
7047          free(resetReq->protocolIEs.list.array);
7048       }
7049    }
7050 }
7051
7052 /*******************************************************************
7053  *
7054  * @brief Process reset req received from RIC
7055  *
7056  * @details
7057  *
7058  *    Function : procE2ResetRequest
7059  *
7060  * Functionality: Process reset req received from RIC
7061  *
7062  * @param  E2AP_PDU_t  *e2apMsg
7063  * @return void
7064  *
7065  ******************************************************************/
7066
7067 void procE2ResetRequest(E2AP_PDU_t  *e2apMsg)
7068 {
7069    uint16_t ranFuncIdx=0;
7070    uint8_t arrIdx =0, transId =0;
7071    ResetRequestE2_t *resetReq;
7072
7073    DU_LOG("\nINFO   -->  E2AP : E2 Reset request received");
7074    resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
7075
7076    for(arrIdx=0; arrIdx<resetReq->protocolIEs.list.count; arrIdx++)
7077    {
7078       switch(resetReq->protocolIEs.list.array[arrIdx]->id)
7079       {
7080          case ProtocolIE_IDE2_id_TransactionID:
7081             {
7082                transId = resetReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
7083                break;
7084             }
7085
7086          case ProtocolIE_IDE2_id_CauseE2:
7087             {
7088                for(ranFuncIdx=0; ranFuncIdx<MAX_RAN_FUNCTION; ranFuncIdx++)
7089                {
7090                   if(duCb.e2apDb.ranFunction[ranFuncIdx].id >0)
7091                   {
7092                      deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList));
7093                      memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo));
7094                   }
7095                }
7096                break;
7097             }
7098       }
7099    }
7100    if(BuildAndSendResetResponse(transId) != ROK)
7101    {
7102       DU_LOG("\nERROR  -->  E2AP : Failed to build and send reset response");
7103    }
7104    freeAperDecodingOfE2ResetReq(resetReq);
7105 }
7106
7107 /*******************************************************************
7108  *
7109  * @brief Free APER decoding of RIC Subscription Modification Refuse
7110  *
7111  * @details
7112  *
7113  *    Function : freeAperDecodingOfRicSubsModRefuse
7114  *
7115  * Functionality:  Free APER decoding of RIC Subscription 
7116  *   Modification Refuse
7117  *
7118  * @param  E2AP Message PDU
7119  * @return void
7120  *
7121  ******************************************************************/
7122 void freeAperDecodingOfRicSubsModRefuse(E2AP_PDU_t *e2apMsg)
7123 {
7124    uint8_t ieIdx =0;
7125    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
7126
7127    if(e2apMsg && e2apMsg->choice.unsuccessfulOutcome)
7128    {
7129       ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
7130       if(ricSubsModRefuse->protocolIEs.list.array)
7131       {
7132          for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++)
7133          {
7134             if(ricSubsModRefuse->protocolIEs.list.array[ieIdx])
7135                free(ricSubsModRefuse->protocolIEs.list.array[ieIdx]);
7136          }
7137          free(ricSubsModRefuse->protocolIEs.list.array);
7138       }
7139    }
7140 }
7141
7142 /*******************************************************************
7143  *
7144  * @brief Process RIC Subscription Modification Refuse Message
7145  *
7146  * @details
7147  *
7148  *    Function : procRicSubscriptionModificationRefuse
7149  *
7150  * Functionality:  Process RIC Subscription Modification Refuse
7151  *    Message received from RIC. 
7152  *
7153  * @param  E2AP Message PDU
7154  * @return void
7155  *
7156  ******************************************************************/
7157 void procRicSubscriptionModificationRefuse(E2AP_PDU_t *e2apMsg)
7158 {
7159    uint8_t ieIdx = 0;
7160    uint16_t ranFuncId = 0;
7161    RicRequestId ricReqId;
7162    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
7163    RICsubscriptionModificationRefuse_IEs_t *ricSubsModRefuseIe = NULLP;
7164    CauseE2_t *cause = NULLP;
7165
7166    DU_LOG("\nINFO   -->  E2AP : %s: Received RIC Subscription Modification Refuse", __func__);
7167
7168    do{
7169       if(!e2apMsg)
7170       {
7171          DU_LOG("\nERROR  -->  E2AP : %s: E2AP Message is NULL", __func__);
7172          break;
7173       }
7174
7175       if(!e2apMsg->choice.unsuccessfulOutcome)
7176       {
7177          DU_LOG("\nERROR  -->  E2AP : %s: Unsuccessful Outcome in E2AP message is NULL", __func__);
7178          break;
7179       }
7180
7181       ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
7182       if(!ricSubsModRefuse->protocolIEs.list.array)
7183       {
7184          DU_LOG("\nERROR  -->  E2AP : %s: Array conatining E2AP message IEs is null", __func__);
7185          break;
7186       }
7187
7188       for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++)
7189       {
7190          if(!ricSubsModRefuse->protocolIEs.list.array[ieIdx])
7191          {
7192             DU_LOG("\nERROR  -->  E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx);
7193             break;
7194          }
7195
7196          ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
7197          switch(ricSubsModRefuseIe->id)
7198          {
7199             case ProtocolIE_IDE2_id_RICrequestID:
7200                {
7201                   memset(&ricReqId, 0, sizeof(RicRequestId));
7202                   ricReqId.requestorId = ricSubsModRefuseIe->value.choice.RICrequestID.ricRequestorID;
7203                   ricReqId.instanceId = ricSubsModRefuseIe->value.choice.RICrequestID.ricInstanceID;
7204                   break;
7205                }
7206
7207             case ProtocolIE_IDE2_id_RANfunctionID:
7208                {
7209                   ranFuncId = ricSubsModRefuseIe->value.choice.RANfunctionID;
7210                   break;
7211                }
7212
7213             case ProtocolIE_IDE2_id_CauseE2:
7214                {
7215                   DU_LOG("\nDEBUG  -->  E2AP : %s: RIC subscriptiom modification refused for RIC_Requestor_ID [%d] \
7216                         RIC_Instance_ID [%d] RAN_Function_ID [%d] ", __func__, ricReqId.requestorId, \
7217                         ricReqId.instanceId, ranFuncId);
7218
7219                   cause = &ricSubsModRefuseIe->value.choice.CauseE2;
7220                   printE2ErrorCause(cause);
7221                }
7222
7223             default:
7224                break;
7225          } /* End of switch for Protocol IE Id */
7226       } /* End of for loop for Protocol IE list */
7227
7228       break;
7229    }while(true);
7230
7231    freeAperDecodingOfRicSubsModRefuse(e2apMsg);
7232    return;
7233 }
7234
7235 /*******************************************************************
7236  *
7237  * @brief Free RIC Subscription Delete Required Message
7238  *
7239  * @details
7240  *
7241  *    Function : FreeRicSubscriptionDeleteRequired
7242  *
7243  * Functionality:  Free RIC Subscription Delete Required
7244  *
7245  * @param  E2AP Message PDU
7246  * @return void
7247  *
7248  ******************************************************************/
7249 void FreeRicSubscriptionDeleteRequired(E2AP_PDU_t *e2apMsg, CmLListCp *ricSubsToBeDelList)
7250 {
7251    uint8_t ieIdx = 0, arrIdx = 0;
7252    RICsubscriptionDeleteRequired_t *ricSubsDelRqd = NULLP;
7253    RICsubscriptionDeleteRequired_IEs_t *ricSubsDelRqdIe = NULLP;
7254    RICsubscription_List_withCause_t *ricSubsList = NULLP;
7255    CmLList *subsNode = NULLP;
7256
7257    if(e2apMsg)
7258    {
7259       if(e2apMsg->choice.initiatingMessage)
7260       {
7261          ricSubsDelRqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired;
7262          if(ricSubsDelRqd->protocolIEs.list.array)
7263          {
7264             for(ieIdx = 0; ieIdx < ricSubsDelRqd->protocolIEs.list.count; ieIdx++)
7265             {
7266                if(ricSubsDelRqd->protocolIEs.list.array[ieIdx])
7267                {
7268                   ricSubsDelRqdIe = ricSubsDelRqd->protocolIEs.list.array[ieIdx];
7269                   switch(ricSubsDelRqdIe->id)
7270                   {
7271                      case ProtocolIE_IDE2_id_RICsubscriptionToBeRemoved:
7272                         {
7273                            ricSubsList = &ricSubsDelRqdIe->value.choice.RICsubscription_List_withCause;
7274                            if(ricSubsList->list.array)
7275                            {
7276                               for(arrIdx = 0; arrIdx < ricSubsList->list.count; arrIdx++)
7277                               {
7278                                  DU_FREE(ricSubsList->list.array[ieIdx], sizeof(RICsubscription_withCause_ItemIEs_t));
7279                               }
7280                               DU_FREE(ricSubsList->list.array, ricSubsList->list.size);
7281                            }
7282                            break;
7283                         }
7284                   }
7285                   DU_FREE(ricSubsDelRqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequired_IEs_t));
7286                }
7287             }
7288             DU_FREE(ricSubsDelRqd->protocolIEs.list.array, ricSubsDelRqd->protocolIEs.list.size);
7289          }
7290          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
7291       }
7292       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));;
7293    }
7294
7295    if(ricSubsToBeDelList)
7296    {
7297       CM_LLIST_FIRST_NODE(ricSubsToBeDelList, subsNode);
7298       while(subsNode)
7299       {
7300          cmLListDelFrm(ricSubsToBeDelList, subsNode);
7301          DU_FREE(subsNode, sizeof(CmLList));
7302          CM_LLIST_FIRST_NODE(ricSubsToBeDelList, subsNode);
7303       }
7304    }
7305 }
7306
7307 /*******************************************************************
7308  *
7309  * @brief Fill list of RIC subscriptions required to be deleted
7310  *    with the cause of deletion
7311  *
7312  * @details
7313  *
7314  *    Function : fillRicSubsListWithCause
7315  *
7316  * Functionality:  Fill list of RIC subscriptions required to be 
7317  *    deleted with the cause of deletion
7318  *
7319  * @param  E2AP Message PDU
7320  * @return void
7321  *
7322  ******************************************************************/
7323 uint8_t fillRicSubsListWithCause(RICsubscription_List_withCause_t *ricSubsList, CmLListCp ricSubsToBeDelList)
7324 {
7325    uint16_t ieIdx = 0;
7326    CmLList *subsNode = NULLP;
7327    RicSubscription *subsInfo = NULLP;
7328    RICsubscription_withCause_ItemIEs_t *subsItemIe = NULLP;
7329    RICsubscription_withCause_Item_t *subsItem = NULLP;
7330
7331    ricSubsList->list.count = ricSubsToBeDelList.count;
7332    ricSubsList->list.size = ricSubsList->list.count * sizeof(RICsubscription_withCause_ItemIEs_t *);
7333    DU_ALLOC(ricSubsList->list.array, ricSubsList->list.size);
7334    if(!ricSubsList->list.array)
7335    {
7336       DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7337       return RFAILED;
7338    }
7339
7340    CM_LLIST_FIRST_NODE(&ricSubsToBeDelList, subsNode);
7341    while(subsNode && (ieIdx < ricSubsList->list.count))
7342    {
7343       subsInfo = (RicSubscription *)subsNode->node;
7344       DU_ALLOC(ricSubsList->list.array[ieIdx], sizeof(RICsubscription_withCause_ItemIEs_t));
7345       if(!ricSubsList->list.array[ieIdx])
7346       {
7347          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7348          return RFAILED;
7349       }
7350
7351       subsItemIe = (RICsubscription_withCause_ItemIEs_t *)ricSubsList->list.array[ieIdx];
7352       subsItemIe->id = ProtocolIE_IDE2_id_RICsubscription_withCause_Item;
7353       subsItemIe->criticality = CriticalityE2_ignore;
7354       subsItemIe->value.present = RICsubscription_withCause_ItemIEs__value_PR_RICsubscription_withCause_Item;
7355
7356       subsItem = & subsItemIe->value.choice.RICsubscription_withCause_Item;
7357       subsItem->ricRequestID.ricRequestorID = subsInfo->requestId.requestorId;
7358       subsItem->ricRequestID.ricInstanceID = subsInfo->requestId.instanceId;
7359       subsItem->ranFunctionID = subsInfo->ranFuncId;
7360       fillE2Cause(&subsItem->cause, subsInfo->failureCause);
7361
7362       ieIdx++;
7363       subsNode = subsNode->next;
7364    }
7365
7366    return ROK;   
7367 }
7368
7369 /*******************************************************************
7370  *
7371  * @brief Builds and Send RIC Subscription delete required
7372  *
7373  * @details
7374  *
7375  *    Function : BuildAndSendRicSubscriptionDeleteRequired
7376  *
7377  * Functionality: Build and send RIC subscription delete required.
7378  *    There can be 2 approaches to trigger following. One of these
7379  *    approaches may/may not be implemented in future:
7380  *    1. It can be triggerred immediately when a RIC subscription's
7381  *       End Time has expired. In this case, only this subscription's
7382  *       info will be sent in this message.
7383  *       Since we have not yet added support to execute RIC 
7384  *       Subscription based on Start Time and End Timer, this message is 
7385  *       not triggered anywhere from DU APP yet.
7386  *    2. Another approach is to have a periodic timer to check subscription
7387  *       status running in background.
7388  *       When RIC Subscription End Time expires, this subscription is
7389  *       marked to be deleted. Later when this background timer expires,
7390  *       a RIC Subscription delete required is sent with all the 
7391  *       subscription's info which is marked to be deleted.
7392  *    The following function is implemented keeping in mind the second 
7393  *    approach.
7394  *
7395  * @params[in] 
7396  * @return ROK     - success
7397  *         RFAILED - failure
7398  *
7399  ******************************************************************/
7400 uint8_t BuildAndSendRicSubscriptionDeleteRequired()
7401 {
7402    uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED;
7403    E2AP_PDU_t         *e2apMsg = NULLP;
7404    RICsubscriptionDeleteRequired_t *ricSubsDelRqd = NULLP;
7405    RICsubscriptionDeleteRequired_IEs_t *ricSubsDelRqdIe = NULLP;
7406    asn_enc_rval_t     encRetVal;        /* Encoder return value */
7407    CmLListCp ricSubsToBeDelList;
7408
7409    while(true)
7410    {
7411       /* Check if there are any RIC subscriptions to be deleted */
7412       cmLListInit(&ricSubsToBeDelList);
7413       fetchRicSubsToBeDeleted(&ricSubsToBeDelList);
7414       if(ricSubsToBeDelList.count == 0)
7415       {
7416          DU_LOG("\nDEBUG  -->  E2AP : %s: No RIC subscriptions are required to be deleted", __func__);
7417          return ROK;
7418       }
7419
7420       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Delete Required Message\n");
7421
7422       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
7423       if(e2apMsg == NULLP)
7424       {
7425          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7426          break;
7427       }
7428
7429       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
7430       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
7431       if(e2apMsg->choice.initiatingMessage == NULLP)
7432       {
7433          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7434          break;
7435       }
7436       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionDeleteRequired;
7437       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
7438       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequired;
7439
7440       ricSubsDelRqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired;
7441       
7442       elementCnt = 1;
7443       ricSubsDelRqd->protocolIEs.list.count = elementCnt;
7444       ricSubsDelRqd->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionDeleteRequired_IEs_t *);
7445
7446       DU_ALLOC(ricSubsDelRqd->protocolIEs.list.array, ricSubsDelRqd->protocolIEs.list.size);
7447       if(ricSubsDelRqd->protocolIEs.list.array == NULLP)
7448       {
7449          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__);
7450          break;
7451       }
7452       
7453       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
7454       {
7455          DU_ALLOC(ricSubsDelRqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequired_IEs_t));
7456          if(ricSubsDelRqd->protocolIEs.list.array[ieIdx] == NULLP)
7457          {
7458             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for index [%d] at line %d", \
7459                __func__, ieIdx, __LINE__);
7460             break;
7461          }
7462       }
7463       if(ieIdx < elementCnt)
7464          break;
7465
7466       ieIdx = 0;
7467       ricSubsDelRqdIe = ricSubsDelRqd->protocolIEs.list.array[ieIdx];
7468       ricSubsDelRqdIe->id = ProtocolIE_IDE2_id_RICsubscriptionToBeRemoved;
7469       ricSubsDelRqdIe->criticality = CriticalityE2_ignore;
7470       ricSubsDelRqdIe->value.present = RICsubscriptionDeleteRequired_IEs__value_PR_RICsubscription_List_withCause;
7471       if(fillRicSubsListWithCause(&ricSubsDelRqdIe->value.choice.RICsubscription_List_withCause, ricSubsToBeDelList)\
7472             != ROK)
7473       {
7474          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Subscription list with cause", __func__);
7475          break;
7476       }
7477
7478       /* Prints the Msg formed */
7479       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
7480       memset(encBuf, 0, ENC_BUF_MAX_LEN);
7481       encBufSize = 0;
7482       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
7483       if(encRetVal.encoded == ENCODE_FAIL)
7484       {
7485          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Delete Required Message (at %s)\n",\
7486                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
7487          break;
7488       }
7489       else
7490       {
7491          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Delete Required Message \n");
7492 #ifdef DEBUG_ASN_PRINT
7493          for(int i=0; i< encBufSize; i++)
7494          {
7495             printf("%x",encBuf[i]);
7496          } 
7497 #endif
7498       }
7499
7500       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
7501       {
7502          DU_LOG("\nERROR   -->  E2AP : Failed to send RIC Susbcription Delete Required Message");      
7503
7504       }
7505       ret = ROK;
7506       break;
7507    }
7508
7509    FreeRicSubscriptionDeleteRequired(e2apMsg, &ricSubsToBeDelList);     
7510    return ret;
7511 }
7512
7513 /*******************************************************************
7514  *
7515  * @brief Free RIC Subscription Delete Failure Message
7516  *
7517  * @details
7518  *
7519  *    Function : FreeRicSubscriptionDeleteFailure
7520  *
7521  * Functionality:  Free RIC Subscription Delete Failure
7522  *
7523  * @param  E2AP Message PDU
7524  * @return void
7525  *
7526  ******************************************************************/
7527 void FreeRicSubscriptionDeleteFailure(E2AP_PDU_t *e2apMsg)
7528 {
7529    uint8_t ieIdx = 0;
7530    RICsubscriptionDeleteFailure_t *ricSubsDelFailure = NULLP;
7531
7532    if(e2apMsg)
7533    {
7534       if(e2apMsg->choice.unsuccessfulOutcome)
7535       {
7536          ricSubsDelFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionDeleteFailure;
7537          if(ricSubsDelFailure->protocolIEs.list.array)
7538          {
7539             for(ieIdx = 0; ieIdx < ricSubsDelFailure->protocolIEs.list.count; ieIdx++)
7540             {
7541                DU_FREE(ricSubsDelFailure->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteFailure_IEs_t));
7542             }
7543             DU_FREE(ricSubsDelFailure->protocolIEs.list.array, ricSubsDelFailure->protocolIEs.list.size);
7544          }
7545          DU_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
7546       }
7547       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));;
7548    }
7549 }
7550
7551 /*******************************************************************
7552  *
7553  * @brief Builds and Send RIC Subscription Delete Failure
7554  *
7555  * @details
7556  *
7557  *    Function : BuildAndSendRicSubscriptionDeleteFailure
7558  *
7559  * Functionality: Build and send RIC Subscription Delete Failure.
7560  *
7561  * @params[in] 
7562  *          Ran Func Id
7563  *          Ric Req Id
7564  *          E2 failure cause
7565  * @return ROK     - success
7566  *         RFAILED - failure
7567  *
7568  ******************************************************************/
7569 uint8_t BuildAndSendRicSubscriptionDeleteFailure(uint16_t ranFuncId,  RicRequestId requestId, E2FailureCause failureCause)
7570 {
7571    uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED;
7572    E2AP_PDU_t         *e2apMsg = NULLP;
7573    RICsubscriptionDeleteFailure_t *ricSubsDelFailure = NULLP;
7574    RICsubscriptionDeleteFailure_IEs_t *ricSubsDelFailureIe = NULLP;
7575    asn_enc_rval_t     encRetVal;        /* Encoder return value */
7576
7577    while(true)
7578    {
7579       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Delete Failure Message\n");
7580
7581       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
7582       if(e2apMsg == NULLP)
7583       {
7584          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7585          break;
7586       }
7587
7588       e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome;
7589       DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
7590       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
7591       {
7592          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7593          break;
7594       }
7595       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionDelete;
7596       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
7597       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICsubscriptionDeleteFailure;
7598
7599
7600       ricSubsDelFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionDeleteFailure;
7601
7602       elementCnt = 3;
7603       ricSubsDelFailure->protocolIEs.list.count = elementCnt;
7604       ricSubsDelFailure->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionDeleteFailure_IEs_t *);
7605
7606       DU_ALLOC(ricSubsDelFailure->protocolIEs.list.array, ricSubsDelFailure->protocolIEs.list.size);
7607       if(ricSubsDelFailure->protocolIEs.list.array == NULLP)
7608       {
7609          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__);
7610          break;
7611       }
7612
7613       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
7614       {
7615          DU_ALLOC(ricSubsDelFailure->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteFailure_IEs_t));
7616          if(ricSubsDelFailure->protocolIEs.list.array[ieIdx] == NULLP)
7617          {
7618             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for index [%d] at line %d", \
7619                   __func__, ieIdx, __LINE__);
7620             break;
7621          }
7622       }
7623       if(ieIdx < elementCnt)
7624          break;
7625
7626       ieIdx = 0;
7627       ricSubsDelFailureIe = ricSubsDelFailure->protocolIEs.list.array[ieIdx];
7628       ricSubsDelFailureIe->id = ProtocolIE_IDE2_id_RICrequestID;
7629       ricSubsDelFailureIe->criticality = CriticalityE2_reject;
7630       ricSubsDelFailureIe->value.present = RICsubscriptionDeleteFailure_IEs__value_PR_RICrequestID;
7631       ricSubsDelFailureIe->value.choice.RICrequestID.ricRequestorID= requestId.requestorId;
7632       ricSubsDelFailureIe->value.choice.RICrequestID.ricInstanceID = requestId.instanceId;
7633
7634       ieIdx++;
7635       ricSubsDelFailureIe = ricSubsDelFailure->protocolIEs.list.array[ieIdx];
7636       ricSubsDelFailureIe->id = ProtocolIE_IDE2_id_RANfunctionID;
7637       ricSubsDelFailureIe->criticality = CriticalityE2_reject;
7638       ricSubsDelFailureIe->value.present = RICsubscriptionDeleteFailure_IEs__value_PR_RANfunctionID;
7639       ricSubsDelFailureIe->value.choice.RANfunctionID = ranFuncId;
7640       
7641       ieIdx++;
7642       ricSubsDelFailureIe->id = ProtocolIE_IDE2_id_CauseE2;
7643       ricSubsDelFailureIe->criticality = CriticalityE2_ignore;
7644       ricSubsDelFailureIe->value.present = RICsubscriptionDeleteFailure_IEs__value_PR_CauseE2;
7645       fillE2Cause(&ricSubsDelFailureIe->value.choice.CauseE2, failureCause);
7646
7647       /* Prints the Msg formed */
7648       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
7649       memset(encBuf, 0, ENC_BUF_MAX_LEN);
7650       encBufSize = 0;
7651       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
7652       if(encRetVal.encoded == ENCODE_FAIL)
7653       {
7654          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Delete Failure Message (at %s)\n",\
7655                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
7656          break;
7657       }
7658       else
7659       {
7660          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Delete Failure Message \n");
7661 #ifdef DEBUG_ASN_PRINT
7662          for(int i=0; i< encBufSize; i++)
7663          {
7664             printf("%x",encBuf[i]);
7665          }
7666 #endif
7667       }
7668
7669       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
7670       {
7671          DU_LOG("\nERROR   -->  E2AP : Failed to send RIC Susbcription Delete Failure Message");
7672          break;
7673       }
7674
7675       ret = ROK;
7676       break;
7677    }
7678
7679    FreeRicSubscriptionDeleteFailure(e2apMsg);
7680    return ret;
7681 }
7682
7683
7684 /*******************************************************************
7685  *
7686  * @brief Free RIC Subscription Delete Response Message
7687  *
7688  * @details
7689  *
7690  *    Function : FreeRicSubscriptionDeleteResponse
7691  *
7692  * Functionality:  Free RIC Subscription Delete Response
7693  *
7694  * @param  E2AP Message PDU
7695  * @return void
7696  *
7697  ******************************************************************/
7698 void FreeRicSubscriptionDeleteResponse(E2AP_PDU_t *e2apMsg)
7699 {
7700    uint8_t ieIdx = 0;
7701    RICsubscriptionDeleteResponse_t *ricSubsDelRsp = NULLP;
7702
7703    if(e2apMsg)
7704    {
7705       if(e2apMsg->choice.successfulOutcome)
7706       {
7707          ricSubsDelRsp = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionDeleteResponse;
7708          if(ricSubsDelRsp->protocolIEs.list.array)
7709          {
7710             for(ieIdx = 0; ieIdx < ricSubsDelRsp->protocolIEs.list.count; ieIdx++)
7711             {
7712                DU_FREE(ricSubsDelRsp->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteResponse_IEs_t));
7713             }
7714             DU_FREE(ricSubsDelRsp->protocolIEs.list.array, ricSubsDelRsp->protocolIEs.list.size);
7715          }
7716          DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
7717       }
7718       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));;
7719    }
7720 }
7721
7722 /*******************************************************************
7723  *
7724  * @brief Builds and Send RIC Subscription delete Response
7725  *
7726  * @details
7727  *
7728  *    Function : BuildAndSendRicSubscriptionDeleteResponse
7729  *
7730  * Functionality: Build and send RIC subscription delete Response.
7731  *
7732  * @params[in]
7733  *          Ran Func Id
7734  *          Ric Req Id
7735  * @return ROK     - success
7736  *         RFAILED - failure
7737  *
7738  ******************************************************************/
7739 uint8_t BuildAndSendRicSubscriptionDeleteResponse(uint16_t ranFuncId,  RicRequestId requestId)
7740 {
7741    uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED;
7742    E2AP_PDU_t         *e2apMsg = NULLP;
7743    RICsubscriptionDeleteResponse_t *ricSubsDelRsp = NULLP;
7744    RICsubscriptionDeleteResponse_IEs_t *ricSubsDelRspIe = NULLP;
7745    asn_enc_rval_t     encRetVal;        /* Encoder return value */
7746
7747    while(true)
7748    {
7749       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Delete Response Message\n");
7750
7751       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
7752       if(e2apMsg == NULLP)
7753       {
7754          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7755          break;
7756       }
7757
7758       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
7759       DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
7760       if(e2apMsg->choice.successfulOutcome == NULLP)
7761       {
7762          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7763          break;
7764       }
7765       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionDelete;
7766       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
7767       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICsubscriptionDeleteResponse;
7768
7769
7770       ricSubsDelRsp = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionDeleteResponse;
7771
7772       elementCnt = 2;
7773       ricSubsDelRsp->protocolIEs.list.count = elementCnt;
7774       ricSubsDelRsp->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionDeleteResponse_IEs_t *);
7775
7776       DU_ALLOC(ricSubsDelRsp->protocolIEs.list.array, ricSubsDelRsp->protocolIEs.list.size);
7777       if(ricSubsDelRsp->protocolIEs.list.array == NULLP)
7778       {
7779          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__);
7780          break;
7781       }
7782
7783       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
7784       {
7785          DU_ALLOC(ricSubsDelRsp->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteResponse_IEs_t));
7786          if(ricSubsDelRsp->protocolIEs.list.array[ieIdx] == NULLP)
7787          {
7788             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for index [%d] at line %d", \
7789                   __func__, ieIdx, __LINE__);
7790             break;
7791          }
7792       }
7793       if(ieIdx < elementCnt)
7794          break;
7795
7796       ieIdx = 0;
7797       ricSubsDelRspIe = ricSubsDelRsp->protocolIEs.list.array[ieIdx];
7798       ricSubsDelRspIe->id = ProtocolIE_IDE2_id_RICrequestID;
7799       ricSubsDelRspIe->criticality = CriticalityE2_reject;
7800       ricSubsDelRspIe->value.present = RICsubscriptionDeleteResponse_IEs__value_PR_RICrequestID;
7801       ricSubsDelRspIe->value.choice.RICrequestID.ricRequestorID= requestId.requestorId;
7802       ricSubsDelRspIe->value.choice.RICrequestID.ricInstanceID = requestId.instanceId;
7803
7804       ieIdx++;
7805       ricSubsDelRspIe = ricSubsDelRsp->protocolIEs.list.array[ieIdx];
7806       ricSubsDelRspIe->id = ProtocolIE_IDE2_id_RANfunctionID;
7807       ricSubsDelRspIe->criticality = CriticalityE2_reject;
7808       ricSubsDelRspIe->value.present = RICsubscriptionDeleteResponse_IEs__value_PR_RANfunctionID;
7809       ricSubsDelRspIe->value.choice.RANfunctionID = ranFuncId;
7810
7811       /* Prints the Msg formed */
7812       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
7813       memset(encBuf, 0, ENC_BUF_MAX_LEN);
7814       encBufSize = 0;
7815       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
7816       if(encRetVal.encoded == ENCODE_FAIL)
7817       {
7818          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Delete Response Message (at %s)\n",\
7819                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
7820          break;
7821       }
7822       else
7823       {
7824          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Delete Response Message \n");
7825 #ifdef DEBUG_ASN_PRINT
7826          for(int i=0; i< encBufSize; i++)
7827          {
7828             printf("%x",encBuf[i]);
7829          }
7830 #endif
7831       }
7832
7833       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
7834       {
7835          DU_LOG("\nERROR   -->  E2AP : Failed to send RIC Susbcription Delete Response Message");
7836          break;
7837       }
7838
7839       ret = ROK;
7840       break;
7841    }
7842
7843    FreeRicSubscriptionDeleteResponse(e2apMsg);
7844    return ret;
7845 }
7846
7847 /*******************************************************************
7848  *
7849  * @brief Free RIC Subscription Delete Request Message
7850  *
7851  * @details
7852  *
7853  *    Function : freeAperDecodingOfRicSubsDeleteReq
7854  *
7855  * Functionality:  Free RIC Subscription Delete Request
7856  *
7857  * @param  E2AP Message PDU
7858  * @return void
7859  *
7860  ******************************************************************/
7861 void freeAperDecodingOfRicSubsDeleteReq(E2AP_PDU_t *e2apMsg)
7862 {
7863    uint8_t ieIdx = 0;
7864    RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
7865
7866    if(e2apMsg)
7867    {
7868       if(e2apMsg->choice.initiatingMessage)
7869       {
7870          ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
7871          if(ricSubsDelReq->protocolIEs.list.array)
7872          {
7873             for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++)
7874             {
7875                if(ricSubsDelReq->protocolIEs.list.array[ieIdx])
7876                {
7877                   free(ricSubsDelReq->protocolIEs.list.array[ieIdx]);
7878                }
7879             }
7880             free(ricSubsDelReq->protocolIEs.list.array);
7881          }
7882       }
7883    }
7884 }
7885
7886 /*******************************************************************
7887  *
7888  * @brief Process RIC Subscription delete request
7889  *
7890  * @details
7891  *
7892  *    Function : procRicSubscriptionDeleteRequest
7893  *
7894  * Functionality: Process RIC subscription delete request.
7895  *    Fetch RAN Function and RIC subscription to be deleted. 
7896  *    Send statistics delete request to MAC for all action sequence
7897  *    within this RIC subscription.
7898  *
7899  * @params[in] E2AP PDU
7900  * @return void
7901  *
7902  ******************************************************************/
7903 void procRicSubscriptionDeleteRequest(E2AP_PDU_t *e2apMsg)
7904 {
7905    uint8_t ieIdx = 0;
7906    uint16_t ranFuncId = 0;
7907    bool procFailure = false;
7908    RicRequestId ricReqId;
7909    RanFunction *ranFuncDb = NULLP;
7910    CmLList *ricSubsNode = NULLP;
7911    RicSubscription *ricSubsDb = NULLP;
7912    RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
7913    RICsubscriptionDeleteRequest_IEs_t *ricSubsDelReqIe = NULLP;
7914
7915    DU_LOG("\nINFO   -->  E2AP : %s: Received RIC Subscription Delete Request", __func__);
7916
7917    do{
7918       if(!e2apMsg)
7919       {
7920          DU_LOG("\nERROR  -->  E2AP : %s: E2AP Message is NULL", __func__);
7921          break;
7922       }
7923
7924       if(!e2apMsg->choice.initiatingMessage)
7925       {
7926          DU_LOG("\nERROR  -->  E2AP : %s: Initiating Message in E2AP PDU is NULL", __func__);
7927          break;
7928       }
7929
7930       ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
7931       if(!ricSubsDelReq->protocolIEs.list.array)
7932       {
7933          DU_LOG("\nERROR  -->  E2AP : %s: Array conatining E2AP message IEs is null", __func__);
7934          break;
7935       }
7936
7937       for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++)
7938       {
7939          if(!ricSubsDelReq->protocolIEs.list.array[ieIdx])
7940          {
7941             DU_LOG("\nERROR  -->  E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx);
7942             break;
7943          }
7944
7945          ricSubsDelReqIe = ricSubsDelReq->protocolIEs.list.array[ieIdx];
7946          switch(ricSubsDelReqIe->id)
7947          {
7948             case ProtocolIE_IDE2_id_RICrequestID:
7949                {
7950                   memset(&ricReqId, 0, sizeof(RicRequestId));
7951                   ricReqId.requestorId = ricSubsDelReqIe->value.choice.RICrequestID.ricRequestorID;
7952                   ricReqId.instanceId = ricSubsDelReqIe->value.choice.RICrequestID.ricInstanceID;
7953                   break;
7954                }
7955
7956             case ProtocolIE_IDE2_id_RANfunctionID:
7957                {
7958                   ranFuncId = ricSubsDelReqIe->value.choice.RANfunctionID;
7959                   ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
7960                   if(!ranFuncDb)
7961                   {
7962                      DU_LOG("\nERROR  -->  E2AP : %s: RAN Function ID [%d] not found", __func__, ranFuncId);
7963                      procFailure = true;
7964                      break;
7965                   }
7966
7967                   ricSubsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode); 
7968                   if(!ricSubsDb)
7969                   {
7970                      DU_LOG("\nERROR  -->  E2AP : %s: RIC Subscription not found for Requestor_ID [%d] Instance_ID [%d]",\
7971                            __func__, ricReqId.requestorId, ricReqId.instanceId);
7972                      procFailure = true;
7973                      break;
7974                   }
7975
7976                   if(BuildAndSendStatsDeleteReq(ricSubsDb) != ROK)
7977                   {
7978                      DU_LOG("\nERROR  -->  E2AP : Failed to build and send ric subscription delete req to du layers");
7979                   }
7980                   break;
7981                }
7982
7983             default:
7984                break;
7985          } /* End of switch for Protocol IE Id */
7986          
7987          if(procFailure)
7988             break;
7989       } /* End of for loop for Protocol IE list */
7990
7991       break;
7992    }while(true);
7993
7994    freeAperDecodingOfRicSubsDeleteReq(e2apMsg);
7995    return;
7996 }
7997
7998 /*******************************************************************
7999  *
8000  * @brief Deallocate the memory allocated for E2 node configuration
8001  * update ack msg by aper decoder
8002  *
8003  * @details
8004  *
8005  *    Function : freeAperDecodingOfE2NodeConfigUpdateAck 
8006  *
8007  *    Functionality:
8008  *       - Deallocate the memory allocated for E2 node configuration
8009  * update ack msg by aper decoder
8010  *
8011  * @params[in] E2AP_PDU_t *e2apMsg
8012  * @return ROK     - success
8013  *         RFAILED - failure
8014  *
8015  * ****************************************************************/
8016
8017 void freeAperDecodingOfE2NodeConfigUpdateAck(E2nodeConfigurationUpdateAcknowledge_t *updateAckMsg)
8018 {
8019    uint8_t arrIdx =0, e2NodeConfigIdx=0;
8020    E2nodeComponentConfigUpdateAck_ItemIEs_t *updateAckItemIe=NULL;
8021    E2nodeComponentConfigUpdateAck_List_t *updateAckList=NULL;
8022    E2nodeComponentConfigRemovalAck_ItemIEs_t *removalAckItemIe=NULL;
8023    E2nodeComponentConfigRemovalAck_List_t *removalAckList=NULL;
8024    E2nodeComponentConfigAdditionAck_ItemIEs_t *additionAckItemIte=NULL;
8025    E2nodeComponentConfigAdditionAck_List_t *additionAckList=NULL;
8026
8027    E2nodeComponentInterfaceF1_t *f1InterfaceInfo=NULLP;
8028    if(updateAckMsg->protocolIEs.list.array != NULLP)
8029    {
8030       for(arrIdx = 0; arrIdx < updateAckMsg->protocolIEs.list.count; arrIdx++)
8031       {
8032          if(updateAckMsg->protocolIEs.list.array[arrIdx])
8033          {
8034             switch(updateAckMsg->protocolIEs.list.array[arrIdx]->id)
8035             {
8036                case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
8037                   {
8038                      additionAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
8039                      if(additionAckList->list.array)
8040                      {
8041                         for(e2NodeConfigIdx=0; e2NodeConfigIdx<additionAckList->list.count; e2NodeConfigIdx++)
8042                         {
8043                            additionAckItemIte = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) additionAckList->list.array[e2NodeConfigIdx];
8044                            if(additionAckItemIte)
8045                            {
8046                               switch(additionAckItemIte->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present)
8047                               {
8048                                  case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
8049                                     {
8050                                        f1InterfaceInfo = additionAckItemIte->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
8051                                        free(f1InterfaceInfo->gNB_DU_ID.buf);
8052                                        free(f1InterfaceInfo);
8053                                        break;
8054                                     }
8055                                  default:
8056                                     break;
8057                               }
8058                               free(additionAckItemIte);
8059                            }
8060                            free(additionAckList->list.array);
8061                         }
8062                         break;
8063                      }
8064                   }
8065                case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
8066                   {
8067                      updateAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List;
8068                      if(updateAckList->list.array)
8069                      {
8070                         for(e2NodeConfigIdx=0; e2NodeConfigIdx<updateAckList->list.count; e2NodeConfigIdx++)
8071                         {
8072                            updateAckItemIe = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) updateAckList->list.array[e2NodeConfigIdx];
8073                            if(updateAckItemIe)
8074                            {
8075                               switch(updateAckItemIe->value.choice.E2nodeComponentConfigUpdateAck_Item.e2nodeComponentID.present)
8076                               {
8077                                  case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
8078                                     {
8079                                        f1InterfaceInfo = updateAckItemIe->value.choice.E2nodeComponentConfigUpdateAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
8080                                        free(f1InterfaceInfo->gNB_DU_ID.buf);
8081                                        free(f1InterfaceInfo);
8082                                        break;
8083                                     }
8084                                  default:
8085                                     break;
8086                               }
8087                               free(updateAckItemIe);
8088                            }
8089                         }
8090                         free(updateAckList->list.array);
8091                      }
8092                      break;
8093                   }
8094                case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
8095                   {
8096                      removalAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List;
8097                      if(removalAckList->list.array)
8098                      {
8099                         for(e2NodeConfigIdx=0; e2NodeConfigIdx<removalAckList->list.count; e2NodeConfigIdx++)
8100                         {
8101                            removalAckItemIe = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) removalAckList->list.array[e2NodeConfigIdx];
8102                            if(removalAckItemIe)
8103                            {
8104                               switch(removalAckItemIe->value.choice.E2nodeComponentConfigRemovalAck_Item.e2nodeComponentID.present)
8105                               {
8106                                  case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
8107                                     {
8108                                        f1InterfaceInfo = removalAckItemIe->value.choice.E2nodeComponentConfigRemovalAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
8109                                        free(f1InterfaceInfo->gNB_DU_ID.buf);
8110                                        free(f1InterfaceInfo);
8111                                        break;
8112                                     }
8113                                  default:
8114                                     break;
8115                               }
8116                               free(removalAckItemIe);
8117                            }
8118                         }
8119                         free(removalAckList->list.array);
8120                      }
8121                      break;
8122                   }
8123             }
8124             free(updateAckMsg->protocolIEs.list.array[arrIdx]);
8125          }
8126       }
8127       free(updateAckMsg->protocolIEs.list.array);
8128    }
8129 }
8130
8131 /******************************************************************
8132  *
8133  * @brief Processes the E2 node config update ack msg
8134  *
8135  * @details
8136  *
8137  *    Function :procE2NodeConfigUpdateAck 
8138  *
8139  *    Functionality: Processes the E2 node config update ack msg
8140  *
8141  * @params[in] E2AP_PDU_t ASN decoded E2AP message
8142  * @return ROK     - success
8143  *         RFAILED - failure
8144  *
8145  * ****************************************************************/
8146
8147 void procE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg)
8148 {
8149    uint8_t arrIdx =0;
8150    uint16_t e2CfgIdx =0;
8151    E2nodeConfigurationUpdateAcknowledge_t *e2NodeConfigUpdateAck =NULLP;
8152    E2nodeComponentConfigUpdateAck_List_t *e2NodeConfigUpdateAckList=NULLP;
8153    E2nodeComponentConfigUpdateAck_ItemIEs_t *e2NodeUpdateAckItem=NULLP;
8154    E2nodeComponentConfigRemovalAck_List_t *e2NodeConfigRemovalAckList=NULLP;
8155    E2nodeComponentConfigRemovalAck_ItemIEs_t *e2NodeRemovalAckItem=NULLP;
8156    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList=NULLP;
8157    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAdditionAckItem=NULLP;
8158
8159    e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
8160
8161    if(e2NodeConfigUpdateAck->protocolIEs.list.array)
8162    {
8163        for(arrIdx =0; arrIdx<e2NodeConfigUpdateAck->protocolIEs.list.count; arrIdx++)
8164        {
8165             switch(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id)
8166             {
8167                case ProtocolIE_IDE2_id_TransactionID:
8168                {
8169                   break;
8170                }
8171                case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
8172                {
8173                   e2NodeConfigAdditionAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
8174                   if(e2NodeConfigAdditionAckList->list.array)
8175                   {
8176                      for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigAdditionAckList->list.count; e2CfgIdx++) 
8177                      {
8178                         e2NodeAdditionAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[e2CfgIdx];    
8179                         handleE2NodeConfigUpdateAckIes((PTR)&e2NodeAdditionAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item,\
8180                         ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck);
8181                      }
8182                   }
8183                   break;
8184                }
8185                case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
8186                {
8187                   e2NodeConfigUpdateAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List;
8188                   if(e2NodeConfigUpdateAckList->list.array)
8189                   {
8190                      for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigUpdateAckList->list.count; e2CfgIdx++) 
8191                      {
8192                         e2NodeUpdateAckItem = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) e2NodeConfigUpdateAckList->list.array[e2CfgIdx];    
8193                         handleE2NodeConfigUpdateAckIes((PTR)&e2NodeUpdateAckItem->value.choice.E2nodeComponentConfigUpdateAck_Item,\
8194                         ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck);
8195                      }
8196                   }
8197                   break;
8198                }
8199                case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
8200                {
8201                   e2NodeConfigRemovalAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List;
8202                   if(e2NodeConfigRemovalAckList->list.array)
8203                   {
8204                      for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigRemovalAckList->list.count; e2CfgIdx++) 
8205                      {
8206                         e2NodeRemovalAckItem = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) e2NodeConfigRemovalAckList->list.array[e2CfgIdx];    
8207                         handleE2NodeConfigUpdateAckIes((PTR)&e2NodeRemovalAckItem->value.choice.E2nodeComponentConfigRemovalAck_Item,\
8208                         ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck);
8209                      }
8210                   }
8211                   break;
8212                }
8213             }
8214        }
8215    }
8216
8217    freeAperDecodingOfE2NodeConfigUpdateAck(e2NodeConfigUpdateAck);
8218 }
8219
8220 /*******************************************************************
8221  *
8222  * @brief Deallocate the memory allocated for RemovalRequest msg
8223  *
8224  * @details
8225  *
8226  *    Function : FreeRemovalRequest
8227  *
8228  *    Functionality:
8229  *       - freeing the memory allocated for RemovalRequest
8230  *
8231  * @params[in] E2AP_PDU_t *e2apMsg
8232  * @return ROK     - success
8233  *         RFAILED - failure
8234  *
8235  * ****************************************************************/
8236 void FreeRemovalRequest(E2AP_PDU_t *e2apMsg)
8237 {
8238    uint8_t ieIdx =0;
8239    E2RemovalRequest_t  *removalReq = NULLP;
8240
8241    if(e2apMsg != NULLP)
8242    {
8243       if(e2apMsg->choice.initiatingMessage != NULLP)
8244       {
8245          removalReq = &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest;
8246          if(removalReq->protocolIEs.list.array)
8247          {
8248             for(ieIdx = 0; ieIdx < removalReq->protocolIEs.list.count; ieIdx++)
8249             {
8250                DU_FREE(removalReq->protocolIEs.list.array[ieIdx], sizeof(E2RemovalRequestIEs_t));
8251             }
8252             DU_FREE(removalReq->protocolIEs.list.array, removalReq->protocolIEs.list.size);
8253          }
8254          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
8255       }
8256       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
8257    }
8258 }
8259
8260 /*******************************************************************
8261  *
8262  * @brief Build and send the removal request msg
8263  *
8264  * @details
8265  *
8266  *    Function : BuildAndSendRemovalRequest
8267  *
8268  *    Functionality:
8269  *         - Buld and send the removal request msg to E2 node
8270  *
8271  * @return ROK     - success
8272  *         RFAILED - failure
8273  *
8274  * ****************************************************************/
8275
8276 uint8_t BuildAndSendRemovalRequest()
8277 {
8278    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
8279    uint8_t ret = RFAILED;
8280    E2AP_PDU_t        *e2apMsg = NULLP;
8281    E2RemovalRequest_t  *removalReq = NULLP;
8282    asn_enc_rval_t     encRetVal;       /* Encoder return value */
8283
8284    DU_LOG("\nINFO   -->  E2AP : Building Removal Request\n");
8285
8286    do
8287    {
8288       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
8289       if(e2apMsg == NULLP)
8290       {
8291          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8292          break;
8293       }
8294
8295       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
8296       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
8297       if(e2apMsg->choice.initiatingMessage == NULLP)
8298       {
8299          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8300          break;
8301       }
8302
8303       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2removal;
8304       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
8305       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2RemovalRequest;
8306       removalReq = &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest;
8307
8308       elementCnt = 1;
8309       removalReq->protocolIEs.list.count = elementCnt;
8310       removalReq->protocolIEs.list.size = elementCnt * sizeof(E2RemovalRequestIEs_t *);
8311
8312       DU_ALLOC(removalReq->protocolIEs.list.array, removalReq->protocolIEs.list.size);
8313       if(!removalReq->protocolIEs.list.array)
8314       {
8315          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8316          break;
8317       }
8318
8319       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
8320       {
8321          DU_ALLOC(removalReq->protocolIEs.list.array[ieIdx], sizeof(E2RemovalRequestIEs_t));
8322          if(!removalReq->protocolIEs.list.array[ieIdx])
8323          {
8324             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8325             break;
8326          }
8327       }
8328
8329       /* In case of failure */
8330       if(ieIdx < elementCnt)
8331          break;
8332
8333       ieIdx = 0;
8334       removalReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
8335       removalReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
8336       removalReq->protocolIEs.list.array[ieIdx]->value.present = E2RemovalRequestIEs__value_PR_TransactionID;
8337       transId = assignTransactionId();
8338       removalReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
8339
8340       /* Prints the Msg formed */
8341       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
8342
8343       memset(encBuf, 0, ENC_BUF_MAX_LEN);
8344       encBufSize = 0;
8345       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
8346             encBuf);
8347       if(encRetVal.encoded == ENCODE_FAIL)
8348       {
8349          DU_LOG("\nERROR  -->  E2AP : Could not encode removal request structure (at %s)\n",\
8350                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
8351          break;
8352       }
8353       else
8354       {
8355          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for removal request\n");
8356 #ifdef DEBUG_ASN_PRINT
8357          for(int i=0; i< encBufSize; i++)
8358          {
8359             printf("%x",encBuf[i]);
8360          }
8361 #endif
8362       }
8363       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
8364       {
8365          DU_LOG("\nERROR  -->  E2AP : Sending removal request failed");
8366          break;
8367       }
8368
8369
8370       ret = ROK;
8371       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
8372       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
8373       break;
8374    }while(true);
8375
8376    /* Free all memory */
8377    FreeRemovalRequest(e2apMsg);
8378    
8379    return ret;
8380 }
8381
8382 /******************************************************************
8383  *
8384  * @brief Deallocation of memory allocated by aper decoder
8385  *   for Removal failure
8386  *
8387  * @details
8388  *
8389  *    Function : freeAperDecodingOfE2RemovalFailure
8390  *
8391  *    Functionality: Deallocation of memory allocated by aper decoder
8392  * for Removal failure
8393  *
8394  * @params[in] Pointer to removalFailure
8395  * @return void
8396  *
8397  * ****************************************************************/
8398 void freeAperDecodingOfE2RemovalFailure(E2RemovalFailure_t *removalFailure)
8399 {
8400    uint8_t arrIdx=0;
8401
8402    if(removalFailure)
8403    {
8404       if(removalFailure->protocolIEs.list.array)
8405       {
8406          for(arrIdx=0; arrIdx<removalFailure->protocolIEs.list.count; arrIdx++)
8407          {
8408             if(removalFailure->protocolIEs.list.array[arrIdx])
8409             {
8410                free(removalFailure->protocolIEs.list.array[arrIdx]);
8411             }
8412          }
8413          free(removalFailure->protocolIEs.list.array);
8414       }
8415    }
8416 }
8417
8418 /******************************************************************
8419  *
8420  * @brief Processes the E2 removal failure msg
8421  *
8422  * @details
8423  *
8424  *    Function : procE2RemovalFailure
8425  *
8426  *    Functionality: Processes the E2 removal failure msg
8427  *
8428  * @params[in] 
8429  *       E2AP_PDU_t *e2apMsg
8430  *
8431  * @return void
8432  *
8433  * ****************************************************************/
8434 void ProcE2RemovalFailure(E2AP_PDU_t *e2apMsg) 
8435 {
8436    uint8_t ieIdx = 0, transId=0;
8437    CauseE2_t *cause = NULLP;
8438    E2RemovalFailure_t *e2RemovalFailure=NULLP;
8439
8440    e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure;
8441
8442    if(!e2RemovalFailure->protocolIEs.list.array)      
8443    {
8444       DU_LOG("\nERROR  -->  E2AP : e2RemovalFailure array pointer is null");
8445       return;
8446    }
8447    
8448    for(ieIdx=0; ieIdx < e2RemovalFailure->protocolIEs.list.count; ieIdx++)
8449    {
8450       if(e2RemovalFailure->protocolIEs.list.array[ieIdx])
8451       {
8452          switch(e2RemovalFailure->protocolIEs.list.array[ieIdx]->id)
8453          {
8454             case ProtocolIE_IDE2_id_TransactionID:
8455                {
8456                   transId = e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
8457                   if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
8458                         (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
8459                   {
8460                      memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
8461                   }
8462                   else
8463                   {
8464                      DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
8465                   }
8466                   break;
8467                }
8468             case ProtocolIE_IDE2_id_CauseE2:
8469                {
8470                    cause = &e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2;
8471                    printE2ErrorCause(cause);
8472                    break; 
8473                }
8474             default:
8475                {
8476                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", e2RemovalFailure->protocolIEs.list.array[ieIdx]->id);
8477                   break;
8478                }
8479          }
8480       }
8481    }
8482    freeAperDecodingOfE2RemovalFailure(e2RemovalFailure);
8483 }
8484
8485  /******************************************************************
8486   *
8487   * @brief Deallocation of memory allocated by aper decoder
8488   *   for Removal failure
8489   *
8490   * @details
8491   *
8492   *    Function : freeAperDecodingOfE2RemovalResponse
8493   *
8494   *    Functionality: Deallocation of memory allocated by aper decoder
8495   * for Removal failure
8496   *
8497   * @params[in] Pointer to removalResponse
8498   * @return void
8499   *
8500   * ****************************************************************/
8501  void freeAperDecodingOfE2RemovalResponse(E2RemovalResponse_t *removalResponse)
8502  {
8503     uint8_t arrIdx=0;
8504
8505     if(removalResponse)
8506     {
8507        if(removalResponse->protocolIEs.list.array)
8508        {
8509           for(arrIdx=0; arrIdx<removalResponse->protocolIEs.list.count; arrIdx++)
8510           {
8511              if(removalResponse->protocolIEs.list.array[arrIdx])
8512              {
8513                 free(removalResponse->protocolIEs.list.array[arrIdx]);
8514              }
8515           }
8516           free(removalResponse->protocolIEs.list.array);
8517        }
8518     }
8519  }
8520
8521 /*******************************************************************
8522  *
8523  * @brief process the E2 Removal Response
8524  *
8525  * @details
8526  *
8527  *    Function : ProcE2RemovalResponse 
8528  *
8529  * Functionality: Process E2 Removal Response 
8530  *
8531  * @params[in] 
8532  *      E2AP_PDU_t *e2apMsg
8533  * @return void
8534  *
8535  ******************************************************************/
8536
8537 void ProcE2RemovalResponse(E2AP_PDU_t *e2apMsg)
8538 {
8539    uint8_t ieIdx = 0, transId=0;
8540    E2RemovalResponse_t *removalRsp = NULLP;
8541    
8542    removalRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse;
8543
8544    if(!removalRsp->protocolIEs.list.array)      
8545    {
8546       DU_LOG("\nERROR  -->  E2AP : removalRsp array pointer is null");
8547       return;
8548    }
8549
8550    for(ieIdx=0; ieIdx < removalRsp->protocolIEs.list.count; ieIdx++)
8551    {
8552       if(removalRsp->protocolIEs.list.array[ieIdx])
8553       {
8554          switch(removalRsp->protocolIEs.list.array[ieIdx]->id)
8555          {
8556             case ProtocolIE_IDE2_id_TransactionID:
8557                {
8558                   transId = removalRsp->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
8559                   if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
8560                         (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
8561                   {
8562                      DU_LOG("\nINFO  -->  E2AP : Sending request to close the sctp connection");
8563                      cmInetClose(&ricParams.sockFd);
8564                      memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
8565                      removeE2NodeInformation();
8566                   }
8567                   else
8568                   {
8569                      DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
8570                   }
8571                   break;
8572                }
8573             default:
8574                {
8575                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", removalRsp->protocolIEs.list.array[ieIdx]->id);
8576                   break;
8577                }
8578          }
8579       }
8580    }
8581    
8582    freeAperDecodingOfE2RemovalResponse(removalRsp);
8583 }
8584
8585 /*******************************************************************
8586  *
8587  * @brief Deallocate the memory allocated for E2 Connection Update Failure
8588  *
8589  * @details
8590  *
8591  *    Function : FreeE2ConnectionUpdateFailure
8592  *
8593  *    Functionality:
8594  *       - freeing the memory allocated for E2ConnectionUpdateFailure
8595  *
8596  * @params[in] E2AP_PDU_t *e2apMsg
8597  * @return ROK     - success
8598  *         RFAILED - failure
8599  *
8600  * ****************************************************************/
8601 void FreeE2ConnectionUpdateFailure(E2AP_PDU_t *e2apMsg)
8602 {
8603    uint8_t ieIdx =0;
8604    E2connectionUpdateFailure_t *e2ConnectionUpdateFailure=NULLP;
8605
8606    if(e2apMsg != NULLP)
8607    {
8608       if(e2apMsg->choice.unsuccessfulOutcome != NULLP)
8609       {
8610          e2ConnectionUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2connectionUpdateFailure;
8611          if(e2ConnectionUpdateFailure->protocolIEs.list.array)
8612          {
8613             for(ieIdx=0; ieIdx < e2ConnectionUpdateFailure->protocolIEs.list.count; ieIdx++)
8614             {
8615                DU_FREE(e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdateFailure_IEs_t));
8616             }
8617             DU_FREE(e2ConnectionUpdateFailure->protocolIEs.list.array, e2ConnectionUpdateFailure->protocolIEs.list.size);
8618          }
8619          DU_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
8620       }
8621       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
8622    }
8623 }
8624
8625 /*******************************************************************
8626  *
8627  * @brief Buld and send the E2 Connection Update Failure msg
8628  *
8629  * @details
8630  *
8631  *    Function : BuildAndSendE2ConnectionUpdateFailure
8632  *
8633  *    Functionality:
8634  *         - Buld and send the E2 Connection Update Failure Message
8635  * @params[in] 
8636  *    Trans Id 
8637  *    Failure Cause
8638  * @return ROK     - success
8639  *         RFAILED - failure
8640  *
8641  * ****************************************************************/
8642
8643 uint8_t BuildAndSendE2ConnectionUpdateFailure(uint16_t transId, E2FailureCause failureCause)
8644 {
8645    uint8_t           ieIdx = 0, elementCnt = 0;
8646    uint8_t           ret = RFAILED;
8647    E2AP_PDU_t        *e2apMsg = NULLP;
8648    E2connectionUpdateFailure_t *e2ConnectionUpdateFailure=NULLP;
8649    asn_enc_rval_t    encRetVal;       /* Encoder return value */
8650
8651    DU_LOG("\nINFO   -->  E2AP : Building E2 Connection Update Failure Message\n");
8652    do
8653    {
8654       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
8655       if(e2apMsg == NULLP)
8656       {
8657          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8658          break;
8659       }
8660       e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome;
8661
8662       DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
8663       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
8664       {
8665          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8666          break;
8667       }
8668
8669       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2connectionUpdate;
8670       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
8671       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2connectionUpdateFailure;
8672       e2ConnectionUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2connectionUpdateFailure;
8673
8674       elementCnt = 2;
8675       e2ConnectionUpdateFailure->protocolIEs.list.count = elementCnt;
8676       e2ConnectionUpdateFailure->protocolIEs.list.size = elementCnt * sizeof(E2connectionUpdateFailure_IEs_t *);
8677       DU_ALLOC(e2ConnectionUpdateFailure->protocolIEs.list.array, e2ConnectionUpdateFailure->protocolIEs.list.size);
8678       if(!e2ConnectionUpdateFailure->protocolIEs.list.array)
8679       {
8680          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8681          break;
8682       }
8683
8684       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
8685       {
8686          DU_ALLOC(e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdateFailure_IEs_t));
8687          if(!e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx])
8688          {
8689             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8690             break;
8691          }
8692       }
8693       if(ieIdx < elementCnt)
8694          break;
8695
8696       ieIdx = 0;
8697       e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
8698       e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
8699       e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateFailure_IEs__value_PR_TransactionID;
8700       e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
8701
8702       /* Cause */
8703       ieIdx++;
8704       e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
8705       e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
8706       e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateFailure_IEs__value_PR_CauseE2;
8707       fillE2Cause(&e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, failureCause);
8708       
8709       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
8710
8711       memset(encBuf, 0, ENC_BUF_MAX_LEN);
8712       encBufSize = 0;
8713       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
8714       if(encRetVal.encoded == ENCODE_FAIL)
8715       {
8716          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 connection update failure structure (at %s)\n",\
8717                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
8718          break;
8719       }
8720       else
8721       {
8722          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Connection Update Failure \n");
8723          for(int i=0; i< encBufSize; i++)
8724          {
8725             DU_LOG("%x",encBuf[i]);
8726          }
8727       }
8728
8729       /* Sending msg */
8730       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
8731       {
8732          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Connection Update Failure");
8733          break;
8734       }
8735
8736       ret = ROK;
8737       break;
8738    }while(true);
8739
8740    FreeE2ConnectionUpdateFailure(e2apMsg);
8741    return ret;
8742 }
8743
8744 /*******************************************************************
8745  *
8746  * @brief fill E2 connection update item
8747  *
8748  * @details
8749  *
8750  *    Function : fillE2connectionUpdateItem
8751  *
8752  *    Functionality: fill E2 connection update item
8753  *
8754  * @params[in]
8755  *    E2connectionUpdate Item to be filled
8756  *    Protocol Id
8757  *    IP Address
8758  *    Usage
8759  * @return ROK - success
8760  *         RFAILED - failure
8761  * ****************************************************************/
8762
8763 uint8_t fillE2connectionUpdateItem(PTR connectionInfo, uint8_t protocolId, uint32_t ipAddress, AssocUsage usage)
8764 {
8765    CauseE2_t *cause=NULLP;
8766    TNLusage_t  *tnlUsage=NULLP;
8767    E2FailureCause failureCause;
8768    TNLinformation_t *tnlInformation = NULLP;
8769    E2connectionUpdate_Item_t *connectionModifyItem=NULLP;
8770    E2connectionSetupFailed_Item_t *connectionRemoveITem=NULLP;
8771
8772    switch(protocolId)
8773    {
8774       case ProtocolIE_IDE2_id_E2connectionUpdate_Item:
8775       {
8776          connectionModifyItem = (E2connectionUpdate_Item_t*)connectionInfo;
8777          tnlInformation = &connectionModifyItem->tnlInformation;
8778          tnlUsage = &connectionModifyItem->tnlUsage;
8779          break;
8780       }
8781
8782       case ProtocolIE_IDE2_id_E2connectionSetupFailed_Item:
8783       {
8784          connectionRemoveITem = (E2connectionSetupFailed_Item_t*)connectionInfo;
8785          tnlInformation= &connectionRemoveITem->tnlInformation;
8786          cause = &connectionRemoveITem->cause;
8787          break;
8788       }
8789       default:
8790          return RFAILED;
8791    }
8792
8793    tnlInformation->tnlAddress.size =  4*sizeof(uint8_t);
8794    DU_ALLOC(tnlInformation->tnlAddress.buf, tnlInformation->tnlAddress.size);
8795    if(!tnlInformation->tnlAddress.buf)
8796    {
8797       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8798       return RFAILED;
8799    }
8800
8801    tnlInformation->tnlAddress.buf[3] =  ipAddress & 0xFF;
8802    tnlInformation->tnlAddress.buf[2] = (ipAddress>> 8) & 0xFF;
8803    tnlInformation->tnlAddress.buf[1] = (ipAddress>> 16) & 0xFF;
8804    tnlInformation->tnlAddress.buf[0] = (ipAddress>> 24) & 0xFF;
8805    tnlInformation->tnlAddress.bits_unused = 0;
8806
8807    switch(protocolId)
8808    {
8809       case ProtocolIE_IDE2_id_E2connectionUpdate_Item:
8810          {
8811             *tnlUsage = usage;
8812             break;
8813          }
8814       case ProtocolIE_IDE2_id_E2connectionSetupFailed_Item:
8815          {
8816             failureCause.causeType = E2_TRANSPORT;
8817             failureCause.cause = E2_TRANSPORT_CAUSE_UNSPECIFIED;
8818             fillE2Cause(cause, failureCause);
8819             break;
8820          }
8821       default:
8822          return RFAILED;
8823    }
8824    return ROK;
8825 }
8826
8827
8828 /*******************************************************************
8829  *
8830  * @brief Build E2 connection modification list
8831  *
8832  * @details
8833  *
8834  *    Function :BuildE2ConnectionUpdateList 
8835  *
8836  *    Functionality: Build E2 connection modification list
8837  *
8838  * @params[in]
8839  *    E2 connection update list to be filled
8840  *    Count of E2 connection to be added in the list    
8841  *    Received list of E2 connection
8842  *
8843  * @return ROK - success
8844  *         RFAILED - failure
8845  * ****************************************************************/
8846
8847 uint8_t BuildE2ConnectionUpdateList(E2connectionUpdate_List_t *connectionSetupList, uint8_t count, E2ConnectionItem *tmpConnectionList)
8848 {
8849    uint8_t arrIdx = 0;
8850    E2connectionUpdate_ItemIEs_t *connectionSetupItem=NULLP;
8851
8852    connectionSetupList->list.count = count;
8853
8854    connectionSetupList->list.size = connectionSetupList->list.count*sizeof(E2connectionUpdate_ItemIEs_t*);
8855    DU_ALLOC(connectionSetupList->list.array, connectionSetupList->list.size);
8856    if(connectionSetupList->list.array)
8857    {
8858       for(arrIdx = 0; arrIdx< connectionSetupList->list.count; arrIdx++)
8859       {
8860          DU_ALLOC(connectionSetupList->list.array[arrIdx], sizeof(E2connectionUpdate_ItemIEs_t));
8861          if(connectionSetupList->list.array[arrIdx] == NULLP)
8862          {
8863             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8864             return RFAILED;
8865          }
8866          connectionSetupItem = (E2connectionUpdate_ItemIEs_t*)connectionSetupList->list.array[arrIdx];
8867          connectionSetupItem->id = ProtocolIE_IDE2_id_E2connectionUpdate_Item;
8868          connectionSetupItem->criticality= CriticalityE2_ignore;
8869          connectionSetupItem->value.present = E2connectionUpdate_ItemIEs__value_PR_E2connectionUpdate_Item;
8870          if(fillE2connectionUpdateItem((PTR)&connectionSetupItem->value.choice.E2connectionUpdate_Item, ProtocolIE_IDE2_id_E2connectionUpdate_Item,\
8871           tmpConnectionList[arrIdx].ipV4Addr, tmpConnectionList[arrIdx].usage) != ROK)
8872          {
8873             DU_LOG("\nERROR  -->  E2AP : Failed to fill E2 connection update item");
8874             return RFAILED;
8875          }
8876
8877       }
8878    }
8879    else
8880    {
8881       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8882       return RFAILED;
8883    }
8884    return ROK;
8885 }
8886
8887 /*******************************************************************
8888  *
8889  * @brief Build E2 connection setup failed list
8890  *
8891  * @details
8892  *
8893  *    Function : BuildE2ConnectionSetupFailedList
8894  *
8895  *    Functionality: Build E2 connection setup failed list
8896  *
8897  * @params[in]
8898  *    E2 connection setup failed list to be filled
8899  *    Count of E2 connection to be added in the list    
8900  *    Received list of E2 connection
8901  *
8902  * @return ROK - success
8903  *         RFAILED - failure
8904  * ****************************************************************/
8905
8906 uint8_t BuildE2ConnectionSetupFailedList(E2connectionSetupFailed_List_t *setupFailedList, uint8_t count, E2ConnectionItem *tmpConnectionList)
8907 {
8908    uint8_t arrIdx = 0;
8909    E2connectionSetupFailed_ItemIEs_t *setupFailedItem=NULLP;
8910
8911    setupFailedList->list.count = 1;
8912
8913    setupFailedList->list.size = setupFailedList->list.count*sizeof(E2connectionSetupFailed_ItemIEs_t *);
8914    DU_ALLOC(setupFailedList->list.array, setupFailedList->list.size);
8915    if(setupFailedList->list.array)
8916    {
8917       for(arrIdx = 0; arrIdx< setupFailedList->list.count; arrIdx++)
8918       {
8919          DU_ALLOC(setupFailedList->list.array[arrIdx], sizeof(E2connectionSetupFailed_ItemIEs_t));
8920          if(setupFailedList->list.array[arrIdx] == NULLP)
8921          {
8922             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8923             return RFAILED;
8924          }
8925          setupFailedItem = (E2connectionSetupFailed_ItemIEs_t*)setupFailedList->list.array[arrIdx];
8926          setupFailedItem->id = ProtocolIE_IDE2_id_E2connectionSetupFailed_Item;
8927          setupFailedItem->criticality= CriticalityE2_ignore;
8928          setupFailedItem->value.present = E2connectionSetupFailed_ItemIEs__value_PR_E2connectionSetupFailed_Item;
8929          if(fillE2connectionUpdateItem((PTR)&setupFailedItem->value.choice.E2connectionSetupFailed_Item, ProtocolIE_IDE2_id_E2connectionSetupFailed_Item,\
8930           tmpConnectionList[arrIdx].ipV4Addr, tmpConnectionList[arrIdx].usage) != ROK)
8931          {
8932             DU_LOG("\nERROR  -->  E2AP : Failed to fill E2 connection failed to update item");
8933             return RFAILED;
8934          }
8935
8936       }
8937    }
8938    else
8939    {
8940       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
8941       return RFAILED;
8942    }
8943    return ROK;
8944 }
8945
8946 /*******************************************************************
8947  *
8948  * @brief Deallocate the memory allocated for E2 Connection
8949  * Update ack msg 
8950  *
8951  * @details
8952  *
8953  *    Function :FreeE2ConnectionUpdateAcknowledge 
8954  *
8955  *    Functionality:
8956  *       - freeing the memory allocated for E2 Connection
8957  * Update ack msg
8958  *
8959  * @params[in] E2AP_PDU_t *e2apMsg
8960  * @return ROK     - success
8961  *         RFAILED - failure
8962  *
8963  * ****************************************************************/
8964
8965 void FreeE2ConnectionUpdateAcknowledge(E2AP_PDU_t *e2apMsg)
8966 {
8967    uint8_t ieIdx =0, arrIdx=0;
8968    E2connectionUpdateAcknowledge_t *connectionUpdate = NULLP;
8969    E2connectionUpdate_List_t *connectionSetupList = NULLP;
8970    E2connectionSetupFailed_List_t *setupFailedList = NULLP;
8971
8972    if(e2apMsg != NULLP)
8973    {
8974       if(e2apMsg->choice.successfulOutcome != NULLP)
8975       {
8976          connectionUpdate = &e2apMsg->choice.successfulOutcome->value.choice.E2connectionUpdateAcknowledge;
8977          if(connectionUpdate->protocolIEs.list.array)
8978          {
8979             for(ieIdx = 0; ieIdx < connectionUpdate->protocolIEs.list.count; ieIdx++)
8980             {
8981                if(connectionUpdate->protocolIEs.list.array[ieIdx])
8982                {
8983                   switch(connectionUpdate->protocolIEs.list.array[ieIdx]->id)
8984                   {
8985                      case ProtocolIE_IDE2_id_TransactionID:
8986                         break;
8987
8988                      case ProtocolIE_IDE2_id_E2connectionSetup:
8989                         {
8990                            connectionSetupList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List;
8991                            if(connectionSetupList->list.array)
8992                            {
8993                               for(arrIdx = 0; arrIdx < connectionSetupList->list.count; arrIdx++)
8994                               {
8995                                  DU_FREE(connectionSetupList->list.array[arrIdx], sizeof(E2connectionUpdate_ItemIEs_t));
8996                               }
8997                               DU_FREE(connectionSetupList->list.array, connectionSetupList->list.size);
8998                            }
8999                            break;
9000                         }
9001
9002                      case ProtocolIE_IDE2_id_E2connectionSetupFailed:
9003                         {
9004                            setupFailedList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionSetupFailed_List;
9005                            if(setupFailedList->list.array)
9006                            {
9007                               for(arrIdx = 0; arrIdx < setupFailedList->list.count; arrIdx++)
9008                               {
9009                                  DU_FREE(setupFailedList->list.array[arrIdx], sizeof(E2connectionSetupFailed_ItemIEs_t));
9010                               }
9011                               DU_FREE(setupFailedList->list.array, setupFailedList->list.size);
9012                            }
9013                            break;
9014                         }
9015                   }
9016                   DU_FREE(connectionUpdate->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdateAck_IEs_t));
9017                }
9018             }
9019             DU_FREE(connectionUpdate->protocolIEs.list.array, connectionUpdate->protocolIEs.list.size);
9020          }
9021          DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
9022       }
9023       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
9024    }
9025 }
9026
9027 /*******************************************************************
9028  *
9029  * @brief Buld and send the E2 Connection Update Acknowledge msg
9030  *
9031  * @details
9032  *
9033  *    Function : BuildAndSendE2ConnectionUpdateAcknowledge
9034  *
9035  *    Functionality:
9036  *         - Buld and send the E2 Connection Update Acknowledge Message
9037  * @params[in] 
9038  *    Trans Id 
9039  *    List of E2 connection needs to fill in IE 
9040  * @return ROK     - success
9041  *         RFAILED - failure
9042  *
9043  * ****************************************************************/
9044
9045 uint8_t BuildAndSendE2ConnectionUpdateAcknowledge(uint16_t transId,  E2ConnectionList connectionInfoList)
9046 {
9047    uint8_t           ieIdx = 0, elementCnt = 0;
9048    uint8_t           ret = RFAILED;
9049    E2AP_PDU_t        *e2apMsg = NULLP;
9050    asn_enc_rval_t    encRetVal;       
9051    E2connectionUpdateAcknowledge_t *e2ConnectionUpdateAcknowledge=NULLP;
9052
9053    DU_LOG("\nINFO   -->  E2AP : Building E2 Connection Update Acknowledge Message\n");
9054    do
9055    {
9056       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
9057       if(e2apMsg == NULLP)
9058       {
9059          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
9060          break;
9061       }
9062       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
9063
9064       DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
9065       if(e2apMsg->choice.successfulOutcome == NULLP)
9066       {
9067          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
9068          break;
9069       }
9070
9071       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2connectionUpdate;
9072       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
9073       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2connectionUpdateAcknowledge;
9074       e2ConnectionUpdateAcknowledge = &e2apMsg->choice.successfulOutcome->value.choice.E2connectionUpdateAcknowledge;
9075
9076       elementCnt = 1;
9077       if(connectionInfoList.numOfE2ConnectionSetup)
9078          elementCnt++;
9079       if(connectionInfoList.numOfE2ConnectionFailedToSetup)
9080          elementCnt++;
9081
9082       e2ConnectionUpdateAcknowledge->protocolIEs.list.count = elementCnt;
9083       e2ConnectionUpdateAcknowledge->protocolIEs.list.size = elementCnt * sizeof(E2connectionUpdateAck_IEs_t*);
9084       DU_ALLOC(e2ConnectionUpdateAcknowledge->protocolIEs.list.array, e2ConnectionUpdateAcknowledge->protocolIEs.list.size);
9085       if(!e2ConnectionUpdateAcknowledge->protocolIEs.list.array)
9086       {
9087          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
9088          break;
9089       }
9090
9091       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
9092       {
9093          DU_ALLOC(e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdateAck_IEs_t));
9094          if(!e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx])
9095          {
9096             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
9097             break;
9098          }
9099       }
9100       if(ieIdx < elementCnt)
9101          break;
9102
9103       ieIdx = 0;
9104       e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
9105       e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
9106       e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateAck_IEs__value_PR_TransactionID;
9107       e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
9108
9109       if(connectionInfoList.numOfE2ConnectionSetup)
9110       {
9111          ieIdx++;
9112          e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_E2connectionSetup;
9113          e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
9114          e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateAck_IEs__value_PR_E2connectionUpdate_List;
9115          if(BuildE2ConnectionUpdateList(&e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List, \
9116                   connectionInfoList.numOfE2ConnectionSetup, connectionInfoList.setupE2Connection) != ROK)
9117          {
9118             DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Connection setup list");
9119             break;
9120          }
9121       }
9122       
9123       if(connectionInfoList.numOfE2ConnectionFailedToSetup)
9124       {
9125          ieIdx++;
9126          e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_E2connectionSetupFailed;
9127          e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
9128          e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateAck_IEs__value_PR_E2connectionSetupFailed_List;
9129          if(BuildE2ConnectionSetupFailedList(&e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.choice.E2connectionSetupFailed_List, \
9130                connectionInfoList.numOfE2ConnectionFailedToSetup, connectionInfoList.failedToSetupE2Connection) != ROK) 
9131          {
9132             DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Connection failed to setup list");
9133             break;
9134          }
9135       }
9136
9137       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
9138
9139       memset(encBuf, 0, ENC_BUF_MAX_LEN);
9140       encBufSize = 0;
9141       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
9142       if(encRetVal.encoded == ENCODE_FAIL)
9143       {
9144          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 connection update acknowledge failure structure (at %s)\n",\
9145                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
9146          break;
9147       }
9148       else
9149       {
9150          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Connection Update Acknowledge \n");
9151          for(int i=0; i< encBufSize; i++)
9152          {
9153             DU_LOG("%x",encBuf[i]);
9154          }
9155       }
9156
9157       /* Sending msg */
9158       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
9159       {
9160          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Connection Update Acknowledge");
9161          break;
9162       }
9163
9164       ret = ROK;
9165       break;
9166    }while(true);
9167
9168    FreeE2ConnectionUpdateAcknowledge(e2apMsg);
9169    return ret;
9170 }
9171
9172 /******************************************************************
9173  *
9174  * @brief Deallocation of memory allocated by aper decoder for 
9175  * E2 Connection Update
9176  *
9177  * @details
9178  *
9179  *    Function :freeAperDecodingOfE2ConnectionUpdate 
9180  *
9181  *    Functionality: Deallocation of memory allocated by aper decoder for
9182  *    E2 Connection Update
9183  *
9184  * @params[in] Pointer to connectionUpdate 
9185  * @return void
9186  *
9187  * ****************************************************************/
9188
9189 void freeAperDecodingOfE2ConnectionUpdate(E2connectionUpdate_t *connectionUpdate)
9190 {
9191    uint8_t ieIdx =0, arrIdx=0;
9192    E2connectionUpdate_List_t *connectionToBeModifyList = NULLP;
9193    E2connectionUpdateRemove_List_t *connectionToBeRemoveList = NULLP;
9194
9195    if(connectionUpdate->protocolIEs.list.array)
9196    {
9197       for(ieIdx = 0; ieIdx < connectionUpdate->protocolIEs.list.count; ieIdx++)
9198       {
9199          if(connectionUpdate->protocolIEs.list.array[ieIdx])
9200          {
9201             switch(connectionUpdate->protocolIEs.list.array[ieIdx]->id)
9202             {
9203                case ProtocolIE_IDE2_id_TransactionID:
9204                   break;
9205
9206                case ProtocolIE_IDE2_id_E2connectionUpdateModify:
9207                   {
9208                      connectionToBeModifyList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List;
9209                      if(connectionToBeModifyList->list.array)
9210                      {
9211                         for(arrIdx= 0; arrIdx< connectionToBeModifyList->list.count; arrIdx++)
9212                         {
9213                            free(connectionToBeModifyList->list.array[arrIdx]);
9214                         }
9215                         free(connectionToBeModifyList->list.array);
9216                      }
9217                      break;
9218                   }
9219                case ProtocolIE_IDE2_id_E2connectionUpdateRemove:
9220                   {
9221                      connectionToBeRemoveList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdateRemove_List;
9222                      if(connectionToBeRemoveList->list.array)
9223                      {
9224                         for(arrIdx= 0; arrIdx< connectionToBeRemoveList->list.count; arrIdx++)
9225                         {
9226                            free(connectionToBeRemoveList->list.array[arrIdx]);
9227                         }
9228                         free(connectionToBeRemoveList->list.array);
9229                      }
9230                      break;
9231                   }
9232             }
9233             free(connectionUpdate->protocolIEs.list.array[ieIdx]);
9234          }
9235       }
9236       free(connectionUpdate->protocolIEs.list.array);
9237    }
9238 }
9239
9240 /*******************************************************************
9241  *
9242  * @brief Handling of E2 connection modification Ie
9243  *
9244  * @details
9245  *
9246  *    Function : handleE2ConnectionModification 
9247  *
9248  * Functionality: Handling of E2 connection modification Ie
9249  *
9250  * @param 
9251  *        E2 Connection update list
9252  *        E2 connection list which needs to be filled
9253  * @return void
9254  *
9255  ******************************************************************/
9256
9257 void handleE2ConnectionModification(E2connectionUpdate_List_t *connectionUpdateList, E2ConnectionList *connectionInfoList)
9258 {
9259    uint32_t ipAddress=0;
9260    bool infoFound = false;
9261    uint8_t arrIdx=0,idx=0, count =0;
9262    E2connectionUpdate_ItemIEs_t *connectionModifyItem=NULLP;
9263
9264    if(connectionUpdateList->list.array)
9265    {
9266       for(arrIdx = 0; arrIdx < connectionUpdateList->list.count; arrIdx++)
9267       {
9268          connectionModifyItem= (E2connectionUpdate_ItemIEs_t*)connectionUpdateList->list.array[arrIdx];
9269          bitStringToInt(&connectionModifyItem->value.choice.E2connectionUpdate_Item.tnlInformation.tnlAddress, &ipAddress);
9270          for(idx=0; idx<duCb.e2apDb.numOfTNLAssoc; idx++)
9271          {
9272             /* If the TNL information is found in the data base, update the
9273              * information in the database */
9274             if(duCb.e2apDb.tnlAssoc[idx].destIpAddress.ipV4Addr == ipAddress)
9275             {
9276                duCb.e2apDb.tnlAssoc[idx].usage = connectionModifyItem->value.choice.E2connectionUpdate_Item.tnlUsage;
9277                infoFound = true;
9278                break;
9279             }
9280          }
9281          
9282          /* If the TNL information is found in the data base, then add the
9283           * information in setupE2Connection array else add in failedToSetupE2Connection array */
9284          if(infoFound == true)
9285          {
9286             count =connectionInfoList->numOfE2ConnectionSetup;
9287             connectionInfoList->setupE2Connection[count].ipV4Addr =  duCb.e2apDb.tnlAssoc[idx].destIpAddress.ipV4Addr;
9288             connectionInfoList->setupE2Connection[count].usage = duCb.e2apDb.tnlAssoc[idx].usage;
9289             connectionInfoList->numOfE2ConnectionSetup++;
9290          }
9291          else
9292          {
9293             count = connectionInfoList->numOfE2ConnectionFailedToSetup;
9294             connectionInfoList->failedToSetupE2Connection[count].ipV4Addr =  ipAddress;
9295             connectionInfoList->failedToSetupE2Connection[count].usage = connectionModifyItem->value.choice.E2connectionUpdate_Item.tnlUsage;
9296             connectionInfoList->numOfE2ConnectionFailedToSetup++;
9297          }
9298       }
9299
9300    }
9301 }
9302
9303 /*******************************************************************
9304  *
9305  * @brief Handling of E2 connection removal Ie
9306  *
9307  * @details
9308  *
9309  *    Function : handleE2ConnectionRemoval 
9310  *
9311  * Functionality: Handling of E2 connection removal Ie
9312  *
9313  * @param  
9314  *    E2 Connection removal List 
9315  * @return void
9316  *
9317  ******************************************************************/
9318
9319 void handleE2ConnectionRemoval(E2connectionUpdateRemove_List_t *connectionRemovalList)
9320 {
9321    uint32_t ipAddress=0;
9322    uint8_t arrIdx=0,idx=0;
9323    E2connectionUpdateRemove_ItemIEs_t *connectionRemovalItem=NULLP;
9324
9325    if(connectionRemovalList->list.array)
9326    {
9327       for(arrIdx = 0; arrIdx < connectionRemovalList->list.count; arrIdx++)
9328       {
9329          connectionRemovalItem= (E2connectionUpdateRemove_ItemIEs_t*)connectionRemovalList->list.array[arrIdx];
9330          bitStringToInt(&connectionRemovalItem->value.choice.E2connectionUpdateRemove_Item.tnlInformation.tnlAddress, &ipAddress);
9331          for(idx=0; idx<duCb.e2apDb.numOfTNLAssoc; idx++)
9332          {
9333             if(duCb.e2apDb.tnlAssoc[idx].destIpAddress.ipV4Addr == ipAddress)
9334             {
9335                cmInetClose(&ricParams.sockFd);
9336                removeE2NodeInformation();
9337                break;
9338             }
9339          }
9340          
9341       }
9342    }
9343 }
9344
9345 /*******************************************************************
9346  *
9347  * @brief Process e2 connection update received from RIC
9348  *
9349  * @details
9350  *
9351  *    Function : procE2ConnectionUpdate
9352  *
9353  * Functionality: Process e2 connection update received from RIC
9354  *
9355  * @param  E2AP_PDU_t  *e2apMsg
9356  * @return void
9357  *
9358  ******************************************************************/
9359
9360 void procE2ConnectionUpdate(E2AP_PDU_t  *e2apMsg)
9361 {
9362    uint8_t arrIdx =0, transId =0;
9363    bool invalidTransId = false, connectionFailedToUpdate=false;
9364    E2FailureCause failureCause;
9365    E2ConnectionList connectionInfoList;
9366    E2connectionUpdate_t *connectionUpdate=NULLP;
9367
9368    DU_LOG("\nINFO   -->  E2AP : E2 connection update received");
9369    connectionUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2connectionUpdate;
9370    
9371    memset(&connectionInfoList, 0, sizeof(E2ConnectionList));
9372    for(arrIdx=0; arrIdx<connectionUpdate->protocolIEs.list.count; arrIdx++)
9373    {
9374       switch(connectionUpdate->protocolIEs.list.array[arrIdx]->id)
9375       {
9376          case ProtocolIE_IDE2_id_TransactionID:
9377             {
9378                transId = connectionUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
9379                if(transId>255)
9380                {
9381                   failureCause.causeType = E2_PROTOCOL;
9382                   failureCause.cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE;
9383                   invalidTransId = true;
9384                }
9385                break;
9386             }
9387
9388          case ProtocolIE_IDE2_id_E2connectionUpdateModify:
9389             {
9390                handleE2ConnectionModification(&connectionUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2connectionUpdate_List,\
9391                      &connectionInfoList);
9392                if((connectionInfoList.numOfE2ConnectionSetup == 0) && (connectionInfoList.numOfE2ConnectionFailedToSetup > 0))
9393                {
9394                   failureCause.causeType = E2_TRANSPORT;
9395                   failureCause.cause = E2_TRANSPORT_CAUSE_UNSPECIFIED;
9396                   connectionFailedToUpdate =true;
9397                }
9398
9399                break;
9400             }
9401
9402          case ProtocolIE_IDE2_id_E2connectionUpdateRemove:
9403             {
9404                handleE2ConnectionRemoval(&connectionUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2connectionUpdateRemove_List);
9405                break;
9406             }
9407
9408          default:
9409             {
9410                DU_LOG("\nERROR  -->  E2AP : Invalid IE received[%ld]",connectionUpdate->protocolIEs.list.array[arrIdx]->id);
9411                break;
9412             }
9413       }
9414
9415       if(invalidTransId == true || connectionFailedToUpdate ==true)
9416          break;
9417    }
9418    
9419    if(invalidTransId == true || connectionFailedToUpdate == true)
9420    {
9421       if(BuildAndSendE2ConnectionUpdateFailure(transId, failureCause) != ROK)
9422       {
9423          DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 connection update failure");
9424       }
9425    }
9426    else
9427    {
9428       if(BuildAndSendE2ConnectionUpdateAcknowledge(transId, connectionInfoList) != ROK)
9429       {
9430          DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 connection update ack");
9431       }
9432    }
9433
9434    freeAperDecodingOfE2ConnectionUpdate(connectionUpdate);
9435 }
9436
9437 /*******************************************************************
9438  *
9439  * @brief Handles received E2AP message and sends back response  
9440  *
9441  * @details
9442  *
9443  *    Function : E2APMsgHdlr
9444  *
9445  *    Functionality:
9446  *         - Decodes received E2AP control message
9447  *         - Prepares response message, encodes and sends to SCTP
9448  *
9449  * @params[in] 
9450  * @return ROK     - success
9451  *         RFAILED - failure
9452  *
9453  * ****************************************************************/
9454 void E2APMsgHdlr(Buffer *mBuf)
9455 {
9456    int i =0;
9457    char *recvBuf = NULLP;
9458    MsgLen copyCnt =0;
9459    MsgLen recvBufLen =0;
9460    E2AP_PDU_t *e2apMsg = NULLP;
9461    asn_dec_rval_t rval ={0}; /* Decoder return value */
9462    E2AP_PDU_t e2apasnmsg={0} ;
9463
9464    DU_LOG("\nDEBUG   -->  E2AP : Received E2AP message buffer");
9465    ODU_PRINT_MSG(mBuf, 0,0);
9466
9467    /* Copy mBuf into char array to decode it */
9468    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
9469    DU_ALLOC(recvBuf, (Size)recvBufLen);
9470
9471    if(recvBuf == NULLP)
9472    {
9473       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
9474       return;
9475    }
9476    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
9477    {
9478       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
9479       return;
9480    }
9481
9482 #ifdef DEBUG_ASN_PRINT
9483    printf("\nDEBUG   -->  E2AP : Received flat buffer to be decoded : ");
9484    for(i=0; i< recvBufLen; i++)
9485    {
9486       printf("%x",recvBuf[i]);
9487    }
9488 #endif
9489
9490    /* Decoding flat buffer into E2AP messsage */
9491    e2apMsg = &e2apasnmsg;
9492    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
9493
9494    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
9495    DU_FREE(recvBuf, (Size)recvBufLen);
9496
9497    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
9498    {
9499       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
9500       return;
9501    }
9502    printf("\n");
9503    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
9504
9505    switch(e2apMsg->present)
9506    {
9507       case E2AP_PDU_PR_unsuccessfulOutcome:
9508          {
9509             switch(e2apMsg->choice.unsuccessfulOutcome->value.present)
9510             {
9511                case UnsuccessfulOutcomeE2__value_PR_E2setupFailure:
9512                   {
9513                      procE2SetupFailure(e2apMsg);
9514                      break;
9515                   }
9516                case UnsuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateFailure:
9517                   {
9518                      procE2NodeConfigUpdateFailure(e2apMsg);
9519                      break;
9520                   }
9521                case UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure:
9522                   {
9523                      procRicServiceUpdateFailure(e2apMsg);
9524                      break;
9525                   }
9526                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionModificationRefuse:
9527                   {
9528                      procRicSubscriptionModificationRefuse(e2apMsg);
9529                      break;
9530                   }
9531                case UnsuccessfulOutcomeE2__value_PR_E2RemovalFailure:
9532                   {
9533                      ProcE2RemovalFailure(e2apMsg);
9534                      break;
9535                   }
9536                default:
9537                   {
9538                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome  [%d]",\
9539                            e2apMsg->choice.unsuccessfulOutcome->value.present);
9540                      return;
9541                   }
9542             }
9543             free(e2apMsg->choice.unsuccessfulOutcome);
9544             break;
9545          }
9546       case E2AP_PDU_PR_successfulOutcome:
9547          {
9548             switch(e2apMsg->choice.successfulOutcome->value.present)
9549             {
9550                case SuccessfulOutcomeE2__value_PR_E2setupResponse:
9551                   {
9552                      if(!duCb.e2Status)
9553                      {
9554                         procE2SetupRsp(e2apMsg);
9555                      }
9556                      break;
9557                   }
9558                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
9559                   {
9560                      procResetResponse(e2apMsg);
9561                      break;
9562                   }
9563                case SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge:
9564                   {
9565                      procRicServiceUpdateAck(e2apMsg);
9566                      break;
9567                   }
9568                case SuccessfulOutcomeE2__value_PR_RICsubscriptionModificationConfirm:
9569                   {
9570                      procRicSubscriptionModificationConfirm(e2apMsg);
9571                      break;
9572                   }
9573                case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge:
9574                   {
9575                      procE2NodeConfigUpdateAck(e2apMsg);
9576                      break;
9577                   }
9578                case SuccessfulOutcomeE2__value_PR_E2RemovalResponse:
9579                   {
9580                      ProcE2RemovalResponse(e2apMsg);
9581                      break;
9582                   }
9583                default:
9584                   {
9585                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome  [%d]",\
9586                            e2apMsg->choice.successfulOutcome->value.present);
9587                      return;
9588                   }
9589             }/* End of switch(successfulOutcome) */
9590             free(e2apMsg->choice.successfulOutcome);
9591             break;
9592          }
9593
9594       case E2AP_PDU_PR_initiatingMessage:
9595          {
9596             switch(e2apMsg->choice.initiatingMessage->value.present)
9597             {
9598                case InitiatingMessageE2__value_PR_RICsubscriptionRequest: 
9599                   {
9600                      procRicSubscriptionRequest(e2apMsg);
9601                      break;
9602                   }
9603                case InitiatingMessageE2__value_PR_RICserviceQuery:
9604                   {
9605                      procRicServiceQuery(e2apMsg);
9606                      break;
9607                   }
9608                case InitiatingMessageE2__value_PR_ErrorIndicationE2:
9609                   {
9610                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
9611                      break;
9612                   }
9613                case InitiatingMessageE2__value_PR_ResetRequestE2:
9614                   {
9615                      DU_LOG("\nINFO  -->  E2AP : Reset request received");
9616                      procE2ResetRequest(e2apMsg);
9617                      break;
9618                   }
9619                case InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequest:
9620                   {
9621                      DU_LOG("\nINFO  -->  E2AP : RIC Subscription Delete Request received");
9622                      procRicSubscriptionDeleteRequest(e2apMsg);
9623                      break;
9624                   }
9625                case InitiatingMessageE2__value_PR_E2RemovalRequest:
9626                   {
9627                      DU_LOG("\nINFO  -->  E2AP : E2 Removal request received");
9628                      procE2RemovalRequest(e2apMsg);
9629                      break;
9630                   }
9631                case InitiatingMessageE2__value_PR_E2connectionUpdate:
9632                   {
9633                      DU_LOG("\nINFO  -->  E2AP : E2 coneection update received");
9634                      procE2ConnectionUpdate(e2apMsg);
9635                      break;
9636                   }
9637                default:
9638                   {
9639                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\
9640                            e2apMsg->choice.initiatingMessage->value.present);
9641                      return;
9642                   }
9643             }/* End of switch(initiatingMessage) */
9644             free(e2apMsg->choice.initiatingMessage);
9645             break;
9646          }
9647       default:
9648          {
9649             DU_LOG("\nERROR  -->  E2AP : Invalid type of e2apMsg->present [%d]",e2apMsg->present);
9650             return;
9651          }
9652          free(e2apMsg);
9653
9654    }/* End of switch(e2apMsg->present) */
9655
9656 } /* End of E2APMsgHdlr */
9657
9658 /**********************************************************************
9659   End of file
9660  **********************************************************************/