[Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-535] Implementation of E2 Removal Procedure...
[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_mgr.h"
30 #include "du_mgr_main.h"
31 #include "du_utils.h"
32 #include "GlobalE2node-gNB-ID.h"
33 #include "ProtocolIE-FieldE2.h"
34 #include "E2setupRequest.h"
35 #include "InitiatingMessageE2.h"
36 #include "SuccessfulOutcomeE2.h"
37 #include "UnsuccessfulOutcomeE2.h"
38 #include "E2AP-PDU.h"
39 #include "odu_common_codec.h"
40 #include "E2nodeComponentInterfaceF1.h"
41 #include "E2setupRequest.h"
42 #include "du_e2_conversions.h"
43 #include "E2SM-KPM-RANfunction-Description.h"
44 #include "RANfunction-Name.h"
45 #include "RIC-EventTriggerStyle-Item.h"
46 #include "RIC-ReportStyle-Item.h"
47 #include "MeasurementInfo-Action-Item.h"
48 #include "E2SM-KPM-EventTriggerDefinition.h"
49 #include "E2SM-KPM-EventTriggerDefinition-Format1.h"
50 #include "E2SM-KPM-ActionDefinition.h"
51 #include "E2SM-KPM-ActionDefinition-Format1.h"
52 #include "MeasurementInfoItem.h"
53 #include "RANfunctionsIDcause-List.h"
54 #include "MeasurementRecord.h"
55 #include "MeasurementData.h"
56 #include "MeasurementRecordItem.h"
57 #include "MeasurementDataItem.h"
58 #include "E2SM-KPM-IndicationMessage-Format1.h"
59 #include "E2SM-KPM-IndicationMessage.h"
60 #include "E2SM-KPM-IndicationHeader.h"
61 #include "E2SM-KPM-IndicationHeader-Format1.h"
62 #include "LabelInfoItem.h"
63
64 /*******************************************************************
65  *
66  * @brief Fill E2 Failure Cause
67  *
68  * @details
69  *
70  *    Function : fillE2Cause
71  *
72  *    Functionality: Fill E2 Failure Cause
73  *
74  * @params[in] E2 Cause pointer to be filled in
75  *             E2 Cause to be filled from 
76  * @return void
77  *
78  ******************************************************************/
79 void fillE2Cause(CauseE2_t *e2Cause, E2FailureCause failureCause)
80 {
81    e2Cause->present = failureCause.causeType;
82    switch(e2Cause->present)
83    {
84       case CauseE2_PR_ricRequest:
85          {
86             e2Cause->choice.ricRequest = failureCause.cause;
87             break;
88          }
89       case CauseE2_PR_ricService:
90          {
91             e2Cause->choice.ricService = failureCause.cause;
92             break;
93          }
94       case CauseE2_PR_e2Node:
95          {
96             e2Cause->choice.e2Node = failureCause.cause;
97             break;
98          }
99       case CauseE2_PR_transport:
100          {
101             e2Cause->choice.transport = failureCause.cause;
102             break;
103          }
104       case CauseE2_PR_protocol:
105          {
106             e2Cause->choice.protocol = failureCause.cause;
107             break;
108          }
109       case CauseE2_PR_misc:
110          {
111             e2Cause->choice.misc = failureCause.cause;
112             break;
113          }
114       case CauseE2_PR_NOTHING:
115       default:
116          break;
117    }
118 }
119
120 /*******************************************************************
121  *
122  * @brief Printing Type and Cause of failure
123  *
124  * @details
125  *
126  *    Function : printE2ErrorCause
127  *
128  *    Functionality: Printing Type and Cause of failure
129  *
130  * @params[in] E2 Cause
131  * @return void
132  *
133  ******************************************************************/
134 void printE2ErrorCause(CauseE2_t *cause)
135 {
136    switch(cause->present)
137    {
138       case CauseE2_PR_ricRequest:
139          {
140             DU_LOG("Failure_Type [%s] Cause [%ld]", "RIC_Request", cause->choice.ricRequest);
141             break;
142          }
143       case CauseE2_PR_ricService:
144          {
145             DU_LOG("Failure_Type [%s] Cause [%ld]", "RIC_Service", cause->choice.ricService);
146             break;
147          }
148       case CauseE2_PR_e2Node:
149          {
150             DU_LOG("Failure_Type [%s] Cause [%ld]", "E2_Node", cause->choice.e2Node);
151             break;
152          }
153       case CauseE2_PR_transport:
154          {
155             DU_LOG("Failure_Type [%s] Cause [%ld]", "Transport", cause->choice.transport);
156             break;
157          }
158       case CauseE2_PR_protocol:
159          {
160             DU_LOG("Failure_Type [%s] Cause [%ld]", "Protocol", cause->choice.protocol);
161             break;
162          }
163       case CauseE2_PR_misc:
164          {
165             DU_LOG("Failure_Type [%s] Cause [%ld]", "Miscellaneous", cause->choice.misc);
166             break;
167          }
168       default:
169          {
170             DU_LOG("Failure_Type and Cause unknown");
171             break;
172          }
173    }
174 }
175
176 /*******************************************************************
177  *
178  * @brief Deallocate the memory allocated for E2 Removal Failure
179  *
180  * @details
181  *
182  *    Function : FreeE2RemovalFailure
183  *
184  *    Functionality:
185  *       - freeing the memory allocated for E2RemovalFailure
186  *
187  * @params[in] E2AP_PDU_t *e2apMsg
188  * @return ROK     - success
189  *         RFAILED - failure
190  *
191  * ****************************************************************/
192 void FreeE2RemovalFailure(E2AP_PDU_t *e2apMsg)
193 {
194    uint8_t ieIdx =0;
195    E2RemovalFailure_t *e2RemovalFailure=NULLP;
196
197    if(e2apMsg != NULLP)
198    {
199       if(e2apMsg->choice.unsuccessfulOutcome != NULLP)
200       {
201          e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure;
202          if(e2RemovalFailure->protocolIEs.list.array)
203          {
204             for(ieIdx=0; ieIdx < e2RemovalFailure->protocolIEs.list.count; ieIdx++)
205             {
206                if(e2RemovalFailure->protocolIEs.list.array[ieIdx])
207                {
208                   DU_FREE(e2RemovalFailure->protocolIEs.list.array[ieIdx], sizeof(E2RemovalFailureIEs_t));
209                }
210             }
211             DU_FREE(e2RemovalFailure->protocolIEs.list.array, e2RemovalFailure->protocolIEs.list.size);
212          }
213          DU_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
214       }
215       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
216    }
217 }
218
219 /*******************************************************************
220  *
221  * @brief Buld and send the E2 Removal Failure msg
222  *
223  * @details
224  *
225  *    Function : BuildAndSendE2RemovalFailure
226  *
227  *    Functionality:
228  *         - Buld and send the E2 Removal Failure Message
229  * @params[in] Trans Id 
230  * @return ROK     - success
231  *         RFAILED - failure
232  *
233  * ****************************************************************/
234
235 uint8_t BuildAndSendRemovalFailure(uint16_t transId, E2FailureCause failureCause)
236 {
237    uint8_t           ieIdx = 0, elementCnt = 0;
238    uint8_t           ret = RFAILED;
239    E2AP_PDU_t        *e2apMsg = NULLP;
240    E2RemovalFailure_t *e2RemovalFailure=NULLP;
241    asn_enc_rval_t    encRetVal;       /* Encoder return value */
242
243    DU_LOG("\nINFO   -->  E2AP : Building E2 Removal Failure Message\n");
244    do
245    {
246       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
247       if(e2apMsg == NULLP)
248       {
249          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
250          break;
251       }
252       e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome;
253
254       DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
255       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
256       {
257          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
258          break;
259       }
260
261       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2removal;
262       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
263       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2RemovalFailure;
264       e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure;
265
266       elementCnt = 2;
267       e2RemovalFailure->protocolIEs.list.count = elementCnt;
268       e2RemovalFailure->protocolIEs.list.size = elementCnt * sizeof(E2RemovalFailureIEs_t *);
269       DU_ALLOC(e2RemovalFailure->protocolIEs.list.array, e2RemovalFailure->protocolIEs.list.size);
270       if(!e2RemovalFailure->protocolIEs.list.array)
271       {
272          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
273          break;
274       }
275
276       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
277       {
278          DU_ALLOC(e2RemovalFailure->protocolIEs.list.array[ieIdx], sizeof(E2RemovalFailureIEs_t));
279          if(!e2RemovalFailure->protocolIEs.list.array[ieIdx])
280          {
281             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
282             break;
283          }
284       }
285       if(ieIdx < elementCnt)
286          break;
287
288       ieIdx = 0;
289       e2RemovalFailure->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
290       e2RemovalFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
291       e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.present = E2RemovalFailureIEs__value_PR_TransactionID;
292       e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
293
294       /* Cause */
295       ieIdx++;
296       e2RemovalFailure->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
297       e2RemovalFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
298       e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2;
299       fillE2Cause(&e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, failureCause);
300       
301       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
302
303       memset(encBuf, 0, ENC_BUF_MAX_LEN);
304       encBufSize = 0;
305       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
306       if(encRetVal.encoded == ENCODE_FAIL)
307       {
308          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 removal failure structure (at %s)\n",\
309                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
310          break;
311       }
312       else
313       {
314          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Removal Failure \n");
315          for(int i=0; i< encBufSize; i++)
316          {
317             DU_LOG("%x",encBuf[i]);
318          }
319       }
320
321       /* Sending msg */
322       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
323       {
324          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Removal Failure");
325          break;
326       }
327
328       ret = ROK;
329       break;
330    }while(true);
331
332    FreeE2RemovalFailure(e2apMsg);
333    return ret;
334 }
335
336 /*******************************************************************
337  *
338  * @brief Deallocate the memory allocated for E2 Removal Response
339  *
340  * @details
341  *
342  *    Function : FreeE2RemovalResponse
343  *
344  *    Functionality:
345  *       - freeing the memory allocated for E2RemovalResponse
346  *
347  * @params[in] E2AP_PDU_t *e2apMsg
348  * @return ROK     - success
349  *         RFAILED - failure
350  *
351  * ****************************************************************/
352 void FreeE2RemovalResponse(E2AP_PDU_t *e2apMsg)
353 {
354    uint8_t ieIdx =0;
355    E2RemovalResponse_t *e2RemovalResponse=NULLP;
356
357    if(e2apMsg != NULLP)
358    {
359       if(e2apMsg->choice.successfulOutcome != NULLP)
360       {
361          e2RemovalResponse = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse;
362          if(e2RemovalResponse->protocolIEs.list.array)
363          {
364             for(ieIdx=0; ieIdx < e2RemovalResponse->protocolIEs.list.count; ieIdx++)
365             {
366                if(e2RemovalResponse->protocolIEs.list.array[ieIdx])
367                {
368                   DU_FREE(e2RemovalResponse->protocolIEs.list.array[ieIdx], sizeof(E2RemovalResponseIEs_t));
369                }
370             }
371             DU_FREE(e2RemovalResponse->protocolIEs.list.array, e2RemovalResponse->protocolIEs.list.size);
372          }
373          DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
374       }
375       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
376    }
377 }
378
379 /*******************************************************************
380  *
381  * @brief Buld and send the E2 Removal Response msg
382  *
383  * @details
384  *
385  *    Function : BuildAndSendE2RemovalResponse
386  *
387  *    Functionality:
388  *         - Buld and send the E2 Removal Response Message
389  * @params[in] Trans Id 
390  * @return ROK     - success
391  *         RFAILED - failure
392  *
393  * ****************************************************************/
394 uint8_t BuildAndSendRemovalResponse(uint16_t transId)
395 {
396    uint8_t           ieIdx = 0, elementCnt = 0;
397    uint8_t           ret = RFAILED;
398    E2AP_PDU_t        *e2apMsg = NULLP;
399    E2RemovalResponse_t *e2RemovalResponse=NULLP;
400    asn_enc_rval_t    encRetVal;       /* Encoder return value */
401
402    DU_LOG("\nINFO   -->  E2AP : Building E2 Removal Response Message\n");
403    do
404    {
405       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
406       if(e2apMsg == NULLP)
407       {
408          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
409          break;
410       }
411       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
412
413       DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
414       if(e2apMsg->choice.successfulOutcome == NULLP)
415       {
416          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
417          break;
418       }
419
420       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2removal;
421       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
422       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2RemovalResponse;
423       e2RemovalResponse = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse;
424
425       elementCnt = 1;
426       e2RemovalResponse->protocolIEs.list.count = elementCnt;
427       e2RemovalResponse->protocolIEs.list.size = elementCnt * sizeof(E2RemovalResponseIEs_t *);
428       DU_ALLOC(e2RemovalResponse->protocolIEs.list.array, e2RemovalResponse->protocolIEs.list.size);
429       if(!e2RemovalResponse->protocolIEs.list.array)
430       {
431          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
432          break;
433       }
434
435       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
436       {
437          DU_ALLOC(e2RemovalResponse->protocolIEs.list.array[ieIdx], sizeof(E2RemovalResponseIEs_t));
438          if(!e2RemovalResponse->protocolIEs.list.array[ieIdx])
439          {
440             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
441             break;
442          }
443       }
444       if(ieIdx < elementCnt)
445          break;
446
447       ieIdx = 0;
448       e2RemovalResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
449       e2RemovalResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
450       e2RemovalResponse->protocolIEs.list.array[ieIdx]->value.present = E2RemovalResponseIEs__value_PR_TransactionID;
451       e2RemovalResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
452
453       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
454
455       memset(encBuf, 0, ENC_BUF_MAX_LEN);
456       encBufSize = 0;
457       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
458       if(encRetVal.encoded == ENCODE_FAIL)
459       {
460          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 removal response structure (at %s)\n",\
461                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
462          break;
463       }
464       else
465       {
466          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Removal Response \n");
467          for(int i=0; i< encBufSize; i++)
468          {
469             DU_LOG("%x",encBuf[i]);
470          }
471       }
472
473       /* Sending msg */
474       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
475       {
476          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Removal Response");
477          break;
478       }
479
480       ret = ROK;
481       break;
482    }while(true);
483
484    FreeE2RemovalResponse(e2apMsg);
485    removeE2NodeInformation();
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
3500    return ret;
3501 }
3502
3503 /******************************************************************
3504  *
3505  * @brief Free RIC Subscription Failure
3506  *
3507  * @details
3508  *
3509  *    Function : FreeRicSubscriptionFailure
3510  *
3511  *    Functionality: Free RIC Subscription Failure
3512  *
3513  * @params[in] E2AP PDU
3514  * @return void
3515  *
3516  * ****************************************************************/
3517 void FreeRicSubscriptionFailure(E2AP_PDU_t *e2apMsg)
3518 {
3519    uint8_t elemIdx = 0;
3520    RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP;
3521
3522    if(e2apMsg)
3523    {
3524       if(e2apMsg->choice.unsuccessfulOutcome)
3525       {
3526          ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
3527          if(ricSubscriptionFailure->protocolIEs.list.array)
3528          {
3529             for(elemIdx = 0; elemIdx < ricSubscriptionFailure->protocolIEs.list.count; elemIdx++)
3530             {
3531                DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t));
3532             }
3533             DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size);
3534          }
3535          DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
3536       }
3537       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3538    }
3539 }
3540
3541 /******************************************************************
3542  *
3543  * @brief Fill and Send RIC Subscription Failure to RIC
3544  *
3545  * @details
3546  *
3547  *    Function : BuildAndSendRicSubscriptionFailure
3548  *
3549  *    Functionality: Fill and Send RIC Subscription Failure to RIC
3550  *
3551  * @params[in] RIC Request ID
3552  *             RAN Function ID
3553  *             Cause of Failure
3554  * @return ROK     - success
3555  *         RFAILED - failure
3556  *
3557  * ****************************************************************/
3558 uint8_t BuildAndSendRicSubscriptionFailure(RicRequestId ricReqId, uint16_t ranFuncId, E2FailureCause failureCause)
3559 {
3560    uint8_t          ret = RFAILED;
3561    uint8_t          elementCnt = 0, elemIdx = 0;
3562    E2AP_PDU_t       *e2apMsg = NULLP;
3563    asn_enc_rval_t   encRetVal;        /* Encoder return value */
3564    RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP;
3565    RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
3566
3567    while(true)
3568    {
3569       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Failure\n");
3570
3571       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3572       if(e2apMsg == NULLP)
3573       {
3574          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
3575          break;
3576       }
3577
3578       e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome;
3579       DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
3580       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
3581       {
3582          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
3583          break;
3584       }
3585       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
3586       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
3587       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure;
3588
3589       ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
3590
3591       elementCnt = 3;
3592       ricSubscriptionFailure->protocolIEs.list.count = elementCnt;
3593       ricSubscriptionFailure->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionFailure_IEs_t *);
3594       DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size);
3595       if(!ricSubscriptionFailure->protocolIEs.list.array)
3596       {
3597          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
3598          break;
3599       }
3600
3601       for(elemIdx = 0; elemIdx < elementCnt; elemIdx++)
3602       {
3603          DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t));
3604          if(!ricSubscriptionFailure->protocolIEs.list.array[elemIdx])
3605          {
3606             DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d] for IE at index [%d]", \
3607                __func__, __LINE__, elemIdx);
3608             break;
3609          }
3610       }
3611       if(elemIdx < elementCnt)
3612          break;
3613
3614       elemIdx = 0;
3615
3616       /* RIC Request ID */
3617       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
3618       ricSubsFailIe->id = ProtocolIE_IDE2_id_RICrequestID;
3619       ricSubsFailIe->criticality = CriticalityE2_reject;
3620       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RICrequestID;
3621       ricSubsFailIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
3622       ricSubsFailIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
3623
3624       /* RAN Function ID */
3625       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
3626       ricSubsFailIe->id = ProtocolIE_IDE2_id_RANfunctionID;
3627       ricSubsFailIe->criticality = CriticalityE2_reject;
3628       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RANfunctionID;
3629       ricSubsFailIe->value.choice.RANfunctionID = ranFuncId;
3630
3631       /* Cause */
3632       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
3633       ricSubsFailIe->id = ProtocolIE_IDE2_id_CauseE2;
3634       ricSubsFailIe->criticality = CriticalityE2_reject;
3635       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_CauseE2;
3636       fillE2Cause(&ricSubsFailIe->value.choice.CauseE2, failureCause);
3637
3638       /* Prints the Msg formed */
3639       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3640       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3641       encBufSize = 0;
3642       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3643       if(encRetVal.encoded == ENCODE_FAIL)
3644       {
3645          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Failure Message (at %s)\n",\
3646                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3647          break;
3648       }
3649       else
3650       {
3651          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Failure Message \n");
3652 #ifdef DEBUG_ASN_PRINT
3653          for(int i=0; i< encBufSize; i++)
3654          {
3655             printf("%x",encBuf[i]);
3656          }
3657 #endif
3658       }
3659
3660       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
3661       {
3662          DU_LOG("\nINFO   -->  E2AP : Sending RIC Subscription Failure");
3663
3664       }
3665       ret = ROK;
3666       break;
3667    }
3668    FreeRicSubscriptionFailure(e2apMsg);
3669    return ret;
3670 }
3671
3672 /*******************************************************************
3673  *
3674  * @brief Free the RicIndication Message
3675  *
3676  * @details
3677  *
3678  *    Function : FreeRicIndication
3679  *
3680  * Functionality: Free the RicIndication Message
3681  *
3682  * @return void
3683  *         
3684  *
3685  ******************************************************************/
3686 void FreeRicIndication(E2AP_PDU_t  *e2apMsg) 
3687 {
3688    uint8_t idx = 0;
3689    RICindication_t *ricIndicationMsg= NULLP;
3690
3691    if(e2apMsg != NULLP)
3692    {
3693       if(e2apMsg->choice.initiatingMessage != NULLP)
3694       {
3695          ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
3696          if(ricIndicationMsg!= NULLP)
3697          {
3698             if(ricIndicationMsg->protocolIEs.list.array != NULLP)
3699             {
3700                for(idx=0; idx<ricIndicationMsg->protocolIEs.list.count; idx++)
3701                {
3702                   if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP)
3703                   {
3704                      switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
3705                      {
3706                         case ProtocolIE_IDE2_id_RICrequestID:
3707                         case ProtocolIE_IDE2_id_RANfunctionID:
3708                         case ProtocolIE_IDE2_id_RICactionID:
3709                         case ProtocolIE_IDE2_id_RICindicationType:
3710                            break;
3711
3712                         case ProtocolIE_IDE2_id_RICindicationHeader:
3713                            {
3714                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\
3715                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
3716                               break;
3717                            }
3718                         case ProtocolIE_IDE2_id_RICindicationMessage:
3719                            {
3720                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\
3721                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
3722                               break;
3723                            }
3724                         default:
3725                            break;
3726                      }
3727                      DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t));
3728                   }
3729                }
3730                DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size);
3731             }
3732          }
3733          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3734       }
3735       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3736    }
3737 }
3738
3739 /*******************************************************************
3740  *
3741  * @brief Free measurement record
3742  *
3743  * @details
3744  *
3745  *    Function : freeMeasRecord
3746  *
3747  * Functionality: Free all measurement recorded for a measurement
3748  *    within an action in a RIC subscription
3749  *
3750  * @param  Measurement data to be freed
3751  * @return void
3752  *
3753  ******************************************************************/
3754 void freeMeasData(MeasurementData_t *measData)
3755 {
3756    uint8_t measIdx = 0, measRecIdx = 0;
3757    MeasurementRecord_t *measRecord = NULLP;
3758
3759    if(measData->list.array)
3760    {
3761       for(measIdx = 0; measIdx < measData->list.count; measIdx++)
3762       {
3763          if(measData->list.array[measIdx])
3764          {
3765             measRecord = &measData->list.array[measIdx]->measRecord;
3766             if(measRecord->list.array)
3767             {
3768                for(measRecIdx = 0; measRecIdx < measRecord->list.count; measRecIdx++)
3769                {
3770                   DU_FREE(measRecord->list.array[measRecIdx], sizeof(MeasurementRecordItem_t));
3771                }
3772                DU_FREE(measRecord->list.array, measRecord->list.size);
3773             }
3774             DU_FREE(measData->list.array[measIdx], sizeof(MeasurementDataItem_t));
3775          }
3776       }
3777       DU_FREE(measData->list.array, measData->list.size);
3778    }
3779 }
3780
3781 /*******************************************************************
3782  *
3783  * @brief Fill measurement info list
3784  *
3785  * @details
3786  *
3787  *    Function : freeMeasInfoList
3788  *
3789  * Functionality: Fills all measurement info within an action 
3790  *    in a RIC subscription
3791  *
3792  * @param  Measurement Info list to be freed
3793  * @return void
3794  *
3795  ******************************************************************/
3796 void freeMeasInfoList(MeasurementInfoList_t *measInfoList)
3797 {
3798    uint8_t measInfoIdx = 0;
3799
3800    if(measInfoList->list.array)
3801    {
3802       for(measInfoIdx = 0; measInfoIdx < measInfoList->list.count; measInfoIdx++)
3803       {
3804          if(measInfoList->list.array[measInfoIdx])
3805          {
3806             DU_FREE(measInfoList->list.array[measInfoIdx]->measType.choice.measName.buf, \
3807                   measInfoList->list.array[measInfoIdx]->measType.choice.measName.size);
3808
3809             DU_FREE(measInfoList->list.array[measInfoIdx], measInfoList->list.size);
3810          }
3811       }
3812       DU_FREE(measInfoList->list.array, measInfoList->list.size);
3813    }
3814 }
3815
3816 /*******************************************************************
3817  *
3818  * @brief Free E2SM-KPM Indication Message
3819  *
3820  * @details
3821  *
3822  *    Function : FreeE2smKpmIndicationMessage
3823  *
3824  * Functionality: Free E2SM-KPM Indication Message
3825  *
3826  * @param  E2SM-KPM Indication message to be freed
3827  * @return void
3828  *
3829  ******************************************************************/
3830 void FreeE2smKpmIndicationMessage(E2SM_KPM_IndicationMessage_t *e2smKpmIndMsg)
3831 {
3832    E2SM_KPM_IndicationMessage_Format1_t *format1Msg = NULLP;
3833
3834    switch(e2smKpmIndMsg->indicationMessage_formats.present)
3835    {
3836       case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format1:
3837          {
3838             if(e2smKpmIndMsg->indicationMessage_formats.choice.indicationMessage_Format1)
3839             {
3840                format1Msg = e2smKpmIndMsg->indicationMessage_formats.choice.indicationMessage_Format1;
3841                
3842                /* Measurement Data */
3843                freeMeasData(&format1Msg->measData);
3844
3845                /* Measurement Info List */
3846                if(format1Msg->measInfoList)
3847                {
3848                   freeMeasInfoList(format1Msg->measInfoList);
3849                   DU_FREE(format1Msg->measInfoList, sizeof(MeasurementInfoList_t));
3850                }
3851
3852                /* Granularity Period */
3853                DU_FREE(format1Msg->granulPeriod, sizeof(GranularityPeriod_t));
3854
3855                DU_FREE(format1Msg, sizeof(E2SM_KPM_IndicationMessage_Format1_t));
3856             }
3857             break;
3858          }
3859
3860       case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_NOTHING:
3861       case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format2:
3862       default:
3863          break;
3864    }
3865 }
3866
3867 /*******************************************************************
3868  *
3869  * @brief Fill measurement record
3870  *
3871  * @details
3872  *
3873  *    Function : fillMeasRecord
3874  *
3875  * Functionality: Fills all measurement value for a measurement
3876  *    within an action in a RIC subscription
3877  *
3878  * @param  Measurement record to be filled
3879  *         Measurement database with measurement records
3880  * @return ROK     - success
3881  *         RFAILED - failure
3882  *
3883  ******************************************************************/
3884 uint8_t fillMeasRecord(MeasurementRecord_t *measRecord, MeasurementInfo *measInfoDb)
3885 {
3886    uint8_t measRecIdx = 0;
3887    CmLList *measValNode = NULLP;
3888    double  measVal = 0;
3889
3890    measRecord->list.count = measInfoDb->measuredValue.count;
3891    measRecord->list.size = measRecord->list.count * sizeof(MeasurementRecordItem_t *);
3892
3893    DU_ALLOC(measRecord->list.array, measRecord->list.size);
3894    if(!measRecord->list.array)
3895    {
3896       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3897       return RFAILED;
3898    }
3899
3900    for(measRecIdx = 0; measRecIdx < measRecord->list.count; measRecIdx++)
3901    {
3902       DU_ALLOC(measRecord->list.array[measRecIdx], sizeof(MeasurementRecordItem_t));
3903       if(!measRecord->list.array[measRecIdx])
3904       {
3905          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3906          return RFAILED;
3907       }
3908    }
3909
3910    measRecIdx = 0;
3911    CM_LLIST_FIRST_NODE(&measInfoDb->measuredValue, measValNode);
3912    while(measValNode)
3913    {
3914      measVal = *(double *)measValNode->node;
3915      if(measVal == (int)measVal)
3916      {
3917         measRecord->list.array[measRecIdx]->present = MeasurementRecordItem_PR_integer;
3918         measRecord->list.array[measRecIdx]->choice.integer = (int)measVal;
3919      }
3920      else
3921      {
3922          measRecord->list.array[measRecIdx]->present = MeasurementRecordItem_PR_real;
3923          measRecord->list.array[measRecIdx]->choice.real = measVal;
3924      }
3925      measRecIdx++;
3926      measValNode= measValNode->next;  
3927      /* Once the measurement record is added to the message, delete it from DB */
3928      measVal = 0;
3929    }
3930    deleteMeasuredValueList(&measInfoDb->measuredValue);
3931    return ROK;
3932 }
3933
3934 /*******************************************************************
3935  *
3936  * @brief Fills measuerement data
3937  *
3938  * @details
3939  *
3940  *    Function : fillMeasData
3941  *
3942  * Functionality: Fill all measurement recorded for all measurements
3943  *    in an action in a RIC subscription
3944  *
3945  * @param  Measurement data to be filled
3946  *         Measurement info list from an action DB
3947  * @return ROK     - success
3948  *         RFAILED - failure
3949  *
3950  ******************************************************************/
3951 uint8_t fillMeasData(MeasurementData_t *measData, CmLListCp *measInfoListDb)
3952 {
3953   uint8_t measIdx = 0;
3954   CmLList *measInfoNode = NULLP;
3955   MeasurementInfo *measInfoDb = NULLP;
3956   MeasurementRecord_t *measRecord = NULLP;
3957
3958   measData->list.count = measInfoListDb->count;
3959   measData->list.size = measData->list.count * sizeof(MeasurementDataItem_t *);
3960
3961   DU_ALLOC(measData->list.array, measData->list.size);
3962   if(!measData->list.array)
3963   {
3964      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3965      return RFAILED;
3966   }
3967
3968   measIdx = 0;
3969   CM_LLIST_FIRST_NODE(measInfoListDb, measInfoNode);
3970   while(measInfoNode)
3971   {
3972      measInfoDb = (MeasurementInfo *)measInfoNode->node;
3973      if(measInfoDb)
3974      {
3975         DU_ALLOC(measData->list.array[measIdx], sizeof(MeasurementDataItem_t));
3976         if(!measData->list.array[measIdx])
3977         {
3978            DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3979            return RFAILED;
3980         }
3981
3982         measRecord = &measData->list.array[measIdx]->measRecord;
3983         if(fillMeasRecord(measRecord, measInfoDb) != ROK)
3984         {
3985            DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement record");
3986            return RFAILED;
3987         }
3988         measIdx++;
3989      }
3990      measInfoNode = measInfoNode->next;
3991   }
3992
3993   return ROK;
3994 }
3995
3996 /*******************************************************************
3997  *
3998  * @brief Fill all measurement info
3999  *
4000  * @details
4001  *
4002  *    Function : fillMeasInfoList
4003  *
4004  * Functionality: Fills all measurement info belonging to an action
4005  *  in a RIC subscription
4006  *
4007  * @param   Measurement Info list to be filled
4008  *          Measurement Info list from E2AP DB
4009  * @return ROK     - success
4010  *         RFAILED - failure
4011  *
4012  ******************************************************************/
4013 uint8_t fillMeasInfoList(MeasurementInfoList_t *measInfoList, CmLListCp *measInfoListDb)
4014 {
4015    uint8_t measInfoIdx = 0;
4016    CmLList *measInfoNode = NULLP;
4017    MeasurementInfo *measInfoDb = NULLP;
4018    MeasurementInfoItem_t *measInfoItem = NULLP;
4019
4020    measInfoList->list.count = measInfoListDb->count;
4021    measInfoList->list.size = measInfoList->list.count * sizeof(MeasurementInfoItem_t *);
4022
4023    DU_ALLOC(measInfoList->list.array, measInfoList->list.size);
4024    if(!measInfoList->list.array)
4025    {
4026       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4027       return RFAILED;
4028    }
4029
4030    measInfoIdx = 0;
4031    CM_LLIST_FIRST_NODE(measInfoListDb, measInfoNode);
4032    while(measInfoNode)
4033    {
4034       DU_ALLOC(measInfoList->list.array[measInfoIdx], sizeof(MeasurementInfoItem_t));
4035       if(!measInfoList->list.array[measInfoIdx])
4036       {
4037          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4038          return RFAILED;
4039       }
4040
4041       measInfoItem = measInfoList->list.array[measInfoIdx];
4042       measInfoDb = (MeasurementInfo *)measInfoNode->node;
4043       if(measInfoDb)
4044       {
4045          /* Measurement Type */
4046          measInfoItem->measType.present = MeasurementType_PR_measName;
4047          measInfoItem->measType.choice.measName.size = strlen(measInfoDb->measurementTypeName);
4048
4049          DU_ALLOC(measInfoItem->measType.choice.measName.buf, measInfoItem->measType.choice.measName.size);
4050          if(!measInfoItem->measType.choice.measName.buf)
4051          {
4052             DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4053             return RFAILED;
4054          }
4055
4056          memcpy(measInfoItem->measType.choice.measName.buf, measInfoDb->measurementTypeName,\
4057             measInfoItem->measType.choice.measName.size);
4058
4059          measInfoIdx++;
4060       }
4061       measInfoNode = measInfoNode->next;
4062       measInfoDb = NULLP;
4063    }
4064
4065    return ROK;
4066 }
4067
4068  /*******************************************************************
4069  *
4070  * @brief Fill E2SM-KPM Indication Message Format 1
4071  *
4072  * @details
4073  *
4074  *    Function : fillE2smKpmIndMsgFormat1
4075  *
4076  * Functionality: Fill E2SM-KPM Indication Message Format 1
4077  *
4078  * @param  Format 1 Message to be filled
4079  *         Action Definition format 1 from E2AP DB
4080  * @return ROK     - success
4081  *         RFAILED - failure
4082  *
4083  ******************************************************************/
4084 uint8_t fillE2smKpmIndMsgFormat1(E2SM_KPM_IndicationMessage_Format1_t *format1Msg, ActionDefFormat1 *format1)
4085 {
4086   /* Measurement Data */
4087   if(fillMeasData(&format1Msg->measData, &format1->measurementInfoList) != ROK)
4088   {
4089      DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement data");
4090      return RFAILED;
4091   }
4092
4093   /* Measurement Information */
4094   DU_ALLOC(format1Msg->measInfoList, sizeof(MeasurementInfoList_t));
4095   if(!format1Msg->measInfoList)
4096   {
4097      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4098      return RFAILED;
4099   }
4100
4101   if(fillMeasInfoList(format1Msg->measInfoList, &format1->measurementInfoList) != ROK)
4102   {
4103      DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement information list");
4104      return RFAILED;
4105   }
4106
4107   /* Granularity Period */
4108   DU_ALLOC(format1Msg->granulPeriod, sizeof(GranularityPeriod_t));
4109   if(!format1Msg->granulPeriod)
4110   {
4111      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4112      return RFAILED;
4113   }
4114   *(format1Msg->granulPeriod) = format1->granularityPeriod;
4115
4116   return ROK;
4117 }
4118
4119 /*******************************************************************
4120  *
4121  * @brief Fill RIC Indication Message buffer
4122  *
4123  * @details
4124  *
4125  *    Function : fillRicIndMsgBuf
4126  *
4127  * Functionality: Fill E2SM-KPM Indication Message
4128  *    Encode this message and copy to RIC Indication Message buffer
4129  * 
4130  * @param  RIC Indication Message buffer to be filled
4131  *         Source action info from E2AP DB
4132  * @return ROK     - success
4133  *         RFAILED - failure
4134  *
4135  ******************************************************************/
4136 uint8_t fillRicIndMsgBuf(RICindicationMessage_t *ricIndMsgBuf, ActionInfo *actionInfo)
4137 {
4138    uint8_t ret = RFAILED;
4139    bool failedInFormat = false;
4140    E2SM_KPM_IndicationMessage_t e2smKpmIndMsg;
4141    asn_enc_rval_t   encRetVal;        /* Encoder return value */
4142
4143    memset(&e2smKpmIndMsg, 0, sizeof(E2SM_KPM_IndicationMessage_t));
4144
4145    while(true)
4146    {
4147       /* E2SM-KPM Indication message format type */
4148       e2smKpmIndMsg.indicationMessage_formats.present = actionInfo->definition.formatType;
4149       switch(e2smKpmIndMsg.indicationMessage_formats.present)
4150       {
4151          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format1:
4152             {
4153                /* E2SM-KPM Indication message format 1 */
4154                DU_ALLOC(e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1, \
4155                      sizeof(E2SM_KPM_IndicationMessage_Format1_t));
4156                if(!e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1)
4157                {
4158                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4159                   failedInFormat = true;
4160                   break;
4161                }
4162
4163                if(fillE2smKpmIndMsgFormat1(e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1, \
4164                   &actionInfo->definition.choice.format1) != ROK)
4165                {
4166                   DU_LOG("\nERROR  -->  E2AP : Failed to fill E2SM-KPM Indication message format 1");
4167                   failedInFormat = true;
4168                   break;
4169                }
4170                break;
4171             }
4172
4173          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_NOTHING:
4174          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format2:
4175          default:
4176             {
4177                DU_LOG("\nERROR  -->  E2AP : fillRicIndMsgBuf: Only Format 1 supported");
4178                failedInFormat = true;
4179                break;
4180             }
4181       }
4182
4183       if(failedInFormat)
4184          break;
4185
4186       /* Encode E2SM-KPM Indication Message */
4187       xer_fprint(stdout, &asn_DEF_E2SM_KPM_IndicationMessage, &e2smKpmIndMsg);
4188       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4189       encBufSize = 0;
4190       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_IndicationMessage, 0, &e2smKpmIndMsg, PrepFinalEncBuf, encBuf);
4191       if(encRetVal.encoded == ENCODE_FAIL)
4192       {
4193          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM Indication Message (at %s)\n",\
4194                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4195          break;
4196       }
4197       else
4198       {
4199          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SM-KPM Indication Message \n");
4200 #ifdef DEBUG_ASN_PRINT
4201          for(int i=0; i< encBufSize; i++)
4202          {
4203             printf("%x",encBuf[i]);
4204          } 
4205 #endif
4206       }
4207
4208       /* Copy encoded string to RIC Indication Message buffer */
4209       ricIndMsgBuf->size = encBufSize;
4210       DU_ALLOC(ricIndMsgBuf->buf, ricIndMsgBuf->size);
4211       if(!ricIndMsgBuf->buf)
4212       {
4213          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4214          break;
4215       }
4216       memset(ricIndMsgBuf->buf, 0, ricIndMsgBuf->size);
4217       memcpy(ricIndMsgBuf->buf, encBuf, encBufSize);
4218
4219       ret = ROK;
4220       break;
4221    }
4222
4223    /* Free E2SM-KPM Indication Message */
4224    FreeE2smKpmIndicationMessage(&e2smKpmIndMsg);
4225
4226    return ret;
4227 }
4228
4229 /*******************************************************************
4230  *
4231  * @brief Free E2SM-KPM Indication Header
4232  *
4233  * @details
4234  *
4235  *    Function : FreeE2smKpmIndicationHeader
4236  *
4237  * Functionality: Free E2SM-KPM Indication Header
4238  * 
4239  * @param  E2SM-KPM Indication Header to be free
4240  * @return void
4241  *
4242  ******************************************************************/
4243 void FreeE2smKpmIndicationHeader(E2SM_KPM_IndicationHeader_t *e2smKpmIndHdr)
4244 {
4245    E2SM_KPM_IndicationHeader_Format1_t *format1 = NULLP;
4246
4247    if(e2smKpmIndHdr)
4248    {
4249       switch(e2smKpmIndHdr->indicationHeader_formats.present)
4250       {
4251          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_indicationHeader_Format1:
4252             {
4253                if(e2smKpmIndHdr->indicationHeader_formats.choice.indicationHeader_Format1)
4254                {
4255                   format1 = e2smKpmIndHdr->indicationHeader_formats.choice.indicationHeader_Format1;
4256
4257                   DU_FREE(format1->colletStartTime.buf, format1->colletStartTime.size);
4258                   DU_FREE(format1, sizeof(E2SM_KPM_IndicationHeader_Format1_t));
4259                }
4260                break;
4261             }
4262          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_NOTHING:
4263          default:
4264             break;
4265       }
4266    }
4267 }
4268
4269 /*******************************************************************
4270  *
4271  * @brief Fill RIC Indication Header buffer
4272  *
4273  * @details
4274  *
4275  *    Function : fillRicIndHeader
4276  *
4277  * Functionality: Fill E2SM-KPM Indication Header
4278  *    Encode this message and copy to RIC Indication Header buffer
4279  * 
4280  * @param  RIC Indication Header buffer to be filled
4281  *         Source RIC subscription info from E2AP DB
4282  * @return ROK     - success
4283  *         RFAILED - failure
4284  *
4285  ******************************************************************/
4286 uint8_t fillRicIndHeader(RICindicationHeader_t *ricIndHdr, RicSubscription *ricSubsInfo)
4287 {
4288    uint8_t ret = RFAILED;
4289    uint8_t secBufIdx = 0, milliSecBufIdx = 0;
4290    int8_t byteIdx = 0;
4291    bool formatFailure = false;
4292    RanFunction *ranFunc = NULLP;
4293    ReportStartTime *startTime = NULLP;
4294    E2SM_KPM_IndicationHeader_t e2smKpmIndHdr;
4295    E2SM_KPM_IndicationHeader_Format1_t *format1 = NULLP;
4296    asn_enc_rval_t   encRetVal;        /* Encoder return value */
4297
4298    while(true)
4299    {
4300       ranFunc = fetchRanFuncFromRanFuncId(ricSubsInfo->ranFuncId);
4301       if(ranFunc == NULLP)
4302       {
4303          DU_LOG("\nERROR  -->  E2AP : RAN Function ID [%d] not found", ricSubsInfo->ranFuncId);
4304          break;
4305       }
4306
4307       memset(&e2smKpmIndHdr, 0, sizeof(E2SM_KPM_IndicationHeader_t));
4308
4309       e2smKpmIndHdr.indicationHeader_formats.present = ranFunc->ricIndicationHeaderFormat;
4310       switch(e2smKpmIndHdr.indicationHeader_formats.present)
4311       {
4312          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_indicationHeader_Format1:
4313             {
4314                DU_ALLOC(e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1, \
4315                      sizeof(E2SM_KPM_IndicationHeader_Format1_t));
4316                if(!e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1)
4317                {
4318                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4319                   formatFailure = true;
4320                   break;
4321                }
4322                format1 = e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1;
4323
4324                /* Fetch reporting period start time from DB */
4325                switch(ricSubsInfo->eventTriggerDefinition.formatType)
4326                {
4327                   case 1:
4328                   {
4329                      startTime = &ricSubsInfo->eventTriggerDefinition.choice.format1.startTime;
4330                   }
4331                }
4332
4333                format1->colletStartTime.size = 8 * sizeof(uint8_t);
4334                DU_ALLOC(format1->colletStartTime.buf, format1->colletStartTime.size);
4335                if(!format1->colletStartTime.buf)
4336                {
4337                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4338                   formatFailure = true;
4339                   break;
4340                }
4341
4342                /* As per O-RAN.WG3.E2SM-KPM-R003-v03.00, section 8.3.12 and
4343                 * RFC 5905, section 6 :
4344                 * Time stamp has a 64-bit format where first 32-bit is seconds
4345                 * and next 32-bit is fraction in picosecond-level.
4346                 * This fraction has been rounded in microseconds.
4347                 *
4348                 * Hence,
4349                 * Storing 32-bit seconds at MSB 0-3 and
4350                 * 32-bit milliseconds at next 4 bytes i.e. bytes 4-7
4351                 */
4352                secBufIdx = 0;
4353                milliSecBufIdx = 4;
4354                for(byteIdx = 3; byteIdx >= 0; byteIdx--)
4355                {
4356                   format1->colletStartTime.buf[secBufIdx++] = startTime->timeInSec >> (8*byteIdx);
4357                   format1->colletStartTime.buf[milliSecBufIdx++] = startTime->timeInMilliSec >> (8*byteIdx);
4358                }
4359                break;
4360             }
4361
4362          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_NOTHING:
4363          default:
4364          {
4365              DU_LOG("\nERROR  -->  E2AP : Only E2SM-KPM Indication Header Format 1 supported");
4366              formatFailure = true;
4367              break;
4368          }
4369       }
4370
4371       if(formatFailure)
4372          break;
4373
4374       /* Encode E2SM-KPM Indication Header */
4375       xer_fprint(stdout, &asn_DEF_E2SM_KPM_IndicationHeader, &e2smKpmIndHdr);
4376       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4377       encBufSize = 0;
4378       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_IndicationHeader, 0, &e2smKpmIndHdr, PrepFinalEncBuf, encBuf);
4379       if(encRetVal.encoded == ENCODE_FAIL)
4380       {
4381          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM Indication Header (at %s)\n",\
4382                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4383          break;
4384       }
4385       else
4386       {
4387          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SM-KPM Indication Header \n");
4388 #ifdef DEBUG_ASN_PRINT
4389          for(int i=0; i< encBufSize; i++)
4390          {
4391             printf("%x",encBuf[i]);
4392          } 
4393 #endif
4394       }
4395
4396       /* Copy encoded string to RIC Indication Header buffer */
4397       ricIndHdr->size = encBufSize;
4398       DU_ALLOC(ricIndHdr->buf, ricIndHdr->size);
4399       if(!ricIndHdr->buf)
4400       {
4401          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4402          break;
4403       }
4404       memset(ricIndHdr->buf, 0, ricIndHdr->size);
4405       memcpy(ricIndHdr->buf, encBuf, encBufSize);
4406       ret = ROK;
4407       break;
4408    }
4409
4410    /* Free E2SM-KPM Indication Header */
4411    FreeE2smKpmIndicationHeader(&e2smKpmIndHdr);
4412
4413    return ret;
4414 }
4415
4416 /*******************************************************************
4417  *
4418  * brief Fill the RIC Indication Message
4419  *
4420  * @details
4421  *
4422  *    Function : fillRicIndication
4423  *
4424  * Functionality: Fills the RIC Indication Message
4425  *
4426  * @param  RIC Indication Message to be filled
4427  *         RIC Subscription DB
4428  *         Action DB
4429  * @return ROK     - success
4430  *         RFAILED - failure
4431  *
4432  ******************************************************************/
4433 uint8_t fillRicIndication(RICindication_t *ricIndicationMsg, RicSubscription *ricSubscriptionInfo, ActionInfo *actionInfo)
4434 {
4435    uint8_t elementCnt = 0, idx = 0;
4436    uint8_t ret = ROK;
4437
4438    elementCnt = 6;
4439
4440    ricIndicationMsg->protocolIEs.list.count = elementCnt;
4441    ricIndicationMsg->protocolIEs.list.size  = elementCnt * sizeof(RICindication_IEs_t *);
4442
4443    /* Initialize the Ric Indication members */
4444    DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, ricIndicationMsg->protocolIEs.list.size);
4445    if(ricIndicationMsg->protocolIEs.list.array == NULLP)
4446    {
4447       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4448       return RFAILED;
4449    }
4450
4451    for(idx=0; idx<elementCnt; idx++)
4452    {
4453       DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx], sizeof(RICindication_IEs_t));
4454       if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
4455       {
4456          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4457          return RFAILED;
4458       }
4459    }
4460
4461    /* RIC Request ID */
4462    idx = 0;
4463    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
4464    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4465    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICrequestID;
4466    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID = \
4467       ricSubscriptionInfo->requestId.requestorId;
4468    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID = \
4469       ricSubscriptionInfo->requestId.instanceId;
4470
4471    /* RAN Function ID */
4472    idx++;
4473    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
4474    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4475    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RANfunctionID;
4476    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ricSubscriptionInfo->ranFuncId;
4477
4478    /* RIC Action ID */
4479    idx++;
4480    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
4481    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4482    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICactionID;
4483    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = actionInfo->actionId;
4484
4485    /* RIC Indication Type */
4486    idx++;
4487    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
4488    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4489    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationType;
4490    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = actionInfo->type;
4491
4492    /* RIC Indication Header */
4493    idx++;
4494    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
4495    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4496    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationHeader;
4497    if(fillRicIndHeader(&ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader, \
4498       ricSubscriptionInfo) != ROK)
4499    {
4500       DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication header");
4501       return RFAILED;
4502    }
4503
4504    /* RIC Indication Message */
4505    idx++;
4506    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
4507    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4508    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationMessage;
4509    if(fillRicIndMsgBuf(&ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage, \
4510       actionInfo) != ROK)
4511    {
4512       DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication Message");
4513       return RFAILED;
4514    }
4515
4516    return ret;
4517 }
4518
4519 /*******************************************************************
4520  *
4521  * @brief Builds and Send the RicIndication Message
4522  *
4523  * @details
4524  *
4525  *    Function : BuildAndSendRicIndication
4526  *
4527  * Functionality:Fills the RicIndication Message
4528  *
4529  * @return ROK     - success
4530  *         RFAILED - failure
4531  *
4532  ******************************************************************/
4533
4534 uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo, ActionInfo *actionInfo)
4535 {
4536    uint8_t          ret = RFAILED; 
4537    E2AP_PDU_t       *e2apMsg = NULLP;
4538    RICindication_t  *ricIndicationMsg = NULLP;
4539    asn_enc_rval_t   encRetVal;        /* Encoder return value */
4540
4541    while(true)
4542    {
4543       DU_LOG("\nINFO   -->  E2AP : Building RIC Indication Message\n");
4544
4545       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4546       if(e2apMsg == NULLP)
4547       {
4548          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4549          break;
4550       }
4551
4552       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4553       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4554       if(e2apMsg->choice.initiatingMessage == NULLP)
4555       {
4556          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4557          break;
4558       }
4559       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
4560       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4561       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication;
4562
4563       ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
4564
4565       if(fillRicIndication(ricIndicationMsg, ricSubscriptionInfo, actionInfo) != ROK)
4566       {
4567          DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication message");
4568          break;
4569       }
4570
4571       /* Prints the Msg formed */
4572       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4573       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4574       encBufSize = 0;
4575       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4576             encBuf);
4577       if(encRetVal.encoded == ENCODE_FAIL)
4578       {
4579          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Indication Message (at %s)\n",\
4580                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4581          break;
4582       }
4583       else
4584       {
4585          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Indication Message \n");
4586 #ifdef DEBUG_ASN_PRINT
4587          for(int i=0; i< encBufSize; i++)
4588          {
4589             printf("%x",encBuf[i]);
4590          } 
4591 #endif
4592       }
4593
4594       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
4595       {
4596          DU_LOG("\nINFO   -->  E2AP : Sending RIC Indication Message");      
4597
4598       }
4599       ret = ROK;
4600       break;
4601    }
4602    FreeRicIndication(e2apMsg);  
4603    return ret;
4604 }
4605
4606 /*******************************************************************
4607  *
4608  * @brief free e2 node component configuration req and rsp
4609  *
4610  * @details
4611  *
4612  *    Function : freeE2NodeComponentConfiguration 
4613  *
4614  *    Functionality:
4615  *       - free e2 node component configuration req and rsp
4616  *
4617  * @params[in] E2nodeComponentConfiguration_t *e2nodeComponentConfiguration
4618  * @return ROK     - success
4619  *         RFAILED - failure
4620  *
4621  * ****************************************************************/
4622
4623 void freeE2NodeComponentConfiguration(E2nodeComponentConfiguration_t *e2nodeComponentConfiguration)
4624 {
4625    /* Free E2 Node Component Request Part */
4626    DU_FREE(e2nodeComponentConfiguration->e2nodeComponentRequestPart.buf, e2nodeComponentConfiguration->e2nodeComponentRequestPart.size);
4627
4628    /* Free E2 Node Component Response Part */
4629    DU_FREE(e2nodeComponentConfiguration->e2nodeComponentResponsePart.buf, e2nodeComponentConfiguration->e2nodeComponentResponsePart.size);
4630                                  
4631 }
4632
4633 /*******************************************************************
4634  *
4635  * @brief free e2 node component component identifier
4636  *
4637  * @details
4638  *
4639  *    Function : freeE2NodeComponentIdentifier
4640  *
4641  *    Functionality:
4642  *       - free e2 node component component identifier
4643  *
4644  * @params[in] E2nodeComponentID_t  *componentID 
4645  * @return ROK     - success
4646  *         RFAILED - failure
4647  *
4648  * ****************************************************************/
4649
4650 void freeE2NodeComponentIdentifier(E2nodeComponentID_t *componentID)
4651 {
4652    if(componentID->choice.e2nodeComponentInterfaceTypeF1)
4653    {
4654       DU_FREE(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf, componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
4655       DU_FREE(componentID->choice.e2nodeComponentInterfaceTypeF1, sizeof(E2nodeComponentInterfaceF1_t));
4656    }
4657                                  
4658 }
4659
4660 /*******************************************************************
4661  *
4662  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
4663  *
4664  * @details
4665  *
4666  *    Function : FreeE2NodeConfigUpdate 
4667  *
4668  *    Functionality:
4669  *       - freeing the memory allocated for E2nodeConfigurationUpdate
4670  *
4671  * @params[in] E2AP_PDU_t *e2apMsg 
4672  * @return ROK     - success
4673  *         RFAILED - failure
4674  *
4675  * ****************************************************************/
4676
4677 void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg)
4678 {
4679    uint8_t arrIdx =0, e2NodeUpdateListIdx=0, e2NodeRemovalListIdx=0, e2NodeAddListIdx=0;
4680    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate =NULL;
4681    E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList  =NULL;
4682    E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItem =NULL;
4683    E2nodeComponentConfigRemoval_List_t *e2NodeRemovalList =NULL;
4684    E2nodeComponentConfigRemoval_ItemIEs_t *e2NodeRemovalItem =NULL;
4685    E2nodeComponentConfigAddition_List_t *e2NodeAddList =NULL;
4686    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem =NULL;
4687
4688    if(e2apMsg != NULLP)
4689    {
4690       if(e2apMsg->choice.initiatingMessage != NULLP)
4691       {
4692          e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
4693          if(e2NodeConfigUpdate->protocolIEs.list.array != NULLP)
4694          {
4695             for(arrIdx = 0; arrIdx < e2NodeConfigUpdate->protocolIEs.list.count; arrIdx++)
4696             {
4697                if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx])
4698                {
4699
4700                   switch(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id)
4701                   {
4702                      case ProtocolIE_IDE2_id_TransactionID:
4703                         break;
4704
4705                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
4706                      {
4707                          e2NodeAddList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;
4708                          if(e2NodeAddList->list.array)
4709                          {
4710                              for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
4711                              {
4712                                 e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
4713                                  
4714                                 freeE2NodeComponentConfiguration(&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration);
4715                                 freeE2NodeComponentIdentifier(&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID);
4716                                 DU_FREE(e2NodeAddItem, sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
4717                              }
4718                              DU_FREE(e2NodeAddList->list.array, e2NodeAddList->list.size);
4719                          }
4720                          break;
4721                      }
4722                      case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate:
4723                         {
4724                            e2NodeUpdateList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdate_List;
4725                            if(e2NodeUpdateList->list.array)
4726                            {
4727                               for(e2NodeUpdateListIdx = 0; e2NodeUpdateListIdx< e2NodeUpdateList->list.count; e2NodeUpdateListIdx++)
4728                               {
4729                                  e2NodeUpdateItem = (E2nodeComponentConfigUpdate_ItemIEs_t *) e2NodeUpdateList->list.array[e2NodeUpdateListIdx];
4730                                  
4731                                  freeE2NodeComponentConfiguration(&e2NodeUpdateItem->value.choice.E2nodeComponentConfigUpdate_Item.e2nodeComponentConfiguration);
4732                                  freeE2NodeComponentIdentifier(&e2NodeUpdateItem->value.choice.E2nodeComponentConfigUpdate_Item.e2nodeComponentID);
4733                                  DU_FREE(e2NodeUpdateItem, sizeof(E2nodeComponentConfigUpdate_ItemIEs_t));
4734                               }
4735                               DU_FREE(e2NodeUpdateList->list.array, e2NodeUpdateList->list.size);
4736                            }
4737                            break;
4738                         }
4739                      case ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval:
4740                         {
4741                            e2NodeRemovalList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemoval_List;
4742                            if(e2NodeRemovalList->list.array)
4743                            {
4744                               for(e2NodeRemovalListIdx = 0; e2NodeRemovalListIdx< e2NodeRemovalList->list.count; e2NodeRemovalListIdx++)
4745                               {
4746                                  e2NodeRemovalItem = (E2nodeComponentConfigRemoval_ItemIEs_t *) e2NodeRemovalList->list.array[e2NodeRemovalListIdx];
4747
4748                                  freeE2NodeComponentIdentifier(&e2NodeRemovalItem->value.choice.E2nodeComponentConfigRemoval_Item.e2nodeComponentID);
4749                                  DU_FREE(e2NodeRemovalItem, sizeof(E2nodeComponentConfigRemoval_ItemIEs_t));
4750                               }
4751                               DU_FREE(e2NodeRemovalList->list.array, e2NodeRemovalList->list.size);
4752                            }
4753                            break;
4754                         }
4755                            
4756                      default:
4757                         break;
4758                   }
4759                   DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
4760                }
4761             }
4762             DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
4763          }
4764          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4765       }
4766       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4767    }
4768 }
4769
4770 /*******************************************************************
4771  *
4772  * @brief Buld and send the E2 node config update msg 
4773  *
4774  * @details
4775  *
4776  *    Function : BuildAndSendE2NodeConfigUpdate
4777  *
4778  *    Functionality:
4779  *         - Buld and send the E2 node config update msg
4780  *
4781  * @params[in] 
4782  * @return ROK     - success
4783  *         RFAILED - failure
4784  *
4785  * ****************************************************************/
4786
4787 uint8_t BuildAndSendE2NodeConfigUpdate(E2NodeConfigList *e2NodeList)
4788 {
4789    uint8_t ret = RFAILED;
4790    uint8_t arrIdx = 0,elementCnt = 0, transId=0;
4791    E2AP_PDU_t  *e2apMsg = NULLP;
4792    asn_enc_rval_t     encRetVal;       /* Encoder return value */
4793    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate = NULLP;
4794
4795    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update\n");
4796    do
4797    {
4798       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4799       if(e2apMsg == NULLP)
4800       {
4801          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4802          break;
4803       }
4804
4805       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4806       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4807       if(e2apMsg->choice.initiatingMessage == NULLP)
4808       {
4809          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4810          break;
4811       }
4812       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4813       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
4814       e2apMsg->choice.initiatingMessage->value.present = \
4815       InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate;
4816       e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
4817       
4818       elementCnt =1;
4819       if(e2NodeList->addE2NodeCount)
4820          elementCnt++;
4821       if(e2NodeList->updateE2NodeCount)
4822          elementCnt++;
4823       if(e2NodeList->removeE2NodeCount)
4824          elementCnt++;
4825
4826       e2NodeConfigUpdate->protocolIEs.list.count = elementCnt;
4827       e2NodeConfigUpdate->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdate_IEs_t*);
4828       DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
4829       if(e2NodeConfigUpdate->protocolIEs.list.array == NULLP)
4830       {
4831          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
4832          break;
4833       }
4834       
4835       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
4836       {
4837          DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
4838          if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx] == NULLP)
4839          {
4840             
4841             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
4842             break;
4843          }
4844       }
4845       
4846       if(arrIdx<elementCnt)
4847          break;
4848
4849       arrIdx = 0;
4850       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4851       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4852       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_TransactionID;
4853       transId = assignTransactionId();
4854       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
4855
4856       if(e2NodeList->addE2NodeCount)
4857       {
4858          arrIdx++;
4859          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition;
4860          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4861          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigAddition_List;
4862          if(BuildE2NodeConfigAddList(&(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List),\
4863          ProcedureCodeE2_id_E2nodeConfigurationUpdate, e2NodeList->addE2NodeCount, e2NodeList->addE2Node)!=ROK)
4864          {
4865             DU_LOG("\nERROR  -->  E2AP : Failed to create E2 Node config list");
4866             break;
4867          }
4868       }
4869       
4870       if(e2NodeList->updateE2NodeCount)
4871       {
4872          arrIdx++;
4873          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate;
4874          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4875          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigUpdate_List;
4876          if(BuildE2NodeConfigUpdateList(&e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdate_List,\
4877          e2NodeList->updateE2NodeCount, e2NodeList->updateE2Node) != ROK)
4878          {
4879
4880             DU_LOG("\nERROR  -->  E2AP : Failed to update the E2 node configuration");
4881             break;
4882          }
4883       }
4884       
4885       if(e2NodeList->removeE2NodeCount)
4886       {
4887          arrIdx++;
4888          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval;
4889          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4890          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigRemoval_List;
4891          if(BuildE2NodeConfigRemoveList(&e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemoval_List,\
4892          e2NodeList->removeE2NodeCount, e2NodeList->removeE2Node) != ROK)
4893          {
4894
4895             DU_LOG("\nERROR  -->  E2AP : Failed to remove the E2 node configuration");
4896             break;
4897          }
4898       }
4899
4900       /* Prints the Msg formed */
4901       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4902
4903       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4904       encBufSize = 0;
4905       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
4906       if(encRetVal.encoded == ENCODE_FAIL)
4907       {
4908          DU_LOG("\nERROR  -->  E2AP : Could not encode E2nodeConfigurationUpdate structure (at %s)\n",\
4909                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4910          break;
4911       }
4912       else
4913       {
4914          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2nodeConfigurationUpdate\n");
4915 #ifdef DEBUG_ASN_PRINT
4916          for(int i=0; i< encBufSize; i++)
4917          {
4918             printf("%x",encBuf[i]);
4919          }
4920 #endif
4921       }
4922       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize))
4923       {
4924          DU_LOG("\nERROR  -->  E2AP : Sending E2 node config update failed");
4925          break;
4926       }
4927
4928       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
4929       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
4930       memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.e2NodeConfigUpdate.configList, e2NodeList, sizeof(E2NodeConfigList));
4931       ret = ROK;
4932       break;
4933    }while(true);
4934    
4935    FreeE2NodeConfigUpdate(e2apMsg);
4936    return ret;
4937 }
4938
4939 /*******************************************************************
4940  *
4941  * @brief Deallocate the memory allocated for E2ResetRequest msg
4942  *
4943  * @details
4944  *
4945  *    Function : FreeE2ResetRequest
4946  *
4947  *    Functionality:
4948  *       - freeing the memory allocated for E2ResetRequest
4949  *
4950  * @params[in] E2AP_PDU_t *e2apMsg
4951  * @return ROK     - success
4952  *         RFAILED - failure
4953  *
4954  * ****************************************************************/
4955 void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg)
4956 {
4957    uint8_t ieIdx =0;
4958    ResetRequestE2_t  *resetReq = NULLP;
4959
4960    if(e2apMsg != NULLP)
4961    {
4962       if(e2apMsg->choice.initiatingMessage != NULLP)
4963       {
4964          resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4965          if(resetReq->protocolIEs.list.array)
4966          {
4967             for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
4968             {
4969                DU_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4970             }
4971             DU_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4972          }
4973          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4974       }
4975       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4976    }
4977 }
4978
4979 /*******************************************************************
4980  *
4981  * @brief Build and send the E2 reset request msg
4982  *
4983  * @details
4984  *
4985  *    Function : BuildAndSendE2ResetRequest
4986  *
4987  *    Functionality:
4988  *         - Buld and send the E2 reset request msg to RIC
4989  *
4990  * @params[in]
4991  *    Reset cause
4992  * @return ROK     - success
4993  *         RFAILED - failure
4994  *
4995  * ****************************************************************/
4996 uint8_t BuildAndSendE2ResetRequest(E2FailureCause resetCause)
4997 {
4998    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
4999    uint8_t ret = RFAILED;
5000    E2AP_PDU_t        *e2apMsg = NULLP;
5001    ResetRequestE2_t  *resetReq = NULLP;
5002    asn_enc_rval_t     encRetVal;       /* Encoder return value */
5003
5004    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Request\n");
5005
5006    do
5007    {
5008       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
5009       if(e2apMsg == NULLP)
5010       {
5011          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for E2AP-PDU failed");
5012          break;
5013       }
5014
5015       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
5016       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5017       if(e2apMsg->choice.initiatingMessage == NULLP)
5018       {
5019          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for initiatingMessage");
5020          break;
5021       }
5022
5023       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
5024       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
5025       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
5026       resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
5027
5028       elementCnt = 2;
5029       resetReq->protocolIEs.list.count = elementCnt;
5030       resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
5031
5032       DU_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
5033       if(!resetReq->protocolIEs.list.array)
5034       {
5035          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
5036             Reset Request IE array");
5037          break;
5038       }
5039
5040       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
5041       {
5042          DU_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
5043          if(!resetReq->protocolIEs.list.array[ieIdx])
5044          {
5045             DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
5046             Reset Request IE array element");
5047             break;
5048          }
5049       }
5050
5051       /* In case of failure */
5052       if(ieIdx < elementCnt)
5053          break;
5054
5055       ieIdx = 0;
5056       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
5057       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
5058       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
5059       transId = assignTransactionId();
5060       resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
5061
5062       ieIdx++;
5063       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
5064       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
5065       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
5066       fillE2Cause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, resetCause);
5067
5068       /* Prints the Msg formed */
5069       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5070
5071       memset(encBuf, 0, ENC_BUF_MAX_LEN);
5072       encBufSize = 0;
5073       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
5074             encBuf);
5075       if(encRetVal.encoded == ENCODE_FAIL)
5076       {
5077          DU_LOG("\nERROR  -->  E2AP : Could not encode reset request structure (at %s)\n",\
5078                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
5079          break;
5080       }
5081       else
5082       {
5083          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for reset request\n");
5084 #ifdef DEBUG_ASN_PRINT
5085          for(int i=0; i< encBufSize; i++)
5086          {
5087             printf("%x",encBuf[i]);
5088          }
5089 #endif
5090       }
5091       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
5092       {
5093          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
5094          break;
5095       }
5096
5097       /* In case the message is sent successfully, store the transaction info to
5098        * be used when response is received */
5099       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
5100       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5101
5102       ret = ROK;
5103       break;
5104    }while(true);
5105
5106    /* Free all memory */
5107    FreeE2ResetRequest(e2apMsg);
5108    return ret;
5109 }
5110
5111 /*******************************************************************
5112  *
5113  * @brief Deallocate the memory allocated for Reset Response msg
5114  *
5115  * @details
5116  *
5117  *    Function : freeAperDecodingOfE2ResetRsp
5118  *
5119  *    Functionality:
5120  *       - freeing the memory allocated for Reset response
5121  *
5122  * @params[in] ResetResponseE2_t *resetResponse
5123  * @return void
5124  *
5125  * ****************************************************************/
5126 void freeAperDecodingOfE2ResetRsp(ResetResponseE2_t *resetResponse)
5127 {
5128    uint8_t ieIdx;
5129
5130    if(resetResponse)
5131    {
5132       if(resetResponse->protocolIEs.list.array)
5133       {
5134          for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
5135          {
5136             if(resetResponse->protocolIEs.list.array[ieIdx])
5137             {
5138                switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
5139                {
5140                   case ProtocolIE_IDE2_id_TransactionID:
5141                      break;
5142
5143                   case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
5144                      break;
5145                }
5146                free(resetResponse->protocolIEs.list.array[ieIdx]);
5147             }
5148          }
5149          free(resetResponse->protocolIEs.list.array);
5150       }
5151    }
5152 }
5153
5154 /******************************************************************
5155  *
5156  * @brief Processes E2 Reset Response sent by RIC
5157  *
5158  * @details
5159  *
5160  *    Function : procResetResponse
5161  *
5162  *    Functionality: Processes E2 Reset Response sent by RIC
5163  *
5164  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5165  * @return void
5166  *
5167  * ****************************************************************/
5168 void procResetResponse(E2AP_PDU_t *e2apMsg)
5169 {
5170    bool invalidTransId=false;
5171    uint8_t ieIdx =0, transId =0;
5172    uint16_t ranFuncIdx=0;
5173    ResetResponseE2_t *resetResponse =NULLP;
5174
5175    DU_LOG("\nINFO   -->  E2AP : E2 Reset Response received");
5176    resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;;
5177
5178    for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
5179    {
5180       switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
5181       {
5182          case ProtocolIE_IDE2_id_TransactionID:
5183             {
5184                transId = resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
5185                if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) && \
5186                      (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
5187                {
5188                   memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
5189                }
5190                else
5191                {
5192                   DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
5193                   invalidTransId = true;
5194                }
5195                break;
5196             }
5197          case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
5198             {
5199                for(ranFuncIdx=0; ranFuncIdx<MAX_RAN_FUNCTION; ranFuncIdx++)
5200                {
5201                   if(duCb.e2apDb.ranFunction[ranFuncIdx].id >0)
5202                   {
5203                      deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList));
5204                      memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo));
5205                   }
5206                }
5207                break;
5208             }
5209          default:
5210             {
5211                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2 Reset Response : %ld",
5212                      resetResponse->protocolIEs.list.array[ieIdx]->id);
5213                break;
5214             }
5215       }
5216
5217       if(invalidTransId == true)
5218       {
5219          break;
5220       }
5221    }
5222
5223    freeAperDecodingOfE2ResetRsp(resetResponse);
5224 }
5225
5226 /******************************************************************
5227  *
5228  * @brief Deallocation of memory allocated by aper decoder for e2 setup Failure
5229  *
5230  * @details
5231  *
5232  *    Function : freeAperDecodingOfE2SetupFailure
5233  *
5234  *    Functionality: Deallocation of memory allocated by aper decoder for e2
5235  *    setup Failure
5236  *
5237  * @params[in] E2setupFailure_t *e2SetupFailure;
5238  * @return void
5239  *
5240  * ****************************************************************/
5241 void freeAperDecodingOfE2SetupFailure(E2setupFailure_t *e2SetupFailure)
5242 {
5243    uint8_t arrIdx;
5244
5245    if(e2SetupFailure)
5246    {
5247       if(e2SetupFailure->protocolIEs.list.array)
5248       {
5249          for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
5250          {
5251             if(e2SetupFailure->protocolIEs.list.array[arrIdx])
5252             {
5253                free(e2SetupFailure->protocolIEs.list.array[arrIdx]);  
5254             }
5255          }
5256          free(e2SetupFailure->protocolIEs.list.array);
5257       }
5258    }
5259 }
5260 /******************************************************************
5261  *
5262  * @brief Processes E2 Setup Failure sent by RIC
5263  *
5264  * @details
5265  *
5266  *    Function : procE2SetupFailure
5267  *
5268  *    Functionality: Processes E2 Setup failure sent by RIC
5269  *
5270  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5271  * @return ROK     - success
5272  *         RFAILED - failure
5273  *
5274  * ****************************************************************/
5275 void procE2SetupFailure(E2AP_PDU_t *e2apMsg)
5276 {
5277    uint8_t arrIdx =0, transId =0, timerValue=0; 
5278    E2setupFailure_t *e2SetupFailure;
5279
5280    DU_LOG("\nINFO   -->  E2AP : E2 Setup failure received"); 
5281    e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
5282
5283    for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
5284    {
5285       switch(e2SetupFailure->protocolIEs.list.array[arrIdx]->id)
5286       {
5287          case ProtocolIE_IDE2_id_TransactionID:
5288          {
5289             transId = e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
5290             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
5291                   (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
5292             {
5293                memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
5294             }
5295             else
5296             {
5297                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
5298                return ;
5299             }
5300             break;
5301          }
5302          case ProtocolIE_IDE2_id_TimeToWaitE2:
5303             {
5304                timerValue = convertE2WaitTimerEnumToValue(e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
5305                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR)) == FALSE)
5306                {
5307                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR, timerValue);
5308                }
5309                else
5310                {
5311                   DU_LOG("\nERROR   -->  E2AP : EVENT_E2_SETUP_TMR timer is already running");
5312                   return;
5313                }
5314                break; 
5315             }
5316       }
5317    }
5318
5319    freeAperDecodingOfE2SetupFailure(e2SetupFailure);
5320 }
5321 /******************************************************************
5322  *
5323  * @brief Deallocation of memory allocated by aper decoder for RIC service Query
5324  *
5325  * @details
5326  *
5327  *    Function : freeAperDecodingOfRicServiceQuery
5328  *
5329  *    Functionality: Deallocation of memory allocated by aper decoder for RIC
5330  *    service Query
5331  *
5332  * @params[in] RICserviceQuery_t *ricServiceQuery;
5333  * @return void
5334  *
5335  * ****************************************************************/
5336
5337 void freeAperDecodingOfRicServiceQuery(RICserviceQuery_t *ricServiceQuery)
5338 {
5339    uint8_t arrIdx,ranFuncIdx;
5340     RANfunctionsID_List_t *ranFuncAddedList;
5341
5342    if(ricServiceQuery)
5343    {
5344       if(ricServiceQuery->protocolIEs.list.array)
5345       {
5346          for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
5347          {
5348             if(ricServiceQuery->protocolIEs.list.array[arrIdx])
5349             {
5350                switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
5351                {
5352                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5353                   {
5354                      ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5355                      if(ranFuncAddedList->list.array)
5356                      {
5357                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
5358                         {
5359                            free(ranFuncAddedList->list.array[ranFuncIdx]);
5360                         }
5361                         free(ranFuncAddedList->list.array);;
5362                      }
5363                      break;
5364                   }
5365                   default:
5366                      break;
5367                }
5368                free(ricServiceQuery->protocolIEs.list.array[arrIdx]);
5369             }
5370          }
5371          free(ricServiceQuery->protocolIEs.list.array);
5372       }
5373    }
5374 }
5375 /*******************************************************************
5376  *
5377  * @brief Build RanFunction Delete List
5378  *
5379  * @details
5380  *
5381  *    Function : BuildRanFunctionDeleteList
5382  *
5383  * Functionality:  Build RanFunction Delete List
5384  *
5385  * @params[in]
5386  *    RANfunctionsID List
5387  *    Count of the RAN function
5388  *    Received RAN function list
5389  *
5390  * @return ROK     - success
5391  *         RFAILED - failure
5392  *
5393  ******************************************************************/
5394
5395 uint8_t BuildRanFunctionDeleteList(RANfunctionsID_List_t *deleteList, uint8_t count, RanFuncInfo *recvdRanFunc)
5396 {
5397    uint8_t ranFuncIdx=0;
5398    RANfunctionID_ItemIEs_t *delRanFuncItem;
5399
5400    if(count)
5401    {
5402       deleteList->list.count = count;
5403       deleteList->list.size = deleteList->list.count * sizeof(RANfunctionID_ItemIEs_t*);
5404       DU_ALLOC(deleteList->list.array, deleteList->list.size);
5405       if(deleteList->list.array == NULLP)
5406       {
5407          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
5408          return RFAILED;
5409       }
5410       for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
5411       {
5412          DU_ALLOC(deleteList->list.array[ranFuncIdx], sizeof(RANfunctionID_ItemIEs_t));
5413          if(deleteList->list.array[ranFuncIdx] == NULLP)
5414          {
5415             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
5416             return RFAILED;
5417          }
5418          delRanFuncItem= (RANfunctionID_ItemIEs_t *) deleteList->list.array[ranFuncIdx];
5419          delRanFuncItem->id = ProtocolIE_IDE2_id_RANfunctionID_Item;
5420          delRanFuncItem->criticality = CriticalityE2_ignore;
5421          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionID = recvdRanFunc[ranFuncIdx].id;
5422          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionRevision = recvdRanFunc[ranFuncIdx].revisionCounter;
5423
5424       }
5425    }
5426    return ROK;
5427 }
5428 /*******************************************************************
5429  *
5430  * @brief De Allocate  Ric Service Update message
5431  *
5432  * @details
5433  *
5434  *    Function : FreeRicServiceUpdate
5435  *
5436  *    Functionality: De-Allocating Ric Service Update message
5437  *
5438  * @params[in] E2AP_PDU_t *e2apMsg
5439
5440  * @return void
5441  *
5442  * ****************************************************************/
5443
5444 void FreeRicServiceUpdate(E2AP_PDU_t *e2apMsg)
5445 {
5446    uint8_t arrIdx = 0;
5447    uint8_t ranFuncAddListIdx=0, ranFuncDelIdx=0;
5448    RICserviceUpdate_t *ricServiceUpdate;
5449    RANfunctions_List_t *ranFunctionsList;
5450    RANfunction_ItemIEs_t *ranFuncItemIe;
5451    RANfunction_Item_t  *ranFunItem;
5452    RANfunctionsID_List_t *deleteList;
5453
5454    /* De-allocating Memory */
5455    if(e2apMsg != NULLP)
5456    {
5457       if(e2apMsg->choice.initiatingMessage != NULLP)
5458       {
5459          ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
5460          if(ricServiceUpdate->protocolIEs.list.array != NULLP)
5461          {
5462             for(arrIdx = 0; arrIdx < ricServiceUpdate->protocolIEs.list.count; arrIdx++)
5463             {
5464                if(ricServiceUpdate->protocolIEs.list.array[arrIdx] != NULLP)
5465                {
5466                   switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
5467                   {
5468                      case ProtocolIE_IDE2_id_TransactionID:
5469                         break;
5470
5471                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
5472                      case ProtocolIE_IDE2_id_RANfunctionsModified:
5473                         {
5474                            ranFunctionsList = &(ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List);
5475                            if(ranFunctionsList->list.array)
5476                            {
5477                               for(ranFuncAddListIdx= 0; ranFuncAddListIdx< ranFunctionsList->list.count; ranFuncAddListIdx++)
5478                               {
5479                                  if(ranFunctionsList->list.array[ranFuncAddListIdx])
5480                                  {
5481                                     ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncAddListIdx];
5482                                     ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
5483                                     DU_FREE(ranFunItem->ranFunctionOID.buf, ranFunItem->ranFunctionOID.size);
5484                                     DU_FREE(ranFunItem->ranFunctionDefinition.buf, ranFunItem->ranFunctionDefinition.size);
5485                                     DU_FREE(ranFunctionsList->list.array[ranFuncAddListIdx], sizeof(RANfunction_ItemIEs_t));
5486                                  }
5487                               }
5488                               DU_FREE(ranFunctionsList->list.array, ranFunctionsList->list.size);
5489                            }
5490                            break;
5491                         }
5492                      case ProtocolIE_IDE2_id_RANfunctionsDeleted:
5493                         {
5494                            deleteList= &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5495                            if(deleteList->list.array)
5496                            {
5497                               for(ranFuncDelIdx = 0; ranFuncDelIdx< deleteList->list.count; ranFuncDelIdx++)
5498                               {
5499                                  DU_FREE(deleteList->list.array[ranFuncDelIdx], sizeof(RANfunctionID_ItemIEs_t));
5500                               }
5501                               DU_FREE(deleteList->list.array, deleteList->list.size);
5502   
5503                            }
5504                            break;
5505                         }
5506                      default:
5507                         DU_LOG("\nERROR  --> E2AP: Invalid event at ricServiceUpdate %ld ",\
5508                               (ricServiceUpdate->protocolIEs.list.array[arrIdx]->id));
5509                         break;
5510                   }
5511                   DU_FREE(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
5512                }
5513             }
5514             DU_FREE(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
5515          }
5516          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5517       }
5518       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
5519    }
5520 }
5521
5522 /*******************************************************************
5523  *
5524  * @brief Builds and Send the RicServiceUpdateuest
5525  *
5526  * @details
5527  *
5528  *    Function : BuildAndSendRicServiceUpdate
5529  *
5530  * Functionality:Fills the RicServiceUpdateuest
5531  *
5532  * @return ROK     - success
5533  *         RFAILED - failure
5534  *
5535  ******************************************************************/
5536
5537 uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate)
5538 {
5539    uint8_t arrIdx = 0, elementCnt=0;
5540    uint8_t transId = 0, ret = RFAILED;
5541    bool memAllocFailed =false;
5542    E2AP_PDU_t        *e2apMsg = NULLP;
5543    RICserviceUpdate_t  *ricServiceUpdate = NULLP;
5544    asn_enc_rval_t     encRetVal;       /* Encoder return value */
5545
5546    DU_LOG("\nINFO   -->  E2AP : Building Ric Service Update\n");
5547    do
5548    {
5549       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
5550       if(e2apMsg == NULLP)
5551       {
5552          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
5553          break;
5554       }
5555       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
5556       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5557       if(e2apMsg->choice.initiatingMessage == NULLP)
5558       {
5559          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
5560          break;
5561       }
5562       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
5563       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
5564       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceUpdate;
5565       ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
5566       
5567       /* For TransId IE, set elementCnt to 1.
5568       If there is any item in the RAN function add list, RAN function modification list, or RAN function delete list, increment the elementCnt.*/
5569
5570       elementCnt =1;
5571       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5572         elementCnt++;
5573       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
5574          elementCnt++;
5575       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
5576          elementCnt++;
5577        
5578       ricServiceUpdate->protocolIEs.list.count = elementCnt;
5579       ricServiceUpdate->protocolIEs.list.size = elementCnt * sizeof(RICserviceUpdate_IEs_t*);
5580
5581       /* Initialize the E2Setup members */
5582       DU_ALLOC(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
5583       if(ricServiceUpdate->protocolIEs.list.array == NULLP)
5584       {
5585          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
5586          break;
5587       }
5588       
5589       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
5590       {
5591          DU_ALLOC(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
5592          if(ricServiceUpdate->protocolIEs.list.array[arrIdx] == NULLP)
5593          {
5594             memAllocFailed = true;
5595             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayIdx [%d]", arrIdx);
5596             break;
5597          }
5598       }
5599       if(memAllocFailed == true)
5600          break;
5601
5602       arrIdx = 0;
5603
5604       /* TransactionID */
5605       ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
5606       ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5607       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
5608       if(serviceUpdate.dir == E2_NODE_INITIATED)
5609          transId = assignTransactionId();
5610       else
5611         transId = serviceUpdate.transId;
5612       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
5613
5614       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5615       {
5616          arrIdx++;
5617          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAdded;
5618          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5619          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
5620          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,\
5621          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded, serviceUpdate.recvRanFuncList.ranFunToBeAdded) !=ROK)
5622          {
5623             break;
5624          }
5625       }
5626
5627       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
5628       {
5629          arrIdx++;
5630          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsModified;
5631          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5632          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
5633          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,
5634          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeModified, serviceUpdate.recvRanFuncList.ranFunToBeModified) !=ROK)
5635          {
5636             break;
5637          }
5638       }
5639
5640       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
5641       {
5642          arrIdx++;
5643          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsDeleted;
5644          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5645          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctionsID_List;
5646          if(BuildRanFunctionDeleteList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List,\
5647          serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted, serviceUpdate.recvRanFuncList.ranFunToBeDeleted) != ROK)
5648          {
5649             break;
5650          }
5651       }
5652       /* Prints the Msg formed */
5653       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5654
5655       memset(encBuf, 0, ENC_BUF_MAX_LEN);
5656       encBufSize = 0;
5657       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
5658       if(encRetVal.encoded == ENCODE_FAIL)
5659       {
5660          DU_LOG("\nERROR  -->  E2AP : Could not encode RicServiceUpdateuest structure (at %s)\n",\
5661                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
5662          break;
5663       }
5664       else
5665       {
5666          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RicServiceUpdateuest\n");
5667 #ifdef DEBUG_ASN_PRINT
5668          for(int i=0; i< encBufSize; i++)
5669          {
5670             printf("%x",encBuf[i]);
5671          }
5672 #endif
5673       }
5674       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
5675       {
5676          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
5677          break;
5678       }
5679       ret = ROK;
5680       break;
5681    }while(true);
5682    
5683    if(ret == ROK)
5684    {
5685       if(serviceUpdate.dir == E2_NODE_INITIATED)
5686       {
5687          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
5688          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5689       }
5690       else
5691       {
5692          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId = transId;
5693          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5694       }
5695       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.dir = serviceUpdate.dir;
5696       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.transId =transId;
5697       memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.recvRanFuncList, &serviceUpdate.recvRanFuncList, sizeof(E2TmpRanFunList));
5698    }
5699    FreeRicServiceUpdate(e2apMsg);
5700    return ret;
5701 }
5702 /******************************************************************
5703  *
5704  * @brief Processes RIC service Query sent by RIC
5705  *
5706  * @details
5707  *
5708  *    Function : procRicServiceQuery
5709  *
5710  *    Functionality: Processes RIC service Query sent by RIC
5711  *
5712  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5713  * @return ROK     - success
5714  *         RFAILED - failure
5715  *
5716  * ****************************************************************/
5717
5718 void procRicServiceQuery(E2AP_PDU_t *e2apMsg)
5719 {
5720    ConfigType action;
5721    uint16_t arrIdx =0, ranFuncIdx=0,tmpIdx=0;
5722    uint16_t id,revisionCcounter;
5723    bool tmpArray[MAX_RAN_FUNCTION] = {false};
5724    RICserviceQuery_t *ricServiceQuery=NULL;
5725    RicServiceUpdate ricUpdate;
5726    RANfunctionID_ItemIEs_t *ranFuncAddedItemIe;
5727    RANfunctionsID_List_t *ranFuncAddedList;
5728
5729    DU_LOG("\nINFO   -->  E2AP : RIC Service Query received");
5730    memset(&ricUpdate, 0, sizeof(RicServiceUpdate));
5731    ricUpdate.dir = RIC_INITIATED;
5732    ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
5733
5734    for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
5735    {
5736       switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
5737       {
5738          /* TODO completing in next patch/gerrit */
5739          case ProtocolIE_IDE2_id_TransactionID:
5740          {
5741             ricUpdate.transId = ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
5742             break;
5743          }
5744
5745          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5746          {
5747             ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5748             if(ranFuncAddedList->list.array)
5749             {
5750                for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
5751                {
5752                   if(ranFuncAddedList->list.array[ranFuncIdx])
5753                   {
5754                      /* Using the RAN function Id, identify the RAN function to be modified or deleted.  */
5755                      
5756                      ranFuncAddedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAddedList->list.array[ranFuncIdx];
5757                      id = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionID;
5758                      revisionCcounter = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision;
5759                      
5760                      if((id != duCb.e2apDb.ranFunction[id-1].id))
5761                      {
5762                         action = CONFIG_DEL;
5763                      }
5764                      else if((id == duCb.e2apDb.ranFunction[id-1].id)&&(revisionCcounter!=duCb.e2apDb.ranFunction[id-1].revisionCounter))
5765                      {
5766                         action = CONFIG_MOD;
5767                      }
5768
5769                      if(action == CONFIG_DEL)
5770                      {
5771                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].id = id;
5772                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].revisionCounter = revisionCcounter;
5773                         ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted++;
5774                      }
5775                      else if(action == CONFIG_MOD)
5776                      {
5777                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].id = id;
5778                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].revisionCounter = revisionCcounter;
5779                         ricUpdate.recvRanFuncList.numOfRanFunToBeModified++;
5780                      }
5781
5782                      /* If any ID is set to true, it means that the ID has been used in either modification or deletion list. 
5783                       * Else we will add the IDs into the added list */
5784                      tmpArray[id-1] = true;
5785                   }
5786                }
5787             }
5788             break;
5789          }
5790       }
5791    }
5792
5793    /*  Traversing the whole RAN function list in ducb to check if any new Ran function ids have been added. */
5794    for(arrIdx =0; arrIdx<MAX_RAN_FUNCTION; arrIdx++)
5795    {
5796       tmpIdx= ricUpdate.recvRanFuncList.numOfRanFunToBeAdded;
5797       if((duCb.e2apDb.ranFunction[arrIdx].id >0)&&(!tmpArray[arrIdx]))
5798       {
5799          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[arrIdx].id;
5800          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[arrIdx].revisionCounter;
5801          ricUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
5802       }
5803    }
5804
5805    if(BuildAndSendRicServiceUpdate(ricUpdate)!= ROK)
5806    {
5807       DU_LOG("\nERROR  -->  E2AP : Failed to build and send ric service update message");
5808    }
5809
5810    freeAperDecodingOfRicServiceQuery(ricServiceQuery);
5811 }
5812
5813 /******************************************************************
5814  *
5815  * @brief Deallocation of memory allocated by aper decoder for 
5816  *    RIC service update ack
5817  *
5818  * @details
5819  *
5820  *    Function : freeAperDecodingOfRicServiceUpdateAck
5821  *
5822  *    Functionality: Deallocation of memory allocated by aper decoder 
5823  *    for RIC service update ack
5824  *
5825  * @params[in] RICserviceUpdateAck_t *ricServiceAck;
5826  * @return void
5827  *
5828  * ****************************************************************/
5829
5830 void freeAperDecodingOfRicServiceUpdateAck(RICserviceUpdateAcknowledge_t *ricServiceAck)
5831 {
5832    uint8_t arrIdx=0,ranFuncIdx=0;
5833    RANfunctionsID_List_t *ranFuncAddedList=NULL;
5834
5835    if(ricServiceAck)
5836    {
5837       if(ricServiceAck->protocolIEs.list.array)
5838       {
5839          for(arrIdx=0; arrIdx<ricServiceAck->protocolIEs.list.count; arrIdx++)
5840          {
5841             if(ricServiceAck->protocolIEs.list.array[arrIdx])
5842             {
5843                switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id)
5844                {
5845                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5846                   {
5847                      ranFuncAddedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5848                      if(ranFuncAddedList->list.array)
5849                      {
5850                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
5851                         {
5852                            free(ranFuncAddedList->list.array[ranFuncIdx]);
5853                         }
5854                         free(ranFuncAddedList->list.array);
5855                      }
5856                      break;
5857                   }
5858                   default:
5859                      break;
5860                }
5861                free(ricServiceAck->protocolIEs.list.array[arrIdx]);  
5862             }
5863          }
5864          free(ricServiceAck->protocolIEs.list.array);
5865       }
5866    }
5867 }
5868
5869 /******************************************************************
5870  *
5871  * @brief Processes RIC service update ack sent by RIC
5872  *
5873  * @details
5874  *
5875  *    Function : procRicServiceUpdateAck
5876  *
5877  *    Functionality: Processes RIC service update ack sent by RIC
5878  *
5879  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5880  * @return ROK     - success
5881  *         RFAILED - failure
5882  *
5883  * ****************************************************************/
5884
5885 void procRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
5886 {
5887    uint8_t arrIdx =0, transId =0; 
5888    uint16_t id =0, tmpIdx=0, ranFuncIdx=0;
5889    RicServiceUpdate serviceUpdate;
5890    RANfunctionsIDcause_List_t *rejectedList=NULL;
5891    RICserviceUpdateAcknowledge_t *ricServiceAck=NULL;
5892    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
5893    
5894    DU_LOG("\nINFO   -->  E2AP : RIC service update ack received"); 
5895    memset(&serviceUpdate, 0, sizeof(RicServiceUpdate));
5896    ricServiceAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
5897    
5898    for(arrIdx=0; arrIdx<ricServiceAck->protocolIEs.list.count; arrIdx++)
5899    {
5900       switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id)
5901       {
5902          case ProtocolIE_IDE2_id_TransactionID:
5903          {
5904             transId = ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
5905             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
5906             (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
5907             {
5908               memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
5909             }
5910             else if((duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId == transId) &&\
5911             (duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
5912             {
5913               memset(&duCb.e2apDb.e2TransInfo.ricInitTransaction[transId], 0, sizeof(E2TransInfo));
5914             }
5915             else
5916             {
5917                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
5918                return ;
5919             }
5920             break;
5921          }
5922          
5923          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5924             break;
5925
5926          case ProtocolIE_IDE2_id_RANfunctionsRejected:
5927          {
5928             rejectedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
5929             if(rejectedList->list.array)
5930             {
5931                for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
5932                {
5933                   ranFuncRejectedItemIe =  (RANfunctionIDcause_ItemIEs_t*)rejectedList->list.array[ranFuncIdx];
5934                   id = ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID;
5935                   tmpIdx= serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded;
5936                   serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[id-1].id;
5937                   serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[id-1].revisionCounter;
5938                   serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
5939                }
5940             }
5941             break;
5942          }
5943
5944       }
5945    }
5946
5947    if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5948    {
5949       serviceUpdate.dir = E2_NODE_INITIATED;
5950       BuildAndSendRicServiceUpdate(serviceUpdate);
5951    }
5952    freeAperDecodingOfRicServiceUpdateAck(ricServiceAck);
5953 }
5954
5955 /******************************************************************
5956  *
5957  * @brief Deallocation of memory allocated by aper decoder for 
5958  *       RIC service update failure
5959  *
5960  * @details
5961  *
5962  *    Function : freeAperDecodingOfRicServiceUpdateFailure
5963  *
5964  *    Functionality: Deallocation of memory allocated by aper decoder 
5965  *    for RIC service update failure
5966  *
5967  * @params[in] RICserviceUpdateFailure_t *ricServiceFailure;
5968  * @return void
5969  *
5970  * ****************************************************************/
5971
5972 void freeAperDecodingOfRicServiceUpdateFailure(RICserviceUpdateFailure_t *ricServiceFailure)
5973 {
5974    uint8_t arrIdx=0;
5975
5976    if(ricServiceFailure)
5977    {
5978       if(ricServiceFailure->protocolIEs.list.array)
5979       {
5980          for(arrIdx=0; arrIdx<ricServiceFailure->protocolIEs.list.count; arrIdx++)
5981          {
5982             if(ricServiceFailure->protocolIEs.list.array[arrIdx])
5983             {
5984                free(ricServiceFailure->protocolIEs.list.array[arrIdx]);  
5985             }
5986          }
5987          free(ricServiceFailure->protocolIEs.list.array);
5988       }
5989    }
5990 }
5991
5992 /******************************************************************
5993  *
5994  * @brief Processes RIC service update failure sent by RIC
5995  *
5996  * @details
5997  *
5998  *    Function : procRicServiceUpdateFailure
5999  *
6000  *    Functionality: Processes RIC service update failure sent by RIC
6001  *
6002  * @params[in] E2AP_PDU_t ASN decoded E2AP message
6003  * @return ROK     - success
6004  *         RFAILED - failure
6005  *
6006  * ****************************************************************/
6007
6008 void procRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
6009 {
6010    uint8_t arrIdx =0, timerValue=0; 
6011    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
6012
6013    DU_LOG("\nINFO   -->  E2AP : RIC service update failure received"); 
6014    ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
6015
6016    for(arrIdx=0; arrIdx<ricServiceFailure->protocolIEs.list.count; arrIdx++)
6017    {
6018       switch(ricServiceFailure->protocolIEs.list.array[arrIdx]->id)
6019       {
6020          case ProtocolIE_IDE2_id_TransactionID:
6021             {
6022                break;
6023             }
6024          case ProtocolIE_IDE2_id_TimeToWaitE2:
6025             {
6026                timerValue = convertE2WaitTimerEnumToValue(ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
6027                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR)) == FALSE)
6028                {
6029                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR, timerValue);
6030                }
6031                else
6032                {
6033                   DU_LOG("\nERROR   -->  E2AP : EVENT_RIC_SERVICE_UPDATE_TMR  timer is already running");
6034                   return;
6035                }
6036                break; 
6037             }
6038          case ProtocolIE_IDE2_id_CauseE2:
6039             {
6040                break;
6041             }
6042       }
6043    }
6044
6045    freeAperDecodingOfRicServiceUpdateFailure(ricServiceFailure);
6046 }
6047
6048 /******************************************************************
6049  *
6050  * @brief DU Send E2 Node Configuration Update
6051  *
6052  * @details
6053  *
6054  *    Function : duSendE2NodeConfigurationUpdate 
6055  *
6056  *    Functionality: DU Send E2 Node Configuration Update
6057  *
6058  * @return ROK     - success
6059  *         RFAILED - failure
6060  *
6061  * ****************************************************************/
6062
6063 uint8_t duSendE2NodeConfigurationUpdate()
6064 {
6065    E2NodeConfigList e2NodeList;
6066    CmLList *node =NULL;
6067    E2NodeComponent *e2NodeComponentInfo=NULL;
6068
6069    memset(&e2NodeList, 0, sizeof(E2NodeConfigList));
6070    CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node);
6071    while(node)
6072    {
6073       e2NodeComponentInfo = (E2NodeComponent*)node->node;
6074
6075       if(e2NodeComponentInfo->addConfiguration)
6076       {
6077          e2NodeList.addE2Node[e2NodeList.addE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
6078          e2NodeList.addE2Node[e2NodeList.addE2NodeCount].componentId= e2NodeComponentInfo->componentId;
6079          e2NodeList.addE2NodeCount++;
6080          break;
6081       }
6082       if(e2NodeComponentInfo->updateConfiguration)
6083       {
6084          e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
6085          e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].componentId= e2NodeComponentInfo->componentId;
6086          e2NodeList.updateE2NodeCount++;
6087          break;
6088       }
6089       if(e2NodeComponentInfo->deleteConfiguration == true)
6090       {
6091          e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
6092          e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].componentId = e2NodeComponentInfo->componentId;
6093          e2NodeList.removeE2NodeCount++;
6094          break;
6095       }
6096       node = node->next;
6097    }
6098
6099    if(BuildAndSendE2NodeConfigUpdate(&e2NodeList) !=ROK)
6100    {
6101       DU_LOG("\nERROR  -->  E2AP : Failed to build and send e2 node config update message to RIC_stub");
6102       return RFAILED;
6103    }
6104    return ROK;
6105 }
6106
6107 /*******************************************************************
6108  *
6109  * @brief Free RIC Subscription Modification Required
6110  *
6111  * @details
6112  *
6113  *    Function : FreeRicSubsModRequired
6114  *
6115  * Functionality: Freqq RIC Subscription Modification required
6116  *
6117  * @param  E2AP Message PDU to be freed
6118  * @return void
6119  *
6120  ******************************************************************/
6121 void FreeRicSubsModRequired(E2AP_PDU_t *e2apMsg)
6122 {
6123    uint8_t ieIdx = 0, arrIdx = 0;
6124    RICsubscriptionModificationRequired_t  *ricSubsModReqd = NULLP;
6125    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
6126    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
6127    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
6128
6129    if(e2apMsg)
6130    {
6131       if(e2apMsg->choice.initiatingMessage)
6132       {
6133          ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired;
6134          if(ricSubsModReqd->protocolIEs.list.array)
6135          {
6136             for(ieIdx = 0; ieIdx < ricSubsModReqd->protocolIEs.list.count; ieIdx++)
6137             {
6138                if(ricSubsModReqd->protocolIEs.list.array[ieIdx])
6139                {
6140                   ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6141                   switch(ricSubsModReqdIe->id)
6142                   {
6143                      case ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List:
6144                         {
6145                            actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
6146                            if(actionToBeModList->list.array)
6147                            {
6148                               for(arrIdx = 0; arrIdx < actionToBeModList->list.count; arrIdx++)
6149                               { 
6150                                  DU_FREE(actionToBeModList->list.array[arrIdx], \
6151                                     sizeof(RICaction_RequiredToBeModified_ItemIEs_t));
6152                               }
6153                               DU_FREE(actionToBeModList->list.array, actionToBeModList->list.size);
6154                            }
6155                            break;
6156                         }
6157
6158                      case ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List:
6159                         {
6160                            actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
6161                            if(actionToBeRmvList->list.array)
6162                            {
6163                               for(arrIdx = 0; arrIdx < actionToBeRmvList->list.count; arrIdx++)
6164                               { 
6165                                  DU_FREE(actionToBeRmvList->list.array[arrIdx], \
6166                                     sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t));
6167                               }
6168                               DU_FREE(actionToBeRmvList->list.array, actionToBeRmvList->list.size);
6169                            }
6170                            break;
6171                         }
6172
6173                      default:
6174                         break;
6175                   }
6176                   DU_FREE(ricSubsModReqd->protocolIEs.list.array[ieIdx], \
6177                         sizeof(RICsubscriptionModificationRequired_IEs_t));
6178                }
6179             }
6180             DU_FREE(ricSubsModReqd->protocolIEs.list.array, ricSubsModReqd->protocolIEs.list.size);
6181          }
6182          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
6183       }
6184       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
6185    }
6186 }
6187
6188 /* A RIC Subscription includes RIC subsequent action only for RIC Insert service.
6189  * However, E2SM-KPM supports only RIC Report service.
6190  * Hence there is no subsequent action in RIC subscription that may require modification.
6191  * So commenting the action-modification IEs for the time being
6192  */
6193 #if 0
6194 /*******************************************************************
6195  *
6196  * @brief Fill Action required to be modified list
6197  *
6198  * @details
6199  *
6200  *    Function : FillActionReqdToBeModList
6201  *
6202  * Functionality: Fill Action required to be modified list
6203  *
6204  * @param  RIC Actions Required To Be Modified List to be filled
6205  *         Number of actions to be modified
6206  *         RIC Subscription DB
6207  * @return ROK     - success
6208  *         RFAILED - failure
6209  *
6210  ******************************************************************/
6211 uint8_t FillActionReqdToBeModList(RICactions_RequiredToBeModified_List_t *actionToBeModList, uint8_t numActionsMod, \
6212    RicSubscription *ricSubscription)
6213 {
6214    uint8_t arrIdx = 0, actionIdx = 0;
6215    RICaction_RequiredToBeModified_ItemIEs_t *actionToBeMod = NULL;
6216
6217    actionToBeModList->list.count = numActionsMod;
6218    actionToBeModList->list.size = numActionsMod * sizeof(RICaction_RequiredToBeModified_ItemIEs_t *);
6219    DU_ALLOC(actionToBeModList->list.array, actionToBeModList->list.size);
6220    if(!actionToBeModList->list.array)
6221    {
6222       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6223       return RFAILED;
6224    }
6225
6226    arrIdx = 0;
6227    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
6228    {
6229       if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD)
6230       {
6231          DU_ALLOC(actionToBeModList->list.array[arrIdx], sizeof(RICaction_RequiredToBeModified_ItemIEs_t));
6232          if(!actionToBeModList->list.array[arrIdx])
6233          {
6234             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6235             return RFAILED;
6236          }
6237          actionToBeMod = (RICaction_RequiredToBeModified_ItemIEs_t *)actionToBeModList->list.array[arrIdx];
6238
6239          actionToBeMod->id = ProtocolIE_IDE2_id_RICaction_RequiredToBeModified_Item;
6240          actionToBeMod->criticality = CriticalityE2_reject;
6241          actionToBeMod->value.present = \
6242             RICaction_RequiredToBeModified_ItemIEs__value_PR_RICaction_RequiredToBeModified_Item;
6243          actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricActionID = \
6244             ricSubscription->actionSequence[actionIdx].actionId;
6245          actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricTimeToWait = RICtimeToWait_w5ms;
6246
6247          arrIdx++;
6248       }
6249    }
6250
6251    return ROK;
6252 }
6253 #endif
6254
6255 /*******************************************************************
6256  *
6257  * @brief Fill Action required to be removed list
6258  *
6259  * @details
6260  *
6261  *    Function : FillActionReqdToBeRmvList
6262  *
6263  * Functionality: Fill Action required to be removed list
6264  *
6265  * @param  RIC Actions Required To Be Removed List to be filled
6266  *         Number of actions to be removed
6267  *         RIC Subscription DB
6268  * @return ROK     - success
6269  *         RFAILED - failure
6270  *
6271  ******************************************************************/
6272 uint8_t FillActionReqdToBeRmvList(RICactions_RequiredToBeRemoved_List_t *actionToBeRmvList, uint8_t numActionsRmv, \
6273    RicSubscription *ricSubscription)
6274 {
6275    uint8_t arrIdx = 0, actionIdx = 0;
6276    RICaction_RequiredToBeRemoved_ItemIEs_t *actionToBeRmv = NULL;
6277
6278    actionToBeRmvList->list.count = numActionsRmv;
6279    actionToBeRmvList->list.size = numActionsRmv * sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t *);
6280    DU_ALLOC(actionToBeRmvList->list.array, actionToBeRmvList->list.size);
6281    if(!actionToBeRmvList->list.array)
6282    {
6283       DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6284       return RFAILED;
6285    }
6286
6287    arrIdx = 0;
6288    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
6289    {
6290       if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL)
6291       {
6292          DU_ALLOC(actionToBeRmvList->list.array[arrIdx], sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t));
6293          if(!actionToBeRmvList->list.array[arrIdx])
6294          {
6295             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6296             return RFAILED;
6297          }
6298          actionToBeRmv = (RICaction_RequiredToBeRemoved_ItemIEs_t *)actionToBeRmvList->list.array[arrIdx];
6299
6300          actionToBeRmv->id = ProtocolIE_IDE2_id_RICaction_RequiredToBeRemoved_Item;
6301          actionToBeRmv->criticality = CriticalityE2_reject;
6302          actionToBeRmv->value.present = \
6303             RICaction_RequiredToBeRemoved_ItemIEs__value_PR_RICaction_RequiredToBeRemoved_Item;
6304          actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.ricActionID = \
6305             ricSubscription->actionSequence[actionIdx].actionId;
6306          fillE2Cause(&actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.cause, \
6307             ricSubscription->actionSequence[actionIdx].failureCause);
6308
6309          arrIdx++;
6310       }
6311    }
6312
6313    return ROK;
6314 }
6315
6316 /*******************************************************************
6317  *
6318  * @brief Fill RIC Subscription Modification Required IEs
6319  *
6320  * @details
6321  *
6322  *    Function : FillRicSubsModRequired
6323  *
6324  * Functionality: Fill RIC Subscription Modification Required IEs
6325  *
6326  * @param  RIC Subscription Modification Required IEs to be filled
6327  *         RIC Subscription DB
6328  * @return ROK     - success
6329  *         RFAILED - failure
6330  *
6331  ******************************************************************/
6332 uint8_t FillRicSubsModRequired(RICsubscriptionModificationRequired_t *ricSubsModReqd, RicSubscription *ricSubscription)
6333 {
6334    uint8_t ieIdx = 0, elementCnt=0, actionIdx = 0;
6335    uint8_t numActionsMod = 0, numActionsRmv = 0;
6336    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
6337    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
6338
6339 /* Unused in case of E2SM-KPM */
6340 #if 0
6341    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
6342 #endif
6343
6344    /* Count number of Actions to be modified or deleted */
6345    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
6346    {
6347       if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD)
6348          numActionsMod++;
6349       else if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL)
6350          numActionsRmv++;
6351    }
6352
6353    /* Count number of IEs to be added to messages */
6354    elementCnt = 2;
6355    if(numActionsMod)
6356       elementCnt++;
6357    if(numActionsRmv)
6358       elementCnt++;
6359
6360    ricSubsModReqd->protocolIEs.list.count = elementCnt;
6361    ricSubsModReqd->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationRequired_IEs_t *);
6362    DU_ALLOC(ricSubsModReqd->protocolIEs.list.array, ricSubsModReqd->protocolIEs.list.size);
6363    if(!ricSubsModReqd->protocolIEs.list.array)
6364    {
6365       DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6366       return RFAILED;
6367    }
6368
6369    for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
6370    {
6371       DU_ALLOC(ricSubsModReqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRequired_IEs_t));
6372       if(!ricSubsModReqd->protocolIEs.list.array[ieIdx])
6373       {
6374          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6375          return RFAILED;
6376       }
6377    }
6378
6379    /* RIC Request ID */
6380    ieIdx = 0;
6381    ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6382    ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICrequestID;
6383    ricSubsModReqdIe->criticality = CriticalityE2_reject;
6384    ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RICrequestID;
6385    ricSubsModReqdIe->value.choice.RICrequestID.ricRequestorID = ricSubscription->requestId.requestorId;
6386    ricSubsModReqdIe->value.choice.RICrequestID.ricInstanceID = ricSubscription->requestId.instanceId;
6387
6388    /* RAN Function ID */
6389    ieIdx++;
6390    ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6391    ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RANfunctionID;
6392    ricSubsModReqdIe->criticality = CriticalityE2_reject;
6393    ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RANfunctionID;
6394    ricSubsModReqdIe->value.choice.RANfunctionID = ricSubscription->ranFuncId;
6395
6396 /* A RIC Subscription includes RIC subsequent action only for RIC Insert service.
6397  * However, E2SM-KPM supports only RIC Report service.
6398  * Hence there is no subsequent action in RIC subscription that may require modification.
6399  * So commenting the action-modification IEs for the time being
6400  */
6401 #if 0
6402    /* RIC Actions Required to be Modified */
6403    if(numActionsMod)
6404    {
6405       ieIdx++;
6406       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6407       ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List;
6408       ricSubsModReqdIe->criticality = CriticalityE2_reject;
6409       ricSubsModReqdIe->value.present = \
6410          RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeModified_List;
6411       actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
6412
6413       if(FillActionReqdToBeModList(actionToBeModList, numActionsMod, ricSubscription) != ROK)
6414       {
6415          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill actions required to be modified list", __func__);
6416          return RFAILED;
6417       }
6418    }
6419 #endif
6420
6421    /* RIC Actions Required to be removed */
6422    if(numActionsRmv)
6423    {
6424       ieIdx++;
6425       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6426       ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List;
6427       ricSubsModReqdIe->criticality = CriticalityE2_reject;
6428       ricSubsModReqdIe->value.present = \
6429          RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeRemoved_List;
6430       actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
6431
6432       if(FillActionReqdToBeRmvList(actionToBeRmvList, numActionsRmv, ricSubscription) != ROK)
6433       {
6434          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill actions required to be removed list", __func__);
6435          return RFAILED;
6436       }
6437    }
6438
6439    return ROK;
6440 }
6441
6442 /*******************************************************************
6443  *
6444  * @brief Builds and Send RIC Subscription Modification Required
6445  *        message
6446  *
6447  * @details
6448  *
6449  *    Function : BuildAndSendRicSubsModRequired
6450  *
6451  * Functionality:  Builds and Send RIC Subscription Modification 
6452  *    Required message
6453  *
6454  * @param  RIC Subscription DB
6455  * @return ROK     - success
6456  *         RFAILED - failure
6457  *
6458  ******************************************************************/
6459 uint8_t BuildAndSendRicSubsModRequired(RicSubscription *ricSubscription)
6460 {
6461    uint8_t ret = RFAILED;
6462    E2AP_PDU_t        *e2apMsg = NULLP;
6463    RICsubscriptionModificationRequired_t  *ricSubsModReqd = NULLP;
6464    asn_enc_rval_t     encRetVal;       /* Encoder return value */
6465
6466    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Required \n");
6467    while(true)
6468    {
6469       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
6470       if(e2apMsg == NULLP)
6471       {
6472          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6473          break;
6474       }
6475
6476       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
6477       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
6478       if(e2apMsg->choice.initiatingMessage == NULLP)
6479       {
6480          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6481          break;
6482       }
6483       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
6484       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired;
6485       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionModificationRequired;
6486
6487       ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired;
6488
6489       if(FillRicSubsModRequired(ricSubsModReqd, ricSubscription) != ROK)
6490       {
6491          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Subscription Modification Required IEs", __func__);
6492          break;
6493       }
6494       
6495       /* Encode */
6496       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6497
6498       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6499       encBufSize = 0;
6500       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6501       if(encRetVal.encoded == ENCODE_FAIL)
6502       {
6503          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Modifiction Required structure (at %s)\n",\
6504                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6505          break;
6506       }
6507       else
6508       {
6509          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RIC Subscription Modification Required \n");
6510 #ifdef DEBUG_ASN_PRINT
6511          for(int i=0; i< encBufSize; i++)
6512          {
6513             printf("%x",encBuf[i]);
6514          }
6515 #endif
6516       }
6517       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
6518       {
6519          DU_LOG("\nERROR  -->  E2AP : Sending RIC Subscription Modification Required failed");
6520       }
6521
6522       ret = ROK;
6523       break;
6524    }
6525
6526    /* Free RIC Subscription modification required */
6527    FreeRicSubsModRequired(e2apMsg);
6528    return ret;
6529 }
6530
6531 /*******************************************************************
6532  *
6533  * @brief Free APER decoding of RIC Subscription Modification Confirm
6534  *
6535  * @details
6536  *
6537  *    Function : freeAperDecodingOfRicSubsModConfirm
6538  *
6539  * Functionality:  Free APER decoding of RIC Subscription 
6540  *   Modification Confirm
6541  *
6542  * @param  E2AP Message PDU
6543  * @return void
6544  *
6545  ******************************************************************/
6546 void freeAperDecodingOfRicSubsModConfirm(E2AP_PDU_t *e2apMsg)
6547 {
6548    uint8_t ieIdx = 0, arrIdx=0;
6549    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
6550    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
6551    RICactions_ConfirmedForModification_List_t *modCfmList = NULLP;
6552    RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP;
6553    RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP;
6554    RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP;
6555
6556    if(e2apMsg && e2apMsg->choice.successfulOutcome)
6557    {
6558       ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
6559       if(ricSubsModCfm->protocolIEs.list.array)
6560       {
6561          for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++)
6562          {
6563             if(ricSubsModCfm->protocolIEs.list.array[ieIdx])
6564             {
6565                ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
6566                switch(ricSubsModCfmIe->id)
6567                {
6568                   case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List:
6569                      {
6570                         modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List;
6571                         if(modCfmList->list.array)
6572                         {
6573                            for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
6574                            {
6575                               if(modCfmList->list.array[arrIdx])
6576                                  free(modCfmList->list.array[arrIdx]);
6577                            }
6578                            free(modCfmList->list.array);
6579                         }
6580                         break;
6581                      }
6582
6583                   case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List:
6584                      {
6585                         modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List;
6586                         if(modRefusedList->list.array)
6587                         {
6588                            for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
6589                            {
6590                               if(modRefusedList->list.array[arrIdx])
6591                                  free(modRefusedList->list.array[arrIdx]);
6592                            }
6593                            free(modRefusedList->list.array);
6594                         }
6595                         break;
6596                      }
6597
6598                   case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List:
6599                      {
6600                         rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List;
6601                         if(rmvCfmList->list.array)
6602                         {
6603                            for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
6604                            {
6605                               if(rmvCfmList->list.array[arrIdx])
6606                                  free(rmvCfmList->list.array[arrIdx]);
6607                            }
6608                            free(rmvCfmList->list.array);
6609                         }
6610                         break;
6611                      }
6612
6613                   case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List:
6614                      {
6615                         rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List;
6616                         if(rmvFailList->list.array)
6617                         {
6618                            for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
6619                            {
6620                               if(rmvFailList->list.array[arrIdx])
6621                                  free(rmvFailList->list.array[arrIdx]);
6622                            }
6623                            free(rmvFailList->list.array);
6624                         }
6625                         break;
6626                      }
6627
6628                   default:
6629                      break;
6630
6631                }
6632                free(ricSubsModCfmIe);
6633             }
6634          }
6635          free(ricSubsModCfm->protocolIEs.list.array);
6636       }
6637    }
6638 }
6639
6640 /*******************************************************************
6641  *
6642  * @brief Process RIC Subscription Modification Confirm Message
6643  *
6644  * @details
6645  *
6646  *    Function : procRicSubscriptionModificationConfirm
6647  *
6648  * Functionality:  Process RIC Subscription Modification Confirm
6649  *    Message received from RIC. 
6650  *
6651  * @param  E2AP Message PDU
6652  * @return void
6653  *
6654  ******************************************************************/
6655 void procRicSubscriptionModificationConfirm(E2AP_PDU_t *e2apMsg)
6656 {
6657    uint8_t actionId = 0, ieIdx = 0, arrIdx = 0;
6658    uint16_t ranFuncId = 0;
6659    bool procFailure = false;
6660    RicRequestId ricReqId;
6661    RanFunction *ranFuncDb = NULLP;
6662    CmLList *ricSubsNode = NULLP;
6663    RicSubscription *ricSubsDb = NULLP;
6664    ActionInfo *actionDb = NULLP;
6665
6666    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
6667    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
6668
6669 /* Not used in case of E2SM-KPM */
6670 #if 0
6671    RICactions_ConfirmedForModification_List_t *modCfmList = NULLP;
6672    RICaction_ConfirmedForModification_ItemIEs_t *modCfmListItem = NULLP;
6673
6674    RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP;
6675    RICaction_RefusedToBeModified_ItemIEs_t *modRefusedListItem = NULLP;
6676 #endif
6677
6678    RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP;
6679    RICaction_ConfirmedForRemoval_ItemIEs_t *rmvCfmListItem = NULLP;
6680
6681    RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP;
6682    RICaction_RefusedToBeRemoved_ItemIEs_t *rmvFailListItem = NULLP;
6683
6684    DU_LOG("\nINFO   -->  E2AP : %s: Received RIC Subscription Modification Confirm", __func__);
6685
6686    do{
6687       if(!e2apMsg)
6688       {
6689          DU_LOG("\nERROR  -->  E2AP : %s: E2AP Message is NULL", __func__);
6690          break;
6691       }
6692
6693       if(!e2apMsg->choice.successfulOutcome)
6694       {
6695          DU_LOG("\nERROR  -->  E2AP : %s: Successful Outcome in E2AP message is NULL", __func__);
6696          break;
6697       }
6698
6699       ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
6700       if(!ricSubsModCfm->protocolIEs.list.array)
6701       {
6702          DU_LOG("\nERROR  -->  E2AP : %s: Array conatining E2AP message IEs is null", __func__);
6703          break;
6704       }
6705
6706       for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++)
6707       {
6708          if(!ricSubsModCfm->protocolIEs.list.array[ieIdx])
6709          {
6710             DU_LOG("\nERROR  -->  E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx);
6711             break;
6712          }
6713
6714          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
6715          switch(ricSubsModCfmIe->id)
6716          {
6717             case ProtocolIE_IDE2_id_RICrequestID:
6718                {
6719                   memset(&ricReqId, 0, sizeof(RicRequestId));
6720                   ricReqId.requestorId = ricSubsModCfmIe->value.choice.RICrequestID.ricRequestorID;
6721                   ricReqId.instanceId = ricSubsModCfmIe->value.choice.RICrequestID.ricInstanceID;
6722                   break;
6723                }
6724
6725             case ProtocolIE_IDE2_id_RANfunctionID:
6726                {
6727                   ranFuncId = ricSubsModCfmIe->value.choice.RANfunctionID;
6728                   ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
6729                   if(!ranFuncDb)
6730                   {
6731                      DU_LOG("\nERROR  -->  E2AP : %s: RAN Function ID [%d] not found", __func__, ranFuncId);
6732                      procFailure = true;
6733                      break;
6734                   }
6735
6736                   ricSubsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode); 
6737                   if(!ricSubsDb)
6738                   {
6739                      DU_LOG("\nERROR  -->  E2AP : %s: RIC Subscription not found for Requestor_ID [%d] Instance_ID [%d]",\
6740                            __func__, ricReqId.requestorId, ricReqId.instanceId);
6741                      procFailure = true;
6742                      break;
6743                   }
6744
6745                   break;
6746                }
6747
6748 /* A RIC Subscription includes RIC subsequent action only for RIC Insert service. 
6749  * However, E2SM-KPM supports only RIC Report service. 
6750  * Hence there is no subsequent action in RIC subscription that may require modification. 
6751  * So commenting the action-modification IEs for the time being 
6752  */
6753 #if 0
6754             case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List:
6755                {
6756                   modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List;
6757                   for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
6758                   {
6759                      modCfmListItem = (RICaction_ConfirmedForModification_ItemIEs_t *)modCfmList->list.array[arrIdx];
6760                      actionId = modCfmListItem->value.choice.RICaction_ConfirmedForModification_Item.ricActionID;
6761
6762                      actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6763                      if(!actionDb)
6764                      {
6765                         DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6766                      }
6767                      else
6768                      {
6769                         actionDb->action = CONFIG_UNKNOWN;
6770                         /* Further handling can be added here in future once the
6771                          * use case of this procedure is identified */
6772                      }
6773                      actionDb = NULLP;
6774                   }
6775                   break;
6776                }
6777
6778             case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List:
6779                {
6780                   modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List;
6781                   for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
6782                   {
6783                     modRefusedListItem = (RICaction_RefusedToBeModified_ItemIEs_t *)modRefusedList->list.array[arrIdx];
6784                     actionId = modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.ricActionID;
6785                     actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6786                     if(!actionDb)
6787                     {
6788                        DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6789                     }
6790                     else
6791                     {
6792                        /* Spec doesnt mention if in case of failure, DU should retry for modify action 
6793                         * Hence, chaging the action from CONFIG_MOD to CONFIG_UNKNOWN
6794                         */
6795                         actionDb->action = CONFIG_UNKNOWN;
6796                     }
6797                     actionDb = NULLP;
6798                   }
6799                   break;
6800                }
6801 #endif
6802
6803             case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List:
6804                {
6805                   rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List;
6806                   for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
6807                   {
6808                      rmvCfmListItem = (RICaction_ConfirmedForRemoval_ItemIEs_t *)rmvCfmList->list.array[arrIdx];
6809                      actionId = rmvCfmListItem->value.choice.RICaction_ConfirmedForRemoval_Item.ricActionID;
6810                      actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6811                      if(!actionDb)
6812                      {
6813                         DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6814                      }
6815                      else
6816                      {
6817                         deleteActionSequence(actionDb);
6818                         actionDb =NULLP;
6819                         ricSubsDb->numOfActions--;
6820                         /* Further handling can include :
6821                          * Deletion of this action from all DU layers 
6822                          */
6823                      }
6824                      actionDb = NULLP;
6825                   }
6826                   break;
6827                }
6828
6829             case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List:
6830                {
6831                   rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List;
6832                   for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
6833                   {
6834                      rmvFailListItem = (RICaction_RefusedToBeRemoved_ItemIEs_t *)rmvFailList->list.array[arrIdx];
6835                      actionId = rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.ricActionID;
6836                      actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6837                      if(!actionDb)
6838                      {
6839                         DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6840                      }
6841                      else
6842                      {
6843                         actionDb->action = CONFIG_UNKNOWN;
6844                      }
6845                      actionDb = NULLP;
6846                   }
6847                   break;
6848                }
6849
6850             default:
6851                break;
6852          } /* End of switch for Protocol IE Id */
6853
6854          if(procFailure)
6855             break;
6856       } /* End of for loop for Protocol IE list */
6857
6858       break;
6859    }while(true);
6860
6861    freeAperDecodingOfRicSubsModConfirm(e2apMsg);
6862    return;
6863 }
6864
6865 /******************************************************************
6866 * @brief Deallocate the memory allocated for E2 Reset Response
6867 *
6868 * @details
6869 *
6870 *    Function : FreeE2ResetResponse
6871 *
6872 *    Functionality:
6873 *       - freeing the memory allocated for E2ResetResponse
6874 *
6875 * @params[in] E2AP_PDU_t *e2apMsg
6876 * @return ROK     - success
6877 *         RFAILED - failure
6878 *
6879 * ****************************************************************/
6880 void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg)
6881 {
6882    uint8_t ieIdx =0;
6883    ResetResponseE2_t *resetResponse;
6884
6885    if(e2apMsg != NULLP)
6886    {
6887       if(e2apMsg->choice.successfulOutcome != NULLP)
6888       {
6889          resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
6890          if(resetResponse->protocolIEs.list.array)
6891          {
6892             for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
6893             {
6894                if(resetResponse->protocolIEs.list.array[ieIdx])
6895                {
6896                   DU_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
6897                }
6898             }
6899             DU_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
6900          }
6901
6902          DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
6903       }
6904       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
6905    }
6906 }
6907
6908 /*******************************************************************
6909  *
6910  * @brief Buld and send the E2 Reset Response msg
6911  *
6912  * @details
6913  *
6914  *    Function : BuildAndSendE2ResetResponse
6915  *
6916  *    Functionality:
6917  *         - Buld and send the E2 Reset Response Message
6918  *
6919  * @params[in] Trans Id
6920  * @return ROK     - success
6921  *         RFAILED - failure
6922  *
6923  * ****************************************************************/
6924 uint8_t BuildAndSendResetResponse(uint8_t transId)
6925 {
6926    uint8_t           ieIdx = 0, elementCnt = 0;
6927    uint8_t           ret = RFAILED;
6928    E2AP_PDU_t        *e2apMsg = NULLP;
6929    ResetResponseE2_t *resetResponse;
6930    asn_enc_rval_t    encRetVal;       /* Encoder return value */
6931
6932    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
6933    do
6934    {
6935       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
6936       if(e2apMsg == NULLP)
6937       {
6938          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
6939          break;
6940       }
6941       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
6942
6943       DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
6944       if(e2apMsg->choice.successfulOutcome == NULLP)
6945       {
6946          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
6947          break;
6948       }
6949
6950       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
6951       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
6952       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
6953       resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
6954
6955       elementCnt = 1;
6956       resetResponse->protocolIEs.list.count = elementCnt;
6957       resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
6958       DU_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
6959       if(!resetResponse->protocolIEs.list.array)
6960       {
6961          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
6962          break;
6963       }
6964
6965       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
6966       {
6967          DU_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
6968          if(!resetResponse->protocolIEs.list.array[ieIdx])
6969          {
6970             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
6971             break;
6972          }
6973       }
6974       if(ieIdx < elementCnt)
6975          break;
6976
6977       ieIdx = 0;
6978       resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
6979       resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6980       resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
6981       resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
6982
6983       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6984
6985       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6986       encBufSize = 0;
6987       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6988       if(encRetVal.encoded == ENCODE_FAIL)
6989       {
6990          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
6991                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6992          break;
6993       }
6994       else
6995       {
6996          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
6997          for(int i=0; i< encBufSize; i++)
6998          {
6999             DU_LOG("%x",encBuf[i]);
7000          }
7001       }
7002
7003       /* Sending msg */
7004       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
7005       {
7006          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
7007          break;
7008       }
7009
7010       ret = ROK;
7011       break;
7012    }while(true);
7013
7014    FreeE2ResetResponse(e2apMsg);
7015    return ret;
7016 }
7017
7018 /******************************************************************
7019  *
7020  * @brief Deallocation of memory allocated by aper decoder for reset req
7021  *
7022  * @details
7023  *
7024  *    Function : freeAperDecodingOfE2ResetReq
7025  *
7026  *    Functionality: Deallocation of memory allocated by aper decoder for
7027  *    reset req
7028  *
7029  * @params[in] Pointer to resetReq
7030  * @return void
7031  *
7032  * ****************************************************************/
7033 void freeAperDecodingOfE2ResetReq(ResetRequestE2_t *resetReq)
7034 {
7035    uint8_t arrIdx=0;
7036
7037    if(resetReq)
7038    {
7039       if(resetReq->protocolIEs.list.array)
7040       {
7041          for(arrIdx=0; arrIdx<resetReq->protocolIEs.list.count; arrIdx++)
7042          {
7043             if(resetReq->protocolIEs.list.array[arrIdx])
7044             {
7045                free(resetReq->protocolIEs.list.array[arrIdx]);
7046             }
7047          }
7048          free(resetReq->protocolIEs.list.array);
7049       }
7050    }
7051 }
7052
7053 /*******************************************************************
7054  *
7055  * @brief Process reset req received from RIC
7056  *
7057  * @details
7058  *
7059  *    Function : procE2ResetRequest
7060  *
7061  * Functionality: Process reset req received from RIC
7062  *
7063  * @param  E2AP_PDU_t  *e2apMsg
7064  * @return void
7065  *
7066  ******************************************************************/
7067
7068 void procE2ResetRequest(E2AP_PDU_t  *e2apMsg)
7069 {
7070    uint16_t ranFuncIdx=0;
7071    uint8_t arrIdx =0, transId =0;
7072    ResetRequestE2_t *resetReq;
7073
7074    DU_LOG("\nINFO   -->  E2AP : E2 Reset request received");
7075    resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
7076
7077    for(arrIdx=0; arrIdx<resetReq->protocolIEs.list.count; arrIdx++)
7078    {
7079       switch(resetReq->protocolIEs.list.array[arrIdx]->id)
7080       {
7081          case ProtocolIE_IDE2_id_TransactionID:
7082             {
7083                transId = resetReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
7084                break;
7085             }
7086
7087          case ProtocolIE_IDE2_id_CauseE2:
7088             {
7089                for(ranFuncIdx=0; ranFuncIdx<MAX_RAN_FUNCTION; ranFuncIdx++)
7090                {
7091                   if(duCb.e2apDb.ranFunction[ranFuncIdx].id >0)
7092                   {
7093                      deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList));
7094                      memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo));
7095                   }
7096                }
7097                break;
7098             }
7099       }
7100    }
7101    if(BuildAndSendResetResponse(transId) != ROK)
7102    {
7103       DU_LOG("\nERROR  -->  E2AP : Failed to build and send reset response");
7104    }
7105    freeAperDecodingOfE2ResetReq(resetReq);
7106 }
7107
7108 /*******************************************************************
7109  *
7110  * @brief Free APER decoding of RIC Subscription Modification Refuse
7111  *
7112  * @details
7113  *
7114  *    Function : freeAperDecodingOfRicSubsModRefuse
7115  *
7116  * Functionality:  Free APER decoding of RIC Subscription 
7117  *   Modification Refuse
7118  *
7119  * @param  E2AP Message PDU
7120  * @return void
7121  *
7122  ******************************************************************/
7123 void freeAperDecodingOfRicSubsModRefuse(E2AP_PDU_t *e2apMsg)
7124 {
7125    uint8_t ieIdx =0;
7126    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
7127
7128    if(e2apMsg && e2apMsg->choice.unsuccessfulOutcome)
7129    {
7130       ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
7131       if(ricSubsModRefuse->protocolIEs.list.array)
7132       {
7133          for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++)
7134          {
7135             if(ricSubsModRefuse->protocolIEs.list.array[ieIdx])
7136                free(ricSubsModRefuse->protocolIEs.list.array[ieIdx]);
7137          }
7138          free(ricSubsModRefuse->protocolIEs.list.array);
7139       }
7140    }
7141 }
7142
7143 /*******************************************************************
7144  *
7145  * @brief Process RIC Subscription Modification Refuse Message
7146  *
7147  * @details
7148  *
7149  *    Function : procRicSubscriptionModificationRefuse
7150  *
7151  * Functionality:  Process RIC Subscription Modification Refuse
7152  *    Message received from RIC. 
7153  *
7154  * @param  E2AP Message PDU
7155  * @return void
7156  *
7157  ******************************************************************/
7158 void procRicSubscriptionModificationRefuse(E2AP_PDU_t *e2apMsg)
7159 {
7160    uint8_t ieIdx = 0;
7161    uint16_t ranFuncId = 0;
7162    RicRequestId ricReqId;
7163    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
7164    RICsubscriptionModificationRefuse_IEs_t *ricSubsModRefuseIe = NULLP;
7165    CauseE2_t *cause = NULLP;
7166
7167    DU_LOG("\nINFO   -->  E2AP : %s: Received RIC Subscription Modification Refuse", __func__);
7168
7169    do{
7170       if(!e2apMsg)
7171       {
7172          DU_LOG("\nERROR  -->  E2AP : %s: E2AP Message is NULL", __func__);
7173          break;
7174       }
7175
7176       if(!e2apMsg->choice.unsuccessfulOutcome)
7177       {
7178          DU_LOG("\nERROR  -->  E2AP : %s: Unsuccessful Outcome in E2AP message is NULL", __func__);
7179          break;
7180       }
7181
7182       ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
7183       if(!ricSubsModRefuse->protocolIEs.list.array)
7184       {
7185          DU_LOG("\nERROR  -->  E2AP : %s: Array conatining E2AP message IEs is null", __func__);
7186          break;
7187       }
7188
7189       for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++)
7190       {
7191          if(!ricSubsModRefuse->protocolIEs.list.array[ieIdx])
7192          {
7193             DU_LOG("\nERROR  -->  E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx);
7194             break;
7195          }
7196
7197          ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
7198          switch(ricSubsModRefuseIe->id)
7199          {
7200             case ProtocolIE_IDE2_id_RICrequestID:
7201                {
7202                   memset(&ricReqId, 0, sizeof(RicRequestId));
7203                   ricReqId.requestorId = ricSubsModRefuseIe->value.choice.RICrequestID.ricRequestorID;
7204                   ricReqId.instanceId = ricSubsModRefuseIe->value.choice.RICrequestID.ricInstanceID;
7205                   break;
7206                }
7207
7208             case ProtocolIE_IDE2_id_RANfunctionID:
7209                {
7210                   ranFuncId = ricSubsModRefuseIe->value.choice.RANfunctionID;
7211                   break;
7212                }
7213
7214             case ProtocolIE_IDE2_id_CauseE2:
7215                {
7216                   DU_LOG("\nDEBUG  -->  E2AP : %s: RIC subscriptiom modification refused for RIC_Requestor_ID [%d] \
7217                         RIC_Instance_ID [%d] RAN_Function_ID [%d] ", __func__, ricReqId.requestorId, \
7218                         ricReqId.instanceId, ranFuncId);
7219
7220                   cause = &ricSubsModRefuseIe->value.choice.CauseE2;
7221                   printE2ErrorCause(cause);
7222                }
7223
7224             default:
7225                break;
7226          } /* End of switch for Protocol IE Id */
7227       } /* End of for loop for Protocol IE list */
7228
7229       break;
7230    }while(true);
7231
7232    freeAperDecodingOfRicSubsModRefuse(e2apMsg);
7233    return;
7234 }
7235
7236 /*******************************************************************
7237  *
7238  * @brief Free RIC Subscription Delete Required Message
7239  *
7240  * @details
7241  *
7242  *    Function : FreeRicSubscriptionDeleteRequired
7243  *
7244  * Functionality:  Free RIC Subscription Delete Required
7245  *
7246  * @param  E2AP Message PDU
7247  * @return void
7248  *
7249  ******************************************************************/
7250 void FreeRicSubscriptionDeleteRequired(E2AP_PDU_t *e2apMsg, CmLListCp *ricSubsToBeDelList)
7251 {
7252    uint8_t ieIdx = 0, arrIdx = 0;
7253    RICsubscriptionDeleteRequired_t *ricSubsDelRqd = NULLP;
7254    RICsubscriptionDeleteRequired_IEs_t *ricSubsDelRqdIe = NULLP;
7255    RICsubscription_List_withCause_t *ricSubsList = NULLP;
7256    CmLList *subsNode = NULLP;
7257
7258    if(e2apMsg)
7259    {
7260       if(e2apMsg->choice.initiatingMessage)
7261       {
7262          ricSubsDelRqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired;
7263          if(ricSubsDelRqd->protocolIEs.list.array)
7264          {
7265             for(ieIdx = 0; ieIdx < ricSubsDelRqd->protocolIEs.list.count; ieIdx++)
7266             {
7267                if(ricSubsDelRqd->protocolIEs.list.array[ieIdx])
7268                {
7269                   ricSubsDelRqdIe = ricSubsDelRqd->protocolIEs.list.array[ieIdx];
7270                   switch(ricSubsDelRqdIe->id)
7271                   {
7272                      case ProtocolIE_IDE2_id_RICsubscriptionToBeRemoved:
7273                         {
7274                            ricSubsList = &ricSubsDelRqdIe->value.choice.RICsubscription_List_withCause;
7275                            if(ricSubsList->list.array)
7276                            {
7277                               for(arrIdx = 0; arrIdx < ricSubsList->list.count; arrIdx++)
7278                               {
7279                                  DU_FREE(ricSubsList->list.array[ieIdx], sizeof(RICsubscription_withCause_ItemIEs_t));
7280                               }
7281                               DU_FREE(ricSubsList->list.array, ricSubsList->list.size);
7282                            }
7283                            break;
7284                         }
7285                   }
7286                   DU_FREE(ricSubsDelRqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequired_IEs_t));
7287                }
7288             }
7289             DU_FREE(ricSubsDelRqd->protocolIEs.list.array, ricSubsDelRqd->protocolIEs.list.size);
7290          }
7291          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
7292       }
7293       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));;
7294    }
7295
7296    if(ricSubsToBeDelList)
7297    {
7298       CM_LLIST_FIRST_NODE(ricSubsToBeDelList, subsNode);
7299       while(subsNode)
7300       {
7301          cmLListDelFrm(ricSubsToBeDelList, subsNode);
7302          DU_FREE(subsNode, sizeof(CmLList));
7303          CM_LLIST_FIRST_NODE(ricSubsToBeDelList, subsNode);
7304       }
7305    }
7306 }
7307
7308 /*******************************************************************
7309  *
7310  * @brief Fill list of RIC subscriptions required to be deleted
7311  *    with the cause of deletion
7312  *
7313  * @details
7314  *
7315  *    Function : fillRicSubsListWithCause
7316  *
7317  * Functionality:  Fill list of RIC subscriptions required to be 
7318  *    deleted with the cause of deletion
7319  *
7320  * @param  E2AP Message PDU
7321  * @return void
7322  *
7323  ******************************************************************/
7324 uint8_t fillRicSubsListWithCause(RICsubscription_List_withCause_t *ricSubsList, CmLListCp ricSubsToBeDelList)
7325 {
7326    uint16_t ieIdx = 0;
7327    CmLList *subsNode = NULLP;
7328    RicSubscription *subsInfo = NULLP;
7329    RICsubscription_withCause_ItemIEs_t *subsItemIe = NULLP;
7330    RICsubscription_withCause_Item_t *subsItem = NULLP;
7331
7332    ricSubsList->list.count = ricSubsToBeDelList.count;
7333    ricSubsList->list.size = ricSubsList->list.count * sizeof(RICsubscription_withCause_ItemIEs_t *);
7334    DU_ALLOC(ricSubsList->list.array, ricSubsList->list.size);
7335    if(!ricSubsList->list.array)
7336    {
7337       DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7338       return RFAILED;
7339    }
7340
7341    CM_LLIST_FIRST_NODE(&ricSubsToBeDelList, subsNode);
7342    while(subsNode && (ieIdx < ricSubsList->list.count))
7343    {
7344       subsInfo = (RicSubscription *)subsNode->node;
7345       DU_ALLOC(ricSubsList->list.array[ieIdx], sizeof(RICsubscription_withCause_ItemIEs_t));
7346       if(!ricSubsList->list.array[ieIdx])
7347       {
7348          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7349          return RFAILED;
7350       }
7351
7352       subsItemIe = (RICsubscription_withCause_ItemIEs_t *)ricSubsList->list.array[ieIdx];
7353       subsItemIe->id = ProtocolIE_IDE2_id_RICsubscription_withCause_Item;
7354       subsItemIe->criticality = CriticalityE2_ignore;
7355       subsItemIe->value.present = RICsubscription_withCause_ItemIEs__value_PR_RICsubscription_withCause_Item;
7356
7357       subsItem = & subsItemIe->value.choice.RICsubscription_withCause_Item;
7358       subsItem->ricRequestID.ricRequestorID = subsInfo->requestId.requestorId;
7359       subsItem->ricRequestID.ricInstanceID = subsInfo->requestId.instanceId;
7360       subsItem->ranFunctionID = subsInfo->ranFuncId;
7361       fillE2Cause(&subsItem->cause, subsInfo->failureCause);
7362
7363       ieIdx++;
7364       subsNode = subsNode->next;
7365    }
7366
7367    return ROK;   
7368 }
7369
7370 /*******************************************************************
7371  *
7372  * @brief Builds and Send RIC Subscription delete required
7373  *
7374  * @details
7375  *
7376  *    Function : BuildAndSendRicSubscriptionDeleteRequired
7377  *
7378  * Functionality: Build and send RIC subscription delete required.
7379  *    There can be 2 approaches to trigger following. One of these
7380  *    approaches may/may not be implemented in future:
7381  *    1. It can be triggerred immediately when a RIC subscription's
7382  *       End Time has expired. In this case, only this subscription's
7383  *       info will be sent in this message.
7384  *       Since we have not yet added support to execute RIC 
7385  *       Subscription based on Start Time and End Timer, this message is 
7386  *       not triggered anywhere from DU APP yet.
7387  *    2. Another approach is to have a periodic timer to check subscription
7388  *       status running in background.
7389  *       When RIC Subscription End Time expires, this subscription is
7390  *       marked to be deleted. Later when this background timer expires,
7391  *       a RIC Subscription delete required is sent with all the 
7392  *       subscription's info which is marked to be deleted.
7393  *    The following function is implemented keeping in mind the second 
7394  *    approach.
7395  *
7396  * @params[in] 
7397  * @return ROK     - success
7398  *         RFAILED - failure
7399  *
7400  ******************************************************************/
7401 uint8_t BuildAndSendRicSubscriptionDeleteRequired()
7402 {
7403    uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED;
7404    E2AP_PDU_t         *e2apMsg = NULLP;
7405    RICsubscriptionDeleteRequired_t *ricSubsDelRqd = NULLP;
7406    RICsubscriptionDeleteRequired_IEs_t *ricSubsDelRqdIe = NULLP;
7407    asn_enc_rval_t     encRetVal;        /* Encoder return value */
7408    CmLListCp ricSubsToBeDelList;
7409
7410    while(true)
7411    {
7412       /* Check if there are any RIC subscriptions to be deleted */
7413       cmLListInit(&ricSubsToBeDelList);
7414       fetchRicSubsToBeDeleted(&ricSubsToBeDelList);
7415       if(ricSubsToBeDelList.count == 0)
7416       {
7417          DU_LOG("\nDEBUG  -->  E2AP : %s: No RIC subscriptions are required to be deleted", __func__);
7418          return ROK;
7419       }
7420
7421       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Delete Required Message\n");
7422
7423       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
7424       if(e2apMsg == NULLP)
7425       {
7426          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7427          break;
7428       }
7429
7430       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
7431       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
7432       if(e2apMsg->choice.initiatingMessage == NULLP)
7433       {
7434          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7435          break;
7436       }
7437       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionDeleteRequired;
7438       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
7439       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequired;
7440
7441       ricSubsDelRqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired;
7442       
7443       elementCnt = 1;
7444       ricSubsDelRqd->protocolIEs.list.count = elementCnt;
7445       ricSubsDelRqd->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionDeleteRequired_IEs_t *);
7446
7447       DU_ALLOC(ricSubsDelRqd->protocolIEs.list.array, ricSubsDelRqd->protocolIEs.list.size);
7448       if(ricSubsDelRqd->protocolIEs.list.array == NULLP)
7449       {
7450          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__);
7451          break;
7452       }
7453       
7454       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
7455       {
7456          DU_ALLOC(ricSubsDelRqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequired_IEs_t));
7457          if(ricSubsDelRqd->protocolIEs.list.array[ieIdx] == NULLP)
7458          {
7459             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for index [%d] at line %d", \
7460                __func__, ieIdx, __LINE__);
7461             break;
7462          }
7463       }
7464       if(ieIdx < elementCnt)
7465          break;
7466
7467       ieIdx = 0;
7468       ricSubsDelRqdIe = ricSubsDelRqd->protocolIEs.list.array[ieIdx];
7469       ricSubsDelRqdIe->id = ProtocolIE_IDE2_id_RICsubscriptionToBeRemoved;
7470       ricSubsDelRqdIe->criticality = CriticalityE2_ignore;
7471       ricSubsDelRqdIe->value.present = RICsubscriptionDeleteRequired_IEs__value_PR_RICsubscription_List_withCause;
7472       if(fillRicSubsListWithCause(&ricSubsDelRqdIe->value.choice.RICsubscription_List_withCause, ricSubsToBeDelList)\
7473             != ROK)
7474       {
7475          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Subscription list with cause", __func__);
7476          break;
7477       }
7478
7479       /* Prints the Msg formed */
7480       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
7481       memset(encBuf, 0, ENC_BUF_MAX_LEN);
7482       encBufSize = 0;
7483       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
7484       if(encRetVal.encoded == ENCODE_FAIL)
7485       {
7486          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Delete Required Message (at %s)\n",\
7487                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
7488          break;
7489       }
7490       else
7491       {
7492          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Delete Required Message \n");
7493 #ifdef DEBUG_ASN_PRINT
7494          for(int i=0; i< encBufSize; i++)
7495          {
7496             printf("%x",encBuf[i]);
7497          } 
7498 #endif
7499       }
7500
7501       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
7502       {
7503          DU_LOG("\nERROR   -->  E2AP : Failed to send RIC Susbcription Delete Required Message");      
7504
7505       }
7506       ret = ROK;
7507       break;
7508    }
7509
7510    FreeRicSubscriptionDeleteRequired(e2apMsg, &ricSubsToBeDelList);     
7511    return ret;
7512 }
7513
7514 /*******************************************************************
7515  *
7516  * @brief Free RIC Subscription Delete Request Message
7517  *
7518  * @details
7519  *
7520  *    Function : freeAperDecodingOfRicSubsDeleteReq
7521  *
7522  * Functionality:  Free RIC Subscription Delete Request
7523  *
7524  * @param  E2AP Message PDU
7525  * @return void
7526  *
7527  ******************************************************************/
7528 void freeAperDecodingOfRicSubsDeleteReq(E2AP_PDU_t *e2apMsg)
7529 {
7530    uint8_t ieIdx = 0;
7531    RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
7532
7533    if(e2apMsg)
7534    {
7535       if(e2apMsg->choice.initiatingMessage)
7536       {
7537          ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
7538          if(ricSubsDelReq->protocolIEs.list.array)
7539          {
7540             for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++)
7541             {
7542                if(ricSubsDelReq->protocolIEs.list.array[ieIdx])
7543                {
7544                   free(ricSubsDelReq->protocolIEs.list.array[ieIdx]);
7545                }
7546             }
7547             free(ricSubsDelReq->protocolIEs.list.array);
7548          }
7549       }
7550    }
7551 }
7552
7553 /*******************************************************************
7554  *
7555  * @brief Process RIC Subscription delete request
7556  *
7557  * @details
7558  *
7559  *    Function : procRicSubscriptionDeleteRequest
7560  *
7561  * Functionality: Process RIC subscription delete request.
7562  *    Fetch RAN Function and RIC subscription to be deleted. 
7563  *    Send statistics delete request to MAC for all action sequence
7564  *    within this RIC subscription.
7565  *
7566  * @params[in] E2AP PDU
7567  * @return void
7568  *
7569  ******************************************************************/
7570 void procRicSubscriptionDeleteRequest(E2AP_PDU_t *e2apMsg)
7571 {
7572    uint8_t ieIdx = 0;
7573    uint16_t ranFuncId = 0;
7574    bool procFailure = false;
7575    RicRequestId ricReqId;
7576    RanFunction *ranFuncDb = NULLP;
7577    CmLList *ricSubsNode = NULLP;
7578    RicSubscription *ricSubsDb = NULLP;
7579    RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
7580    RICsubscriptionDeleteRequest_IEs_t *ricSubsDelReqIe = NULLP;
7581
7582    DU_LOG("\nINFO   -->  E2AP : %s: Received RIC Subscription Delete Request", __func__);
7583
7584    do{
7585       if(!e2apMsg)
7586       {
7587          DU_LOG("\nERROR  -->  E2AP : %s: E2AP Message is NULL", __func__);
7588          break;
7589       }
7590
7591       if(!e2apMsg->choice.initiatingMessage)
7592       {
7593          DU_LOG("\nERROR  -->  E2AP : %s: Initiating Message in E2AP PDU is NULL", __func__);
7594          break;
7595       }
7596
7597       ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
7598       if(!ricSubsDelReq->protocolIEs.list.array)
7599       {
7600          DU_LOG("\nERROR  -->  E2AP : %s: Array conatining E2AP message IEs is null", __func__);
7601          break;
7602       }
7603
7604       for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++)
7605       {
7606          if(!ricSubsDelReq->protocolIEs.list.array[ieIdx])
7607          {
7608             DU_LOG("\nERROR  -->  E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx);
7609             break;
7610          }
7611
7612          ricSubsDelReqIe = ricSubsDelReq->protocolIEs.list.array[ieIdx];
7613          switch(ricSubsDelReqIe->id)
7614          {
7615             case ProtocolIE_IDE2_id_RICrequestID:
7616                {
7617                   memset(&ricReqId, 0, sizeof(RicRequestId));
7618                   ricReqId.requestorId = ricSubsDelReqIe->value.choice.RICrequestID.ricRequestorID;
7619                   ricReqId.instanceId = ricSubsDelReqIe->value.choice.RICrequestID.ricInstanceID;
7620                   break;
7621                }
7622
7623             case ProtocolIE_IDE2_id_RANfunctionID:
7624                {
7625                   ranFuncId = ricSubsDelReqIe->value.choice.RANfunctionID;
7626                   ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
7627                   if(!ranFuncDb)
7628                   {
7629                      DU_LOG("\nERROR  -->  E2AP : %s: RAN Function ID [%d] not found", __func__, ranFuncId);
7630                      procFailure = true;
7631                      break;
7632                   }
7633
7634                   ricSubsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode); 
7635                   if(!ricSubsDb)
7636                   {
7637                      DU_LOG("\nERROR  -->  E2AP : %s: RIC Subscription not found for Requestor_ID [%d] Instance_ID [%d]",\
7638                            __func__, ricReqId.requestorId, ricReqId.instanceId);
7639                      procFailure = true;
7640                      break;
7641                   }
7642
7643                   //TODO : Send statistics delete request to MAC 
7644                   break;
7645                }
7646
7647             default:
7648                break;
7649          } /* End of switch for Protocol IE Id */
7650          
7651          if(procFailure)
7652             break;
7653       } /* End of for loop for Protocol IE list */
7654
7655       break;
7656    }while(true);
7657
7658    freeAperDecodingOfRicSubsDeleteReq(e2apMsg);
7659    return;
7660 }
7661
7662 /*******************************************************************
7663  *
7664  * @brief Deallocate the memory allocated for E2 node configuration
7665  * update ack msg by aper decoder
7666  *
7667  * @details
7668  *
7669  *    Function : freeAperDecodingOfE2NodeConfigUpdateAck 
7670  *
7671  *    Functionality:
7672  *       - Deallocate the memory allocated for E2 node configuration
7673  * update ack msg by aper decoder
7674  *
7675  * @params[in] E2AP_PDU_t *e2apMsg
7676  * @return ROK     - success
7677  *         RFAILED - failure
7678  *
7679  * ****************************************************************/
7680
7681 void freeAperDecodingOfE2NodeConfigUpdateAck(E2nodeConfigurationUpdateAcknowledge_t *updateAckMsg)
7682 {
7683    uint8_t arrIdx =0, e2NodeConfigIdx=0;
7684    E2nodeComponentConfigUpdateAck_ItemIEs_t *updateAckItemIe=NULL;
7685    E2nodeComponentConfigUpdateAck_List_t *updateAckList=NULL;
7686    E2nodeComponentConfigRemovalAck_ItemIEs_t *removalAckItemIe=NULL;
7687    E2nodeComponentConfigRemovalAck_List_t *removalAckList=NULL;
7688    E2nodeComponentConfigAdditionAck_ItemIEs_t *additionAckItemIte=NULL;
7689    E2nodeComponentConfigAdditionAck_List_t *additionAckList=NULL;
7690
7691    E2nodeComponentInterfaceF1_t *f1InterfaceInfo=NULLP;
7692    if(updateAckMsg->protocolIEs.list.array != NULLP)
7693    {
7694       for(arrIdx = 0; arrIdx < updateAckMsg->protocolIEs.list.count; arrIdx++)
7695       {
7696          if(updateAckMsg->protocolIEs.list.array[arrIdx])
7697          {
7698             switch(updateAckMsg->protocolIEs.list.array[arrIdx]->id)
7699             {
7700                case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
7701                   {
7702                      additionAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
7703                      if(additionAckList->list.array)
7704                      {
7705                         for(e2NodeConfigIdx=0; e2NodeConfigIdx<additionAckList->list.count; e2NodeConfigIdx++)
7706                         {
7707                            additionAckItemIte = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) additionAckList->list.array[e2NodeConfigIdx];
7708                            if(additionAckItemIte)
7709                            {
7710                               switch(additionAckItemIte->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present)
7711                               {
7712                                  case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
7713                                     {
7714                                        f1InterfaceInfo = additionAckItemIte->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
7715                                        free(f1InterfaceInfo->gNB_DU_ID.buf);
7716                                        free(f1InterfaceInfo);
7717                                        break;
7718                                     }
7719                                  default:
7720                                     break;
7721                               }
7722                               free(additionAckItemIte);
7723                            }
7724                            free(additionAckList->list.array);
7725                         }
7726                         break;
7727                      }
7728                   }
7729                case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
7730                   {
7731                      updateAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List;
7732                      if(updateAckList->list.array)
7733                      {
7734                         for(e2NodeConfigIdx=0; e2NodeConfigIdx<updateAckList->list.count; e2NodeConfigIdx++)
7735                         {
7736                            updateAckItemIe = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) updateAckList->list.array[e2NodeConfigIdx];
7737                            if(updateAckItemIe)
7738                            {
7739                               switch(updateAckItemIe->value.choice.E2nodeComponentConfigUpdateAck_Item.e2nodeComponentID.present)
7740                               {
7741                                  case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
7742                                     {
7743                                        f1InterfaceInfo = updateAckItemIe->value.choice.E2nodeComponentConfigUpdateAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
7744                                        free(f1InterfaceInfo->gNB_DU_ID.buf);
7745                                        free(f1InterfaceInfo);
7746                                        break;
7747                                     }
7748                                  default:
7749                                     break;
7750                               }
7751                               free(updateAckItemIe);
7752                            }
7753                         }
7754                         free(updateAckList->list.array);
7755                      }
7756                      break;
7757                   }
7758                case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
7759                   {
7760                      removalAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List;
7761                      if(removalAckList->list.array)
7762                      {
7763                         for(e2NodeConfigIdx=0; e2NodeConfigIdx<removalAckList->list.count; e2NodeConfigIdx++)
7764                         {
7765                            removalAckItemIe = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) removalAckList->list.array[e2NodeConfigIdx];
7766                            if(removalAckItemIe)
7767                            {
7768                               switch(removalAckItemIe->value.choice.E2nodeComponentConfigRemovalAck_Item.e2nodeComponentID.present)
7769                               {
7770                                  case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
7771                                     {
7772                                        f1InterfaceInfo = removalAckItemIe->value.choice.E2nodeComponentConfigRemovalAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
7773                                        free(f1InterfaceInfo->gNB_DU_ID.buf);
7774                                        free(f1InterfaceInfo);
7775                                        break;
7776                                     }
7777                                  default:
7778                                     break;
7779                               }
7780                               free(removalAckItemIe);
7781                            }
7782                         }
7783                         free(removalAckList->list.array);
7784                      }
7785                      break;
7786                   }
7787             }
7788             free(updateAckMsg->protocolIEs.list.array[arrIdx]);
7789          }
7790       }
7791       free(updateAckMsg->protocolIEs.list.array);
7792    }
7793 }
7794
7795 /******************************************************************
7796  *
7797  * @brief Processes the E2 node config update ack msg
7798  *
7799  * @details
7800  *
7801  *    Function :procE2NodeConfigUpdateAck 
7802  *
7803  *    Functionality: Processes the E2 node config update ack msg
7804  *
7805  * @params[in] E2AP_PDU_t ASN decoded E2AP message
7806  * @return ROK     - success
7807  *         RFAILED - failure
7808  *
7809  * ****************************************************************/
7810
7811 void procE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg)
7812 {
7813    uint8_t arrIdx =0;
7814    uint16_t e2CfgIdx =0;
7815    E2nodeConfigurationUpdateAcknowledge_t *e2NodeConfigUpdateAck =NULLP;
7816    E2nodeComponentConfigUpdateAck_List_t *e2NodeConfigUpdateAckList=NULLP;
7817    E2nodeComponentConfigUpdateAck_ItemIEs_t *e2NodeUpdateAckItem=NULLP;
7818    E2nodeComponentConfigRemovalAck_List_t *e2NodeConfigRemovalAckList=NULLP;
7819    E2nodeComponentConfigRemovalAck_ItemIEs_t *e2NodeRemovalAckItem=NULLP;
7820    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList=NULLP;
7821    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAdditionAckItem=NULLP;
7822
7823    e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
7824
7825    if(e2NodeConfigUpdateAck->protocolIEs.list.array)
7826    {
7827        for(arrIdx =0; arrIdx<e2NodeConfigUpdateAck->protocolIEs.list.count; arrIdx++)
7828        {
7829             switch(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id)
7830             {
7831                case ProtocolIE_IDE2_id_TransactionID:
7832                {
7833                   break;
7834                }
7835                case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
7836                {
7837                   e2NodeConfigAdditionAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
7838                   if(e2NodeConfigAdditionAckList->list.array)
7839                   {
7840                      for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigAdditionAckList->list.count; e2CfgIdx++) 
7841                      {
7842                         e2NodeAdditionAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[e2CfgIdx];    
7843                         handleE2NodeConfigUpdateAckIes((PTR)&e2NodeAdditionAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item,\
7844                         ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck);
7845                      }
7846                   }
7847                   break;
7848                }
7849                case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
7850                {
7851                   e2NodeConfigUpdateAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List;
7852                   if(e2NodeConfigUpdateAckList->list.array)
7853                   {
7854                      for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigUpdateAckList->list.count; e2CfgIdx++) 
7855                      {
7856                         e2NodeUpdateAckItem = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) e2NodeConfigUpdateAckList->list.array[e2CfgIdx];    
7857                         handleE2NodeConfigUpdateAckIes((PTR)&e2NodeUpdateAckItem->value.choice.E2nodeComponentConfigUpdateAck_Item,\
7858                         ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck);
7859                      }
7860                   }
7861                   break;
7862                }
7863                case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
7864                {
7865                   e2NodeConfigRemovalAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List;
7866                   if(e2NodeConfigRemovalAckList->list.array)
7867                   {
7868                      for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigRemovalAckList->list.count; e2CfgIdx++) 
7869                      {
7870                         e2NodeRemovalAckItem = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) e2NodeConfigRemovalAckList->list.array[e2CfgIdx];    
7871                         handleE2NodeConfigUpdateAckIes((PTR)&e2NodeRemovalAckItem->value.choice.E2nodeComponentConfigRemovalAck_Item,\
7872                         ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck);
7873                      }
7874                   }
7875                   break;
7876                }
7877             }
7878        }
7879    }
7880
7881    freeAperDecodingOfE2NodeConfigUpdateAck(e2NodeConfigUpdateAck);
7882 }
7883
7884 /*******************************************************************
7885  *
7886  * @brief Deallocate the memory allocated for RemovalRequest msg
7887  *
7888  * @details
7889  *
7890  *    Function : FreeRemovalRequest
7891  *
7892  *    Functionality:
7893  *       - freeing the memory allocated for RemovalRequest
7894  *
7895  * @params[in] E2AP_PDU_t *e2apMsg
7896  * @return ROK     - success
7897  *         RFAILED - failure
7898  *
7899  * ****************************************************************/
7900 void FreeRemovalRequest(E2AP_PDU_t *e2apMsg)
7901 {
7902    uint8_t ieIdx =0;
7903    E2RemovalRequest_t  *removalReq = NULLP;
7904
7905    if(e2apMsg != NULLP)
7906    {
7907       if(e2apMsg->choice.initiatingMessage != NULLP)
7908       {
7909          removalReq = &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest;
7910          if(removalReq->protocolIEs.list.array)
7911          {
7912             for(ieIdx = 0; ieIdx < removalReq->protocolIEs.list.count; ieIdx++)
7913             {
7914                DU_FREE(removalReq->protocolIEs.list.array[ieIdx], sizeof(E2RemovalRequestIEs_t));
7915             }
7916             DU_FREE(removalReq->protocolIEs.list.array, removalReq->protocolIEs.list.size);
7917          }
7918          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
7919       }
7920       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
7921    }
7922 }
7923
7924 /*******************************************************************
7925  *
7926  * @brief Build and send the removal request msg
7927  *
7928  * @details
7929  *
7930  *    Function : BuildAndSendRemovalRequest
7931  *
7932  *    Functionality:
7933  *         - Buld and send the removal request msg to E2 node
7934  *
7935  * @return ROK     - success
7936  *         RFAILED - failure
7937  *
7938  * ****************************************************************/
7939
7940 uint8_t BuildAndSendRemovalRequest()
7941 {
7942    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
7943    uint8_t ret = RFAILED;
7944    E2AP_PDU_t        *e2apMsg = NULLP;
7945    E2RemovalRequest_t  *removalReq = NULLP;
7946    asn_enc_rval_t     encRetVal;       /* Encoder return value */
7947
7948    DU_LOG("\nINFO   -->  E2AP : Building Removal Request\n");
7949
7950    do
7951    {
7952       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
7953       if(e2apMsg == NULLP)
7954       {
7955          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
7956          break;
7957       }
7958
7959       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
7960       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
7961       if(e2apMsg->choice.initiatingMessage == NULLP)
7962       {
7963          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
7964          break;
7965       }
7966
7967       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2removal;
7968       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
7969       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2RemovalRequest;
7970       removalReq = &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest;
7971
7972       elementCnt = 1;
7973       removalReq->protocolIEs.list.count = elementCnt;
7974       removalReq->protocolIEs.list.size = elementCnt * sizeof(E2RemovalRequestIEs_t *);
7975
7976       DU_ALLOC(removalReq->protocolIEs.list.array, removalReq->protocolIEs.list.size);
7977       if(!removalReq->protocolIEs.list.array)
7978       {
7979          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
7980          break;
7981       }
7982
7983       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
7984       {
7985          DU_ALLOC(removalReq->protocolIEs.list.array[ieIdx], sizeof(E2RemovalRequestIEs_t));
7986          if(!removalReq->protocolIEs.list.array[ieIdx])
7987          {
7988             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
7989             break;
7990          }
7991       }
7992
7993       /* In case of failure */
7994       if(ieIdx < elementCnt)
7995          break;
7996
7997       ieIdx = 0;
7998       removalReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
7999       removalReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
8000       removalReq->protocolIEs.list.array[ieIdx]->value.present = E2RemovalRequestIEs__value_PR_TransactionID;
8001       transId = assignTransactionId();
8002       removalReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
8003
8004       /* Prints the Msg formed */
8005       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
8006
8007       memset(encBuf, 0, ENC_BUF_MAX_LEN);
8008       encBufSize = 0;
8009       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
8010             encBuf);
8011       if(encRetVal.encoded == ENCODE_FAIL)
8012       {
8013          DU_LOG("\nERROR  -->  E2AP : Could not encode removal request structure (at %s)\n",\
8014                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
8015          break;
8016       }
8017       else
8018       {
8019          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for removal request\n");
8020 #ifdef DEBUG_ASN_PRINT
8021          for(int i=0; i< encBufSize; i++)
8022          {
8023             printf("%x",encBuf[i]);
8024          }
8025 #endif
8026       }
8027       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
8028       {
8029          DU_LOG("\nERROR  -->  E2AP : Sending removal request failed");
8030          break;
8031       }
8032
8033
8034       ret = ROK;
8035       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
8036       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
8037       break;
8038    }while(true);
8039
8040    /* Free all memory */
8041    FreeRemovalRequest(e2apMsg);
8042    
8043    return ret;
8044 }
8045
8046 /******************************************************************
8047  *
8048  * @brief Deallocation of memory allocated by aper decoder
8049  *   for Removal failure
8050  *
8051  * @details
8052  *
8053  *    Function : freeAperDecodingOfE2RemovalFailure
8054  *
8055  *    Functionality: Deallocation of memory allocated by aper decoder
8056  * for Removal failure
8057  *
8058  * @params[in] Pointer to removalFailure
8059  * @return void
8060  *
8061  * ****************************************************************/
8062 void freeAperDecodingOfE2RemovalFailure(E2RemovalFailure_t *removalFailure)
8063 {
8064    uint8_t arrIdx=0;
8065
8066    if(removalFailure)
8067    {
8068       if(removalFailure->protocolIEs.list.array)
8069       {
8070          for(arrIdx=0; arrIdx<removalFailure->protocolIEs.list.count; arrIdx++)
8071          {
8072             if(removalFailure->protocolIEs.list.array[arrIdx])
8073             {
8074                free(removalFailure->protocolIEs.list.array[arrIdx]);
8075             }
8076          }
8077          free(removalFailure->protocolIEs.list.array);
8078       }
8079    }
8080 }
8081
8082 /******************************************************************
8083  *
8084  * @brief Processes the E2 removal failure msg
8085  *
8086  * @details
8087  *
8088  *    Function : procE2RemovalFailure
8089  *
8090  *    Functionality: Processes the E2 removal failure msg
8091  *
8092  * @params[in] 
8093  *       E2AP_PDU_t *e2apMsg
8094  *
8095  * @return void
8096  *
8097  * ****************************************************************/
8098 void ProcE2RemovalFailure(E2AP_PDU_t *e2apMsg) 
8099 {
8100    uint8_t ieIdx = 0, transId=0;
8101    CauseE2_t *cause = NULLP;
8102    E2RemovalFailure_t *e2RemovalFailure=NULLP;
8103
8104    e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure;
8105
8106    if(!e2RemovalFailure->protocolIEs.list.array)      
8107    {
8108       DU_LOG("\nERROR  -->  E2AP : e2RemovalFailure array pointer is null");
8109       return;
8110    }
8111    
8112    for(ieIdx=0; ieIdx < e2RemovalFailure->protocolIEs.list.count; ieIdx++)
8113    {
8114       if(e2RemovalFailure->protocolIEs.list.array[ieIdx])
8115       {
8116          switch(e2RemovalFailure->protocolIEs.list.array[ieIdx]->id)
8117          {
8118             case ProtocolIE_IDE2_id_TransactionID:
8119                {
8120                   transId = e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
8121                   if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
8122                         (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
8123                   {
8124                      memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
8125                   }
8126                   else
8127                   {
8128                      DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
8129                   }
8130                   break;
8131                }
8132             case ProtocolIE_IDE2_id_CauseE2:
8133                {
8134                    cause = &e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2;
8135                    printE2ErrorCause(cause);
8136                    break; 
8137                }
8138             default:
8139                {
8140                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", e2RemovalFailure->protocolIEs.list.array[ieIdx]->id);
8141                   break;
8142                }
8143          }
8144       }
8145    }
8146    freeAperDecodingOfE2RemovalFailure(e2RemovalFailure);
8147 }
8148
8149  /******************************************************************
8150   *
8151   * @brief Deallocation of memory allocated by aper decoder
8152   *   for Removal failure
8153   *
8154   * @details
8155   *
8156   *    Function : freeAperDecodingOfE2RemovalResponse
8157   *
8158   *    Functionality: Deallocation of memory allocated by aper decoder
8159   * for Removal failure
8160   *
8161   * @params[in] Pointer to removalResponse
8162   * @return void
8163   *
8164   * ****************************************************************/
8165  void freeAperDecodingOfE2RemovalResponse(E2RemovalResponse_t *removalResponse)
8166  {
8167     uint8_t arrIdx=0;
8168
8169     if(removalResponse)
8170     {
8171        if(removalResponse->protocolIEs.list.array)
8172        {
8173           for(arrIdx=0; arrIdx<removalResponse->protocolIEs.list.count; arrIdx++)
8174           {
8175              if(removalResponse->protocolIEs.list.array[arrIdx])
8176              {
8177                 free(removalResponse->protocolIEs.list.array[arrIdx]);
8178              }
8179           }
8180           free(removalResponse->protocolIEs.list.array);
8181        }
8182     }
8183  }
8184
8185 /*******************************************************************
8186  *
8187  * @brief process the E2 Removal Response
8188  *
8189  * @details
8190  *
8191  *    Function : ProcE2RemovalResponse 
8192  *
8193  * Functionality: Process E2 Removal Response 
8194  *
8195  * @params[in] 
8196  *      E2AP_PDU_t *e2apMsg
8197  * @return void
8198  *
8199  ******************************************************************/
8200
8201 void ProcE2RemovalResponse(E2AP_PDU_t *e2apMsg)
8202 {
8203    uint8_t ieIdx = 0, transId=0;
8204    E2RemovalResponse_t *removalRsp = NULLP;
8205    
8206    removalRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse;
8207
8208    if(!removalRsp->protocolIEs.list.array)      
8209    {
8210       DU_LOG("\nERROR  -->  E2AP : removalRsp array pointer is null");
8211       return;
8212    }
8213
8214    for(ieIdx=0; ieIdx < removalRsp->protocolIEs.list.count; ieIdx++)
8215    {
8216       if(removalRsp->protocolIEs.list.array[ieIdx])
8217       {
8218          switch(removalRsp->protocolIEs.list.array[ieIdx]->id)
8219          {
8220             case ProtocolIE_IDE2_id_TransactionID:
8221                {
8222                   transId = removalRsp->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
8223                   if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
8224                         (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
8225                   {
8226                      removeE2NodeInformation();
8227                      memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
8228                   }
8229                   else
8230                   {
8231                      DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
8232                   }
8233                   break;
8234                }
8235             default:
8236                {
8237                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", removalRsp->protocolIEs.list.array[ieIdx]->id);
8238                   break;
8239                }
8240          }
8241       }
8242    }
8243    
8244    freeAperDecodingOfE2RemovalResponse(removalRsp);
8245 }
8246
8247 /*******************************************************************
8248  *
8249  * @brief Handles received E2AP message and sends back response  
8250  *
8251  * @details
8252  *
8253  *    Function : E2APMsgHdlr
8254  *
8255  *    Functionality:
8256  *         - Decodes received E2AP control message
8257  *         - Prepares response message, encodes and sends to SCTP
8258  *
8259  * @params[in] 
8260  * @return ROK     - success
8261  *         RFAILED - failure
8262  *
8263  * ****************************************************************/
8264 void E2APMsgHdlr(Buffer *mBuf)
8265 {
8266    int i =0;
8267    char *recvBuf = NULLP;
8268    MsgLen copyCnt =0;
8269    MsgLen recvBufLen =0;
8270    E2AP_PDU_t *e2apMsg = NULLP;
8271    asn_dec_rval_t rval ={0}; /* Decoder return value */
8272    E2AP_PDU_t e2apasnmsg={0} ;
8273
8274    DU_LOG("\nDEBUG   -->  E2AP : Received E2AP message buffer");
8275    ODU_PRINT_MSG(mBuf, 0,0);
8276
8277    /* Copy mBuf into char array to decode it */
8278    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
8279    DU_ALLOC(recvBuf, (Size)recvBufLen);
8280
8281    if(recvBuf == NULLP)
8282    {
8283       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
8284       return;
8285    }
8286    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
8287    {
8288       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
8289       return;
8290    }
8291
8292 #ifdef DEBUG_ASN_PRINT
8293    printf("\nDEBUG   -->  E2AP : Received flat buffer to be decoded : ");
8294    for(i=0; i< recvBufLen; i++)
8295    {
8296       printf("%x",recvBuf[i]);
8297    }
8298 #endif
8299
8300    /* Decoding flat buffer into E2AP messsage */
8301    e2apMsg = &e2apasnmsg;
8302    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
8303
8304    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
8305    DU_FREE(recvBuf, (Size)recvBufLen);
8306
8307    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
8308    {
8309       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
8310       return;
8311    }
8312    printf("\n");
8313    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
8314
8315    switch(e2apMsg->present)
8316    {
8317       case E2AP_PDU_PR_unsuccessfulOutcome:
8318          {
8319             switch(e2apMsg->choice.unsuccessfulOutcome->value.present)
8320             {
8321                case UnsuccessfulOutcomeE2__value_PR_E2setupFailure:
8322                   {
8323                      procE2SetupFailure(e2apMsg);
8324                      break;
8325                   }
8326                case UnsuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateFailure:
8327                   {
8328                      procE2NodeConfigUpdateFailure(e2apMsg);
8329                      break;
8330                   }
8331                case UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure:
8332                   {
8333                      procRicServiceUpdateFailure(e2apMsg);
8334                      break;
8335                   }
8336                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionModificationRefuse:
8337                   {
8338                      procRicSubscriptionModificationRefuse(e2apMsg);
8339                      break;
8340                   }
8341                case UnsuccessfulOutcomeE2__value_PR_E2RemovalFailure:
8342                   {
8343                      ProcE2RemovalFailure(e2apMsg);
8344                      break;
8345                   }
8346                default:
8347                   {
8348                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome  [%d]",\
8349                            e2apMsg->choice.unsuccessfulOutcome->value.present);
8350                      return;
8351                   }
8352             }
8353             free(e2apMsg->choice.unsuccessfulOutcome);
8354             break;
8355          }
8356       case E2AP_PDU_PR_successfulOutcome:
8357          {
8358             switch(e2apMsg->choice.successfulOutcome->value.present)
8359             {
8360                case SuccessfulOutcomeE2__value_PR_E2setupResponse:
8361                   {
8362                      if(!duCb.e2Status)
8363                      {
8364                         procE2SetupRsp(e2apMsg);
8365                      }
8366                      break;
8367                   }
8368                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
8369                   {
8370                      procResetResponse(e2apMsg);
8371                      break;
8372                   }
8373                case SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge:
8374                   {
8375                      procRicServiceUpdateAck(e2apMsg);
8376                      break;
8377                   }
8378                case SuccessfulOutcomeE2__value_PR_RICsubscriptionModificationConfirm:
8379                   {
8380                      procRicSubscriptionModificationConfirm(e2apMsg);
8381                      break;
8382                   }
8383                case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge:
8384                   {
8385                      procE2NodeConfigUpdateAck(e2apMsg);
8386                      break;
8387                   }
8388                case SuccessfulOutcomeE2__value_PR_E2RemovalResponse:
8389                   {
8390                      ProcE2RemovalResponse(e2apMsg);
8391                      break;
8392                   }
8393                default:
8394                   {
8395                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome  [%d]",\
8396                            e2apMsg->choice.successfulOutcome->value.present);
8397                      return;
8398                   }
8399             }/* End of switch(successfulOutcome) */
8400             free(e2apMsg->choice.successfulOutcome);
8401             break;
8402          }
8403
8404       case E2AP_PDU_PR_initiatingMessage:
8405          {
8406             switch(e2apMsg->choice.initiatingMessage->value.present)
8407             {
8408                case InitiatingMessageE2__value_PR_RICsubscriptionRequest: 
8409                   {
8410                      procRicSubscriptionRequest(e2apMsg);
8411                      break;
8412                   }
8413                case InitiatingMessageE2__value_PR_RICserviceQuery:
8414                   {
8415                      procRicServiceQuery(e2apMsg);
8416                      break;
8417                   }
8418                case InitiatingMessageE2__value_PR_ErrorIndicationE2:
8419                   {
8420                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
8421                      break;
8422                   }
8423                case InitiatingMessageE2__value_PR_ResetRequestE2:
8424                   {
8425                      DU_LOG("\nINFO  -->  E2AP : Reset request received");
8426                      procE2ResetRequest(e2apMsg);
8427                      break;
8428                   }
8429                case InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequest:
8430                   {
8431                      DU_LOG("\nINFO  -->  E2AP : RIC Subscription Delete Request received");
8432                      procRicSubscriptionDeleteRequest(e2apMsg);
8433                      break;
8434                   }
8435                case InitiatingMessageE2__value_PR_E2RemovalRequest:
8436                   {
8437                      DU_LOG("\nINFO  -->  E2AP : E2 Removal request received");
8438                      procE2RemovalRequest(e2apMsg);
8439                      break;
8440                   }
8441                default:
8442                   {
8443                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\
8444                            e2apMsg->choice.initiatingMessage->value.present);
8445                      return;
8446                   }
8447             }/* End of switch(initiatingMessage) */
8448             free(e2apMsg->choice.initiatingMessage);
8449             break;
8450          }
8451       default:
8452          {
8453             DU_LOG("\nERROR  -->  E2AP : Invalid type of e2apMsg->present [%d]",e2apMsg->present);
8454             return;
8455          }
8456          free(e2apMsg);
8457
8458    }/* End of switch(e2apMsg->present) */
8459
8460 } /* End of E2APMsgHdlr */
8461
8462 /**********************************************************************
8463   End of file
8464  **********************************************************************/