[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(uint8_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(uint8_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    return ret;
486 }
487
488 /******************************************************************
489  *
490  * @brief Deallocation of memory allocated by aper decoder for Removal req
491  *
492  * @details
493  *
494  *    Function : freeAperDecodingOfE2RemovalReq
495  *
496  *    Functionality: Deallocation of memory allocated by aper decoder for
497  *    Removal req
498  *
499  * @params[in] Pointer to removalReq
500  * @return void
501  *
502  * ****************************************************************/
503 void freeAperDecodingOfE2RemovalReq(E2RemovalRequest_t *removalReq)
504 {
505    uint8_t arrIdx=0;
506
507    if(removalReq)
508    {
509       if(removalReq->protocolIEs.list.array)
510       {
511          for(arrIdx=0; arrIdx<removalReq->protocolIEs.list.count; arrIdx++)
512          {
513             if(removalReq->protocolIEs.list.array[arrIdx])
514             {
515                free(removalReq->protocolIEs.list.array[arrIdx]);
516             }
517          }
518          free(removalReq->protocolIEs.list.array);
519       }
520    }
521 }
522
523 /*******************************************************************
524  *
525  * @brief Process Removal req received from RIC
526  *
527  * @details
528  *
529  *    Function : procE2RemovalRequest
530  *
531  * Functionality: Process Removal req received from RIC
532  *
533  * @param  E2AP_PDU_t  *e2apMsg
534  * @return void
535  *
536  ******************************************************************/
537
538 void procE2RemovalRequest(E2AP_PDU_t  *e2apMsg)
539 {
540    uint8_t arrIdx =0, transId =0, count =0;
541    E2FailureCause failureCause;
542    E2RemovalRequest_t *removalReq=NULLP;
543
544    DU_LOG("\nINFO   -->  E2AP : E2 Removal request received");
545    removalReq = &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest;
546    
547    count =removalReq->protocolIEs.list.count;
548    for(arrIdx=0; arrIdx<removalReq->protocolIEs.list.count; arrIdx++)
549    {
550       switch(removalReq->protocolIEs.list.array[arrIdx]->id)
551       {
552          case ProtocolIE_IDE2_id_TransactionID:
553             {
554                transId = removalReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
555                break;
556             }
557          default:
558             {
559                DU_LOG("\nERROR  -->  E2AP : Invalid IE recevied [%d]", transId);
560                break;
561             }
562       }
563    }
564    
565    if(transId>=0 && transId<=255)
566    {
567       if(BuildAndSendRemovalResponse(transId) != ROK)
568       {
569          DU_LOG("\nERROR  -->  E2AP : Failed to build and send Removal response");
570       }
571    }
572    else
573    {
574       failureCause.causeType = E2_PROTOCOL;
575       failureCause.cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE;
576
577       if(BuildAndSendRemovalFailure(transId, failureCause) != ROK)
578       {
579          DU_LOG("\nERROR  -->  E2AP : Failed to build and send Removal response");
580       }
581    }
582    freeAperDecodingOfE2RemovalReq(removalReq);
583 }
584
585 /*******************************************************************
586  *
587  * @brief Free the ErrorIndication Message
588  *
589  * @details
590  *
591  *    Function : FreeRicIndication
592  *
593  * Functionality: Free the ErrorIndication Message
594  *
595  * @params[in] 
596  *    E2AP_PDU is to freed
597  * @return void
598  *
599  ******************************************************************/
600 void FreeErrorIndication(E2AP_PDU_t  *e2apMsg) 
601 {
602    uint8_t arrIdx = 0;
603    ErrorIndicationE2_t *errorIndicationMsg= NULLP;
604
605    if(e2apMsg != NULLP)
606    {
607       if(e2apMsg->choice.initiatingMessage != NULLP)
608       {
609          errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
610          if(errorIndicationMsg!= NULLP)
611          {
612             if(errorIndicationMsg->protocolIEs.list.array != NULLP)
613             {
614                for(arrIdx=0; arrIdx<errorIndicationMsg->protocolIEs.list.count; arrIdx++)
615                {
616                   DU_FREE(errorIndicationMsg->protocolIEs.list.array[arrIdx],sizeof(ErrorIndicationE2_t));
617                }
618                DU_FREE(errorIndicationMsg->protocolIEs.list.array,errorIndicationMsg->protocolIEs.list.size);
619             }
620          }
621          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
622       }
623       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
624    }
625 }
626
627 /*******************************************************************
628  *
629  * @brief Builds and Send the ErrorIndication Message
630  *
631  * @details
632  *
633  *    Function : BuildAndSendErrorIndication
634  *
635  * Functionality:Fills the ErrorIndication Message
636  *
637  * @params[in] 
638  *    Trans id
639  *    Ric req id
640  *    Ran function id
641  *    Cause of failure
642  * @return ROK     - success
643  *         RFAILED - failure
644  *
645  ******************************************************************/
646
647 uint8_t BuildAndSendErrorIndication(int8_t transId, RicRequestId requestId, uint16_t ranFuncId,  E2FailureCause failureCause)
648 {
649    uint8_t elementCnt =0, arrIdx=0, ret = RFAILED;
650    E2AP_PDU_t         *e2apMsg = NULLP;
651    ErrorIndicationE2_t *errorIndicationMsg=NULLP;
652    asn_enc_rval_t     encRetVal;        /* Encoder return value */
653
654    while(true)
655    {
656       DU_LOG("\nINFO   -->  E2AP : Building Error Indication Message\n");
657
658       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
659       if(e2apMsg == NULLP)
660       {
661          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
662          break;
663       }
664
665       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
666       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
667       if(e2apMsg->choice.initiatingMessage == NULLP)
668       {
669          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
670          break;
671       }
672       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_ErrorIndicationE2;
673       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
674       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ErrorIndicationE2;
675
676       errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
677       
678       /* Element count is 2 for TransactionID/RICrequestID and Cause.
679        * If the RAN function id is present, the count will be increased.*/
680       elementCnt = 2;
681       if(ranFuncId>0)
682       {
683          elementCnt++;
684       }
685       
686       errorIndicationMsg->protocolIEs.list.count = elementCnt;
687       errorIndicationMsg->protocolIEs.list.size = elementCnt * sizeof(ErrorIndicationE2_IEs_t*);
688
689       /* Initialize the E2Setup members */
690       DU_ALLOC(errorIndicationMsg->protocolIEs.list.array, errorIndicationMsg->protocolIEs.list.size);
691       if(errorIndicationMsg->protocolIEs.list.array == NULLP)
692       {
693          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements in %s at line %d",__func__, __LINE__);
694          break;
695       }
696       
697       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
698       {
699          DU_ALLOC(errorIndicationMsg->protocolIEs.list.array[arrIdx], sizeof(ErrorIndicationE2_IEs_t));
700          if(errorIndicationMsg->protocolIEs.list.array[arrIdx] == NULLP)
701          {
702             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array [%d] elements in %s at line %d", arrIdx, __func__, __LINE__);
703             break;
704          }
705       }
706       if(arrIdx < elementCnt)
707          break;
708
709       arrIdx = 0;
710
711       if(transId >=0 && transId<=255)
712       {
713          /* TransactionID */
714          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
715          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
716          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_TransactionID;
717          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
718       }
719       else
720       {
721          /* RICrequestID */
722          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RICrequestID;
723          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
724          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RICrequestID;
725          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricRequestorID = requestId.requestorId;
726          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricInstanceID = requestId.instanceId;
727       }
728       
729       if(ranFuncId>0)
730       {
731          /* RAN Function ID */
732          arrIdx++;
733          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionID;
734          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
735          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RANfunctionID;
736          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionID = ranFuncId;
737       }
738
739       /* Cause */
740       arrIdx++;
741       errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
742       errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
743       errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2;
744       fillE2Cause(&errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, failureCause);
745
746       /* Prints the Msg formed */
747       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
748       memset(encBuf, 0, ENC_BUF_MAX_LEN);
749       encBufSize = 0;
750       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
751             encBuf);
752       if(encRetVal.encoded == ENCODE_FAIL)
753       {
754          DU_LOG("\nERROR  -->  E2AP : Could not encode Error Indication Message (at %s)\n",\
755                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
756          break;
757       }
758       else
759       {
760          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for Error Indication Message \n");
761 #ifdef DEBUG_ASN_PRINT
762          for(int i=0; i< encBufSize; i++)
763          {
764             printf("%x",encBuf[i]);
765          } 
766 #endif
767       }
768
769       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
770       {
771          DU_LOG("\nINFO   -->  E2AP : Sending Error Indication Message");      
772
773       }
774       ret = ROK;
775       break;
776    }
777    FreeErrorIndication(e2apMsg);        
778    return ret;
779 }
780
781 /******************************************************************
782  *
783  * @brief Deallocation of memory allocated by aper decoder for e2 
784  * Config Update Failure
785  *
786  * @details
787  *
788  *    Function : freeAperDecodingOfE2Node Config UpdateFailure
789  *
790  *    Functionality: Deallocation of memory allocated by  aper decoder 
791  *    for e2 Config Update Failure
792  *
793  * @params[in] E2nodeConfigurationUpdateFailure_t to be deallocated 
794  * @return void
795  *
796  * ****************************************************************/
797
798 void freeAperDecodingOfE2NodeConfigUpdateFailure(E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdFail)
799 {
800    uint8_t arrIdx =0;
801
802    if(e2NodeCfgUpdFail)
803    {
804       if(e2NodeCfgUpdFail->protocolIEs.list.array)
805       {
806          for(arrIdx=0; arrIdx<e2NodeCfgUpdFail->protocolIEs.list.count; arrIdx++)
807          {
808             if(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx])
809             {
810                free(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]);
811             }
812          }
813          free(e2NodeCfgUpdFail->protocolIEs.list.array);
814       }
815    }
816 }
817
818 /******************************************************************
819  *
820  * @brief Processes E2 Node Config Update Failure sent by RIC
821  *
822  * @details
823  *
824  *    Function : procE2NodeConfigUpdateFailure
825  *
826  *    Functionality: Processes E2 Node Config Update failure sent by RIC
827  *
828  * @params[in] E2AP_PDU_t ASN decoded E2AP message
829  * @return ROK     - success
830  *         RFAILED - failure
831  *
832  * ****************************************************************/
833
834 void procE2NodeConfigUpdateFailure(E2AP_PDU_t *e2apMsg)
835 {
836    uint8_t arrIdx =0, transId =0, timerValue=0;
837    E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdFail=NULL;
838
839    DU_LOG("\nINFO   -->  E2AP : E2 Node Config Update failure received");
840    e2NodeCfgUpdFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2nodeConfigurationUpdateFailure;
841
842    for(arrIdx=0; arrIdx<e2NodeCfgUpdFail->protocolIEs.list.count; arrIdx++)
843    {
844       switch(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]->id)
845       {
846          case ProtocolIE_IDE2_id_TransactionID:
847             {
848                transId = e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
849                if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
850                      (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
851                {
852                   memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
853                }
854                else
855                {
856                   DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
857                }
858                break;
859          }
860          case ProtocolIE_IDE2_id_TimeToWaitE2:
861             {
862                timerValue = convertE2WaitTimerEnumToValue(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
863                if((duChkTmr((PTR)&(duCb.e2apDb), EVENT_E2_NODE_CONFIG_UPDATE_TMR)) == FALSE)
864                {
865                   duStartTmr((PTR)&(duCb.e2apDb), EVENT_E2_NODE_CONFIG_UPDATE_TMR, timerValue);
866                }
867                else
868                {
869                   DU_LOG("\nERROR   -->  E2AP : EVENT_E2_NODE_CONFIG_UPDATE_TMR timer is already running");
870                }
871                break;
872             }
873       }
874    }
875
876    freeAperDecodingOfE2NodeConfigUpdateFailure(e2NodeCfgUpdFail);
877 }
878
879 /*******************************************************************
880  *
881  * @brief Builds Global gNodeB Params
882  *
883  * @details
884  *
885  *    Function : BuildGlobalgNBId
886  *
887  *    Functionality: Building the Plmn and gNB id
888  *
889  * @params[in] GlobalE2node_gNB_ID_t *gNbId
890  * @return ROK     - success
891  *         RFAILED - failure
892  *
893  ******************************************************************/
894
895 uint8_t BuildGlobalgNBId(GlobalE2node_gNB_ID_t *gNbId)
896 {
897    uint8_t unused = 0;
898    uint8_t byteSize = 4;
899    uint8_t gnbId = duCb.gnbId;
900    uint8_t ret = ROK;
901
902    /* fill Global gNB ID Id */
903    gNbId->global_gNB_ID.plmn_id.size = 3 * sizeof(uint8_t);
904    gNbId->global_gNB_ID.plmn_id.buf = NULLP;
905    DU_ALLOC(gNbId->global_gNB_ID.plmn_id.buf , gNbId->global_gNB_ID.plmn_id.size);
906    if(gNbId->global_gNB_ID.plmn_id.buf == NULLP)
907    {
908       DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for Plmn buffer");
909       ret = RFAILED;
910    }
911    else
912    {
913       buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
914             gNbId->global_gNB_ID.plmn_id.buf);
915       gNbId->global_gNB_ID.gnb_id.present = GNB_ID_Choice_PR_gnb_ID;
916       /* Allocate Buffer size */
917       gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size = byteSize * sizeof(uint8_t);
918       gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf = NULLP;
919       DU_ALLOC(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf, \
920             gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size);
921       if(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf == NULLP)
922       {
923          DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for gnb buffer");
924          ret = RFAILED;
925       }
926       else
927       {
928          fillBitString(&gNbId->global_gNB_ID.gnb_id.choice.gnb_ID, unused, byteSize, gnbId);
929       }
930    }
931
932    /* fill gNB-DU ID */ 
933    DU_ALLOC( gNbId->gNB_DU_ID, sizeof(GNB_DU_ID_t));
934    if(gNbId->gNB_DU_ID == NULLP)
935    {
936       DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for gNB_DU_ID ");
937       ret = RFAILED;
938    }
939    else
940    {
941       gNbId->gNB_DU_ID->size = sizeof(uint8_t);
942       DU_ALLOC( gNbId->gNB_DU_ID->buf, sizeof(uint8_t));
943       if(gNbId->gNB_DU_ID->buf)
944       {
945          gNbId->gNB_DU_ID->buf[0] =duCb.e2apDb.e2NodeId;
946       }
947       else
948       {
949          DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for gNB_DU_ID buffer");
950          ret = RFAILED;
951       }
952    }
953
954    return ret;
955 }
956
957 /*******************************************************************
958  *
959  * @brief fill the E2 node config information
960  *
961  * @details
962  *
963  *    Function : fillE2NodeConfig
964  *
965  *    Functionality: fill E2 node config information
966  *
967  * @params[in]  
968  *       Pointer to e2NodeCfg to be filled
969  *       E2 Node Component information
970  *       Type of configuration 
971  * @return ROK     - success
972  *         RFAILED - failure
973  *
974  ******************************************************************/
975
976 uint8_t fillE2NodeConfig(PTR e2NodeCfg, E2NodeComponent *e2NodeComponentInfo, ConfigType configType)
977 {
978    E2NodeConfig *e2NodeConfig=NULLP;
979    E2nodeComponentInterfaceType_t *interfaceType=NULLP;
980    E2nodeComponentID_t *componentID =NULLP;
981    E2nodeComponentConfiguration_t *configuration=NULLP;
982    E2nodeComponentConfigAddition_Item_t *e2NodeAddItem=NULL;
983    E2nodeComponentConfigUpdate_Item_t *e2NodeUpdateItem =NULL;
984    E2nodeComponentConfigRemoval_Item_t *e2NodeRemovalItem=NULL;
985    
986    switch(configType)
987    {
988       case CONFIG_ADD:
989       {
990          e2NodeAddItem = (E2nodeComponentConfigAddition_Item_t*)e2NodeCfg;
991          interfaceType = &e2NodeAddItem->e2nodeComponentInterfaceType;
992          componentID   = &e2NodeAddItem->e2nodeComponentID;
993          configuration = &e2NodeAddItem->e2nodeComponentConfiguration; 
994          e2NodeConfig = e2NodeComponentInfo->addConfiguration;
995          break;
996       }
997       case CONFIG_MOD:
998       {
999          e2NodeUpdateItem = (E2nodeComponentConfigUpdate_Item_t *) e2NodeCfg;
1000          interfaceType = &e2NodeUpdateItem->e2nodeComponentInterfaceType;
1001          componentID   = &e2NodeUpdateItem->e2nodeComponentID;
1002          configuration = &e2NodeUpdateItem->e2nodeComponentConfiguration; 
1003          e2NodeConfig = e2NodeComponentInfo->updateConfiguration;
1004          break;
1005       }
1006       case CONFIG_DEL:
1007       {
1008          e2NodeRemovalItem = (E2nodeComponentConfigRemoval_Item_t*) e2NodeCfg;
1009          interfaceType = &e2NodeRemovalItem->e2nodeComponentInterfaceType;
1010          componentID  = &e2NodeRemovalItem->e2nodeComponentID;
1011          break;
1012       }
1013       default:
1014       {
1015          DU_LOG("\nERROR  --> E2AP : Configuration type %d does not supported ", configType);
1016          return RFAILED;
1017       }
1018    }
1019    /* E2nodeComponentInterfaceType */
1020    *interfaceType = convertInterfaceToE2ComponentInterfaceType(e2NodeComponentInfo->interfaceType);
1021    
1022    /*  We now only support the F1 interface out of these interfaces
1023     * (NG,XN,E1,F1,W1,S1,X2), therefore only the F1 component identifier was filled in. */
1024    
1025    if(*interfaceType == F1)
1026    {
1027       /* E2 Node Component ID */
1028       componentID->present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1;
1029       DU_ALLOC(componentID->choice.e2nodeComponentInterfaceTypeF1,sizeof(E2nodeComponentInterfaceF1_t));
1030       if(componentID->choice.e2nodeComponentInterfaceTypeF1 == NULLP)
1031       {
1032          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__);
1033          return RFAILED;
1034       }
1035       componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t);
1036       DU_ALLOC(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
1037             componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
1038
1039       if(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP)
1040       {
1041          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__);
1042          return RFAILED;
1043       }
1044       memcpy(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf, &e2NodeComponentInfo->componentId,\
1045             componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
1046    }
1047   
1048    if(configType == CONFIG_DEL)
1049    {
1050       /* We don't need to fill out the E2 Node Component Request and Response
1051        * information in the case of CONFIG_DEL, therefore returning ROK from here. */
1052       return ROK;
1053    }
1054
1055    /* E2 Node Component Request Part */
1056    if(e2NodeConfig->componentRequestPart)
1057    {
1058       configuration->e2nodeComponentRequestPart.size = e2NodeConfig->reqBufSize ;
1059       DU_ALLOC(configuration->e2nodeComponentRequestPart.buf,\
1060             configuration->e2nodeComponentRequestPart.size);
1061       if(configuration->e2nodeComponentRequestPart.buf == NULLP)
1062       {
1063          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__);
1064          return RFAILED;
1065       }
1066
1067       memcpy(configuration->e2nodeComponentRequestPart.buf,\
1068             e2NodeConfig->componentRequestPart, configuration->\
1069             e2nodeComponentRequestPart.size);
1070    }
1071    else
1072    {
1073       DU_LOG("\nERROR  --> E2AP: componentRequestPart is null ");
1074       return RFAILED;
1075    }
1076
1077    /* E2 Node Component Response Part */
1078    if(e2NodeConfig->componentResponsePart)
1079    {
1080       configuration->e2nodeComponentResponsePart.size = e2NodeConfig->rspBufSize; 
1081       DU_ALLOC(configuration->e2nodeComponentResponsePart.buf, configuration->e2nodeComponentResponsePart.size);
1082       if(configuration->e2nodeComponentResponsePart.buf == NULLP)
1083       {
1084          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__);
1085          return RFAILED;
1086       }
1087       memcpy(configuration->e2nodeComponentResponsePart.buf,  e2NodeConfig->componentResponsePart, configuration->\
1088             e2nodeComponentResponsePart.size);
1089    }
1090    else
1091    {
1092       DU_LOG("\nERROR  --> E2AP: componentResponsePart is null");
1093       return RFAILED;
1094    }
1095    
1096    return ROK;
1097 }
1098
1099 /*******************************************************************
1100  *
1101  * @brief Builds E2 node config addition list 
1102  *
1103  * @details
1104  *
1105  *    Function : BuildE2NodeConfigAddList
1106  *
1107  *    Functionality: Building E2 node config addition list
1108  *
1109  * @params[in] 
1110  *    E2nodeComponentConfigAddition_List_t to be filled
1111  *    Procedure Code
1112  *    Count of E2 node to be added in the list    
1113  *    Received list of E2 node configuration
1114  *
1115  * @return ROK     - success
1116  *         RFAILED - failure
1117  *
1118  ******************************************************************/
1119
1120 uint8_t BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAddList, uint8_t procedureCode, uint16_t count, E2NodeConfigItem *e2NodeList)
1121 {
1122    uint8_t arrIdx = 0;
1123    CmLList         *node =NULL;
1124    E2NodeComponent *e2NodeComponentInfo=NULL;
1125    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItemIe=NULL;
1126    E2nodeComponentConfigAddition_Item_t *e2NodeAddItem=NULL;
1127    
1128
1129    /* For ProcedureCodeE2_id_E2setup, the number of E2 node configuration list items is
1130     * equal to the number of E2 node configuration entries stored in the database.
1131     * For any other procedure, the E2 node configuration list count is equal
1132     * to the count of E2 node configuration obtained from the function's caller */
1133
1134    if(procedureCode == ProcedureCodeE2_id_E2setup)
1135       e2NodeAddList->list.count = duCb.e2apDb.e2NodeComponentList.count;
1136    else
1137       e2NodeAddList->list.count = count;
1138
1139    e2NodeAddList->list.size = e2NodeAddList->list.count * sizeof(E2nodeComponentConfigAddition_ItemIEs_t *);
1140    DU_ALLOC(e2NodeAddList->list.array, e2NodeAddList->list.size);
1141    if(e2NodeAddList->list.array == NULLP)
1142    {
1143        DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
1144        return RFAILED;
1145    }
1146
1147    for(arrIdx = 0; arrIdx< e2NodeAddList->list.count; arrIdx++)
1148    {
1149       DU_ALLOC(e2NodeAddList->list.array[arrIdx], sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
1150       if(e2NodeAddList->list.array[arrIdx] == NULLP)
1151       {
1152          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
1153          return RFAILED;
1154       }
1155       
1156       if(procedureCode == ProcedureCodeE2_id_E2setup)
1157       {
1158          /* Getting all of the E2 node configuration's information from DuCb one by one*/
1159          if(arrIdx == 0)
1160          {
1161             CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node); 
1162          }
1163          else
1164          {
1165             node = node->next;
1166          }
1167          if(!node)
1168          {
1169             DU_LOG("\nERROR  --> E2AP : E2 node component list node is null");
1170             return RFAILED;
1171          }
1172          e2NodeComponentInfo = (E2NodeComponent*)node->node;
1173       }
1174       else
1175       {
1176          /* Getting only those E2 node configuration from DuCb whose interface
1177           * and action type is present in the received array */
1178          e2NodeComponentInfo = fetchE2NodeComponentInfo(e2NodeList[arrIdx].interface, e2NodeList[arrIdx].componentId, &node);
1179       }
1180       
1181       if(!e2NodeComponentInfo)
1182       {
1183          DU_LOG("\nERROR  --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__);
1184          return RFAILED;
1185       }
1186
1187       e2NodeAddItemIe = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[arrIdx];
1188       e2NodeAddItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition_Item;
1189       e2NodeAddItemIe->criticality = CriticalityE2_reject;
1190       e2NodeAddItemIe->value.present = E2nodeComponentConfigAddition_ItemIEs__value_PR_E2nodeComponentConfigAddition_Item;
1191       e2NodeAddItem = &e2NodeAddItemIe->value.choice.E2nodeComponentConfigAddition_Item;
1192       if(fillE2NodeConfig((PTR)e2NodeAddItem, e2NodeComponentInfo, CONFIG_ADD) != ROK)
1193       {
1194          DU_LOG("\nERROR  --> E2AP : Failed to fill the E2 node configuration");
1195          return RFAILED;
1196       }
1197    }
1198    return ROK;
1199 }
1200
1201 /*******************************************************************
1202  *
1203  * @brief Builds E2 node config update list 
1204  *
1205  * @details
1206  *
1207  *    Function : BuildE2NodeConfigUpdateList
1208  *
1209  *    Functionality: Building E2 node config update list
1210  *
1211  * @params[in] 
1212  *    E2nodeComponentConfigUpdate_List_t to be filled
1213  *    Count of E2 node to be update in the list    
1214  *    Received list of E2 node configuration
1215  *
1216  * @return ROK     - success
1217  *         RFAILED - failure
1218  *
1219  ******************************************************************/
1220
1221 uint8_t BuildE2NodeConfigUpdateList(E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList, uint16_t count,  E2NodeConfigItem *updateE2Node)
1222 {
1223    uint8_t arrIdx = 0;
1224    CmLList         *node =NULL;
1225    E2NodeComponent *e2NodeComponentInfo =NULL;
1226    E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItemIe =NULL;
1227    E2nodeComponentConfigUpdate_Item_t *e2NodeUpdateItem =NULL;
1228
1229    e2NodeUpdateList->list.count = count;
1230    e2NodeUpdateList->list.size = e2NodeUpdateList->list.count * sizeof(E2nodeComponentConfigUpdate_ItemIEs_t *);
1231    DU_ALLOC(e2NodeUpdateList->list.array, e2NodeUpdateList->list.size);
1232    if(e2NodeUpdateList->list.array == NULLP)
1233    {
1234       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigUpdateList %d",__LINE__);
1235       return RFAILED;
1236    }
1237
1238    for(arrIdx = 0; arrIdx< e2NodeUpdateList->list.count; arrIdx++)
1239    {
1240       DU_ALLOC(e2NodeUpdateList->list.array[arrIdx], sizeof(E2nodeComponentConfigUpdate_ItemIEs_t));
1241       if(e2NodeUpdateList->list.array[arrIdx] == NULLP)
1242       {
1243          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigUpdateList %d",__LINE__);
1244          return RFAILED;
1245       }
1246
1247       e2NodeComponentInfo= fetchE2NodeComponentInfo(updateE2Node[arrIdx].interface, updateE2Node[arrIdx].componentId, &node);
1248       if(!e2NodeComponentInfo)
1249       {
1250          DU_LOG("\nERROR  --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__);
1251          return RFAILED;
1252       }
1253
1254       e2NodeUpdateItemIe = (E2nodeComponentConfigUpdate_ItemIEs_t *) e2NodeUpdateList->list.array[arrIdx];
1255       e2NodeUpdateItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate_Item;
1256       e2NodeUpdateItemIe->criticality = CriticalityE2_reject;
1257       e2NodeUpdateItemIe->value.present = E2nodeComponentConfigUpdate_ItemIEs__value_PR_E2nodeComponentConfigUpdate_Item;
1258       e2NodeUpdateItem = &e2NodeUpdateItemIe->value.choice.E2nodeComponentConfigUpdate_Item;
1259
1260       if(fillE2NodeConfig((PTR)e2NodeUpdateItem, e2NodeComponentInfo, CONFIG_MOD) != ROK)
1261       {
1262          DU_LOG("\nERROR  --> E2AP : Failed to fill the E2 node configuration");
1263          return RFAILED;
1264       }
1265
1266    }
1267    return ROK;
1268
1269 }
1270
1271
1272 /*******************************************************************
1273  *
1274  * @brief Builds E2 node config remove list 
1275  *
1276  * @details
1277  *
1278  *    Function :BuildE2NodeConfigRemoveList 
1279  *
1280  *    Functionality: Building E2 node config remove list
1281  *
1282  * @params[in] 
1283  *    E2nodeComponentConfigRemoval_List_t to be filled
1284  *    Count of E2 node to be remove in the list    
1285  *    Received list of E2 node configuration
1286  * @return ROK     - success
1287  *         RFAILED - failure
1288  *
1289  ******************************************************************/
1290
1291 uint8_t BuildE2NodeConfigRemoveList(E2nodeComponentConfigRemoval_List_t *e2NodeRemoveList, uint16_t count,  E2NodeConfigItem *updateE2Node)
1292 {
1293    uint8_t arrIdx = 0;
1294    CmLList         *node=NULL;
1295    E2NodeComponent *e2NodeComponentInfo=NULL;
1296    E2nodeComponentConfigRemoval_ItemIEs_t *e2NodeRemovalItemIe=NULL;
1297    E2nodeComponentConfigRemoval_Item_t *e2NodeRemovalItem=NULL;
1298
1299    e2NodeRemoveList->list.count = count;
1300    e2NodeRemoveList->list.size = e2NodeRemoveList->list.count * sizeof(E2nodeComponentConfigRemoval_ItemIEs_t *);
1301    DU_ALLOC(e2NodeRemoveList->list.array, e2NodeRemoveList->list.size);
1302    if(e2NodeRemoveList->list.array == NULLP)
1303    {
1304       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigRemoveList %d",__LINE__);
1305       return RFAILED;
1306    }
1307
1308    for(arrIdx = 0; arrIdx< e2NodeRemoveList->list.count; arrIdx++)
1309    {
1310       DU_ALLOC(e2NodeRemoveList->list.array[arrIdx], sizeof(E2nodeComponentConfigRemoval_ItemIEs_t));
1311       if(e2NodeRemoveList->list.array[arrIdx] == NULLP)
1312       {
1313          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigRemoveList %d",__LINE__);
1314          return RFAILED;
1315       }
1316
1317       e2NodeComponentInfo= fetchE2NodeComponentInfo(updateE2Node[arrIdx].interface,updateE2Node[arrIdx].componentId, &node);
1318       if(!e2NodeComponentInfo)
1319       {
1320          DU_LOG("\nERROR  --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__);
1321          return RFAILED;
1322       }
1323
1324       e2NodeRemovalItemIe = (E2nodeComponentConfigRemoval_ItemIEs_t *) e2NodeRemoveList->list.array[arrIdx];
1325       e2NodeRemovalItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval_Item;
1326       e2NodeRemovalItemIe->criticality = CriticalityE2_reject;
1327       e2NodeRemovalItemIe->value.present = E2nodeComponentConfigRemoval_ItemIEs__value_PR_E2nodeComponentConfigRemoval_Item;
1328       e2NodeRemovalItem = &e2NodeRemovalItemIe->value.choice.E2nodeComponentConfigRemoval_Item;
1329
1330       if(fillE2NodeConfig((PTR)e2NodeRemovalItem, e2NodeComponentInfo, CONFIG_DEL) != ROK)
1331       {
1332          DU_LOG("\nERROR  --> E2AP : Failed to fill the E2 node configuration");
1333          return RFAILED;
1334       }
1335
1336    }
1337    return ROK;
1338 }
1339 /*******************************************************************
1340  *
1341  * @brief deallocation of E2SM_KPM_RANfunction_Description_t
1342  *
1343  * @details
1344  *
1345  *    Function : freeE2smKpmRanFunctionDefinition
1346  *
1347  *    Functionality: deallocation of E2SM_KPM_RANfunction_Description_t
1348  *
1349  * @params[in]  E2SM_KPM_RANfunction_Description_t *ranFunctionDefinition
1350  * @return void
1351  *
1352  ******************************************************************/
1353
1354 void freeE2smKpmRanFunctionDefinition(E2SM_KPM_RANfunction_Description_t *ranFunctionDefinition)
1355 {
1356    MeasurementInfo_Action_Item_t *measInfoList;
1357    uint8_t eventTriggerIdx, reportStyleIdx, measInfoIdx;
1358    RANfunction_Name_t *ranFuncName;
1359    struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle;
1360    struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List *eventTriggerStyle;
1361    if(ranFunctionDefinition)
1362    {
1363       ranFuncName = &ranFunctionDefinition->ranFunction_Name;
1364       /* Free RAN function Name */     
1365       DU_FREE(ranFuncName->ranFunction_ShortName.buf,  ranFuncName->ranFunction_ShortName.size);
1366       DU_FREE(ranFuncName->ranFunction_E2SM_OID.buf, ranFuncName->ranFunction_E2SM_OID.size);
1367       DU_FREE(ranFuncName->ranFunction_Description.buf, ranFuncName->ranFunction_Description.size);
1368
1369       /* Sequence of Event Trigger styles */
1370       eventTriggerStyle = ranFunctionDefinition->ric_EventTriggerStyle_List;
1371       if(eventTriggerStyle)
1372       {
1373          if(eventTriggerStyle->list.array)
1374          {
1375             for(eventTriggerIdx =0;eventTriggerIdx<eventTriggerStyle->list.count; eventTriggerIdx++)
1376             {
1377                if(eventTriggerStyle->list.array[eventTriggerIdx])
1378                {
1379                   DU_FREE(eventTriggerStyle->list.array[eventTriggerIdx]->ric_EventTriggerStyle_Name.buf,\
1380                         eventTriggerStyle->list.array[eventTriggerIdx]->ric_EventTriggerStyle_Name.size);
1381                   DU_FREE(eventTriggerStyle->list.array[eventTriggerIdx], sizeof(RIC_EventTriggerStyle_Item_t ));
1382                }
1383             }
1384             DU_FREE(eventTriggerStyle->list.array, eventTriggerStyle->list.size)
1385          }
1386          DU_FREE(eventTriggerStyle, sizeof(struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List));
1387       }
1388       
1389       /* Sequence of Report styles */
1390       ricReportStyle = ranFunctionDefinition->ric_ReportStyle_List;
1391       if(ricReportStyle)
1392       {
1393          if(ricReportStyle->list.array)
1394          {
1395             for(reportStyleIdx =0;reportStyleIdx<ricReportStyle->list.count; reportStyleIdx++)
1396             {
1397                if(ricReportStyle->list.array[reportStyleIdx])
1398                {
1399                   if(ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.buf)
1400                   {
1401                      DU_FREE(ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.buf,\
1402                            ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.size);
1403                   }
1404                   if(ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.array)
1405                   {
1406                      for(measInfoIdx=0; measInfoIdx<ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.count; \
1407                            measInfoIdx++)
1408                      {
1409                         measInfoList = ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.array[measInfoIdx];
1410                         if(measInfoList)
1411                         {
1412                            DU_FREE(measInfoList->measID, sizeof(long));
1413                            DU_FREE(measInfoList->measName.buf, measInfoList->measName.size);
1414                            DU_FREE(measInfoList,sizeof(MeasurementInfo_Action_Item_t)); 
1415                         }
1416                      }
1417                      DU_FREE(measInfoList,ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.size);
1418                   }
1419                   DU_FREE(ricReportStyle->list.array[reportStyleIdx], sizeof(RIC_ReportStyle_Item_t));
1420                }
1421             }
1422             DU_FREE(ricReportStyle->list.array, ricReportStyle->list.size);
1423          }
1424          DU_FREE(ricReportStyle, sizeof(struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List));
1425       }
1426       DU_FREE(ranFunctionDefinition, sizeof(E2SM_KPM_RANfunction_Description_t)); 
1427    }
1428 }
1429
1430 /*******************************************************************
1431  *
1432  * @brief fill the e2sm ric report style
1433  *
1434  * @details
1435  *
1436  *    Function : fillRicReportStyle
1437  *
1438  *    Functionality: fill the report style
1439  *
1440  * @params[in]   RanFunction *ranFuncDb, struct
1441  * E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle
1442  * @return ROK     - success
1443  *         RFAILED - failure
1444  *
1445  ******************************************************************/
1446 uint8_t fillRicReportStyle(RanFunction *ranFuncDb, struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle)
1447 {
1448    uint8_t styleIdx, measInfoIdx;
1449    MeasurementInfo_Action_List_t *measInfo;
1450    CmLList  *node;
1451    
1452    ricReportStyle->list.count = ranFuncDb->numOfReportStyleSupported;
1453    ricReportStyle->list.size = ricReportStyle->list.count * sizeof(RIC_ReportStyle_Item_t*);
1454    DU_ALLOC(ricReportStyle->list.array, ricReportStyle->list.size);
1455    if(!ricReportStyle->list.array)
1456    {
1457       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for ranFuncDefinition %d",__LINE__);
1458       return RFAILED;
1459    }
1460
1461    for(styleIdx =0;styleIdx<ricReportStyle->list.count; styleIdx++)
1462    {
1463       DU_ALLOC(ricReportStyle->list.array[styleIdx], sizeof(RIC_ReportStyle_Item_t));
1464       if(!ricReportStyle->list.array[styleIdx])
1465       {
1466          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1467          return RFAILED;
1468       }
1469       
1470       /* RIC Report Style Type */
1471       ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Type = ranFuncDb->reportStyleList[styleIdx].reportStyle.styleType;
1472       
1473       /* RIC Report Style Format Type */
1474       ricReportStyle->list.array[styleIdx]->ric_ActionFormat_Type = ranFuncDb->reportStyleList[styleIdx].reportStyle.formatType;
1475       
1476       /* RIC Report Style Name */
1477       ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size = strlen(ranFuncDb->reportStyleList[styleIdx].reportStyle.name);
1478       DU_ALLOC(ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf,\
1479             ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size);
1480       if(!ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf)
1481       {
1482          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1483          return RFAILED;
1484       }
1485       memcpy(ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf, ranFuncDb->reportStyleList[styleIdx].reportStyle.name,\
1486             ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size);
1487
1488       /* RIC Indication Header Format Type*/
1489       ricReportStyle->list.array[styleIdx]->ric_IndicationHeaderFormat_Type = ranFuncDb->ricIndicationHeaderFormat;
1490
1491       /* RIC Indication Message Format Type*/
1492       ricReportStyle->list.array[styleIdx]->ric_IndicationMessageFormat_Type = ranFuncDb->ricIndicationMessageFormat;
1493       
1494       /* Measurement Info Action List */
1495       CmLListCp measInfoList =ranFuncDb->reportStyleList[styleIdx].measurementInfoList;
1496       if(!measInfoList.count)
1497       {
1498          continue;      
1499       }
1500
1501       CM_LLIST_FIRST_NODE(&ranFuncDb->reportStyleList[styleIdx].measurementInfoList, node);
1502       measInfo = &ricReportStyle->list.array[styleIdx]->measInfo_Action_List;
1503
1504       measInfo->list.count = measInfoList.count; 
1505       measInfo->list.size =  measInfoList.count*sizeof(MeasurementInfo_Action_Item_t*);
1506       DU_ALLOC(measInfo->list.array, measInfo->list.size);
1507       if(!measInfo->list.array)
1508       {
1509          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1510          return RFAILED;
1511       }
1512
1513       for(measInfoIdx=0; measInfoIdx<measInfo->list.count; measInfoIdx++)
1514       {
1515          if(!node)
1516          {
1517             DU_LOG("\nERROR  --> E2AP: Measurement info node is null");
1518             return RFAILED;
1519          }
1520
1521          DU_ALLOC(measInfo->list.array[measInfoIdx],sizeof(MeasurementInfo_Action_Item_t));  
1522          if(!measInfo->list.array[measInfoIdx])
1523          {
1524             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1525             return RFAILED;
1526          }
1527          MeasurementInfoForAction *measInfoForAction= (MeasurementInfoForAction*)node->node;
1528          DU_ALLOC(measInfo->list.array[measInfoIdx]->measID, sizeof(long));
1529          if(!measInfo->list.array[measInfoIdx]->measID)
1530          {
1531             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1532             return RFAILED;
1533          }
1534          
1535          memcpy(measInfo->list.array[measInfoIdx]->measID, &measInfoForAction->measurementTypeId,sizeof(long));
1536          measInfo->list.array[measInfoIdx]->measName.size= strlen(measInfoForAction->measurementTypeName);
1537          DU_ALLOC(measInfo->list.array[measInfoIdx]->measName.buf, measInfo->list.array[measInfoIdx]->measName.size);
1538          if(!measInfo->list.array[measInfoIdx]->measName.size)
1539          {
1540             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1541             return RFAILED;
1542          }
1543
1544          memcpy(measInfo->list.array[measInfoIdx]->measName.buf, \
1545                measInfoForAction->measurementTypeName,\
1546                measInfo->list.array[measInfoIdx]->measName.size);
1547          node = node->next;
1548       }
1549
1550    }
1551    return ROK;
1552 }
1553 /*******************************************************************
1554  *
1555  * @brief fill the ric event trigger style
1556  *
1557  * @details
1558  *
1559  *    Function : fillRicEventTriggerStyle
1560  *
1561  *    Functionality: fill the ric event trigger style
1562  *
1563  * @params[in]   
1564  * @return ROK     - success
1565  *         RFAILED - failure
1566  *
1567  ******************************************************************/
1568 uint8_t fillRicEventTriggerStyle(RanFunction *ranFuncDb, struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List *ricEventTriggerStyle)
1569 {
1570    uint8_t styleIdx;
1571
1572    ricEventTriggerStyle->list.count = ranFuncDb->numOfEventTriggerStyleSupported;
1573    ricEventTriggerStyle->list.size = ricEventTriggerStyle->list.count*  sizeof(RIC_EventTriggerStyle_Item_t *);
1574    DU_ALLOC(ricEventTriggerStyle->list.array, ricEventTriggerStyle->list.size);
1575    if(!ricEventTriggerStyle->list.array)
1576    {
1577       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for ric_EventTriggerStyle_List %d",__LINE__);
1578       return RFAILED;
1579    }
1580
1581    for(styleIdx =0;styleIdx<ricEventTriggerStyle->list.count; styleIdx++)
1582    {
1583       DU_ALLOC(ricEventTriggerStyle->list.array[styleIdx], sizeof(RIC_EventTriggerStyle_Item_t ));
1584       if(!ricEventTriggerStyle->list.array[styleIdx])
1585       {
1586          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1587          return RFAILED;
1588       }
1589       ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Type = ranFuncDb->eventTriggerStyleList[styleIdx].styleType;
1590
1591       ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerFormat_Type = ranFuncDb->eventTriggerStyleList[styleIdx].formatType;
1592
1593       ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.size = strlen(ranFuncDb->eventTriggerStyleList[styleIdx].name);
1594       DU_ALLOC(ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.buf,\
1595             ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.size);
1596       if(!ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.buf)
1597       {
1598          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1599          return RFAILED;
1600       }
1601       memcpy(ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.buf,ranFuncDb->eventTriggerStyleList[styleIdx].name,\
1602             ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.size);
1603    
1604    }
1605    return ROK;
1606 }
1607
1608 /*******************************************************************
1609  *
1610  * @brief Builds Ran function item
1611  *
1612  * @details
1613  *
1614  *    Function : BuildRanFunctionItem  
1615  *
1616  *    Functionality: Building RAN function item
1617  *
1618  * @params[in] 
1619  *             RAN function item that has to be filled 
1620  *             Stored RAN Function information
1621  * @return ROK     - success
1622  *         RFAILED - failure
1623  *
1624  ******************************************************************/
1625
1626 uint8_t BuildRanFunctionItem(RANfunction_Item_t *ranFuncItem, RanFunction *ranFuncDb)
1627 {
1628    uint8_t ret =RFAILED;
1629    RANfunctionDefinition_t  *ranFunctionDefinition;
1630    RANfunction_Name_t *ranFuncName;
1631    asn_enc_rval_t encRetVal;
1632    E2SM_KPM_RANfunction_Description_t *ranFuncDefinition;
1633    
1634    while(true)
1635    {
1636       /* RAN function Id*/
1637       ranFuncItem->ranFunctionID = ranFuncDb->id;
1638
1639       /* RAN Function Revision*/
1640       ranFuncItem->ranFunctionRevision = ranFuncDb->revisionCounter;
1641
1642       /* RAN function OID*/
1643       ranFuncItem->ranFunctionOID.size = strlen(ranFuncDb->name.serviceModelOID);
1644       DU_ALLOC(ranFuncItem->ranFunctionOID.buf, ranFuncItem->ranFunctionOID.size);
1645       if(!ranFuncItem->ranFunctionOID.buf)
1646       {
1647          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1648          break;
1649       }
1650       memcpy(ranFuncItem->ranFunctionOID.buf, ranFuncDb->name.serviceModelOID, ranFuncItem->ranFunctionOID.size);
1651
1652       /* RAN function Definition */
1653       DU_ALLOC(ranFuncDefinition, sizeof(E2SM_KPM_RANfunction_Description_t));
1654       if(!ranFuncDefinition)
1655       {
1656          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1657          break;
1658       }
1659
1660       /* RAN function Name */
1661       ranFuncName = &ranFuncDefinition->ranFunction_Name;
1662
1663       /* RAN function ShortName */
1664       ranFuncName->ranFunction_ShortName.size = strlen(ranFuncDb->name.shortName); 
1665       DU_ALLOC(ranFuncName->ranFunction_ShortName.buf,  ranFuncName->ranFunction_ShortName.size);
1666       if(!ranFuncName->ranFunction_ShortName.buf)
1667       {
1668          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1669          break;
1670       }
1671       memcpy(ranFuncName->ranFunction_ShortName.buf, ranFuncDb->name.shortName, strlen(ranFuncDb->name.shortName));
1672
1673       /* RAN function E2SM_OID */
1674       ranFuncName->ranFunction_E2SM_OID.size = strlen(ranFuncDb->name.serviceModelOID);
1675       DU_ALLOC(ranFuncName->ranFunction_E2SM_OID.buf, ranFuncName->ranFunction_E2SM_OID.size);
1676       if(!ranFuncName->ranFunction_E2SM_OID.buf)
1677       {
1678          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1679          break;
1680       }
1681       memcpy(ranFuncName->ranFunction_E2SM_OID.buf, ranFuncDb->name.serviceModelOID, ranFuncName->ranFunction_E2SM_OID.size);
1682
1683       /* RAN Function Name Description */
1684       ranFuncName->ranFunction_Description.size = strlen(ranFuncDb->name.description);
1685       DU_ALLOC(ranFuncName->ranFunction_Description.buf, ranFuncName->ranFunction_Description.size);
1686       if(!ranFuncName->ranFunction_Description.buf)
1687       {
1688          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1689          break;
1690       }
1691       memcpy(ranFuncName->ranFunction_Description.buf, ranFuncDb->name.description, ranFuncName->ranFunction_Description.size);
1692
1693       /* RIC Event Trigger Style List */
1694       DU_ALLOC(ranFuncDefinition->ric_EventTriggerStyle_List, sizeof(struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List));
1695       if(!ranFuncDefinition->ric_EventTriggerStyle_List)
1696       {
1697          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1698          break;
1699       }
1700
1701       if(fillRicEventTriggerStyle(ranFuncDb, ranFuncDefinition->ric_EventTriggerStyle_List)!=ROK)
1702       {
1703          DU_LOG("\nERROR  --> E2AP: failed to fill ric event trigger style");
1704          break;
1705       }
1706
1707       /* RIC Report Style List */
1708       DU_ALLOC(ranFuncDefinition->ric_ReportStyle_List, sizeof(struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List));
1709       if(!ranFuncDefinition->ric_ReportStyle_List)
1710       {
1711          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1712          break;
1713       }
1714       if(fillRicReportStyle(ranFuncDb, ranFuncDefinition->ric_ReportStyle_List) != ROK)
1715       {
1716          DU_LOG("\nERROR  --> E2AP: failed to fill ric report style");
1717          break;
1718       }
1719
1720       /* Encode the F1SetupRequest type as APER */
1721       xer_fprint(stdout, &asn_DEF_E2SM_KPM_RANfunction_Description, ranFuncDefinition);
1722
1723       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1724       encBufSize = 0;
1725       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_RANfunction_Description, 0, ranFuncDefinition, PrepFinalEncBuf, encBuf);
1726
1727       /* Encode results */
1728       if(encRetVal.encoded == ENCODE_FAIL)
1729       {
1730          DU_LOG("\nERROR  -->  F1AP : Could not encode RAN function definition  (at %s)\n",\
1731                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1732          break;
1733       }
1734       else
1735       {
1736          DU_LOG("\nDEBUG   -->  F1AP : Created APER encoded buffer for RAN function definition \n");
1737          for(uint8_t measIeIdx=0; measIeIdx< encBufSize; measIeIdx++)
1738          {
1739             printf("%x",encBuf[measIeIdx]);
1740          }
1741          ranFunctionDefinition = &ranFuncItem->ranFunctionDefinition; 
1742          ranFunctionDefinition->size = encBufSize;
1743          DU_ALLOC(ranFunctionDefinition->buf, encBufSize);
1744          if(ranFunctionDefinition->buf == NULLP)
1745          {
1746             DU_LOG("\nERROR  -->  F1AP : Memory allocation failed for RAN function definition buffer");
1747             break;
1748          }
1749          memcpy(ranFunctionDefinition->buf, &encBuf, encBufSize);
1750          ret = ROK;
1751          break;
1752       }
1753    }
1754    freeE2smKpmRanFunctionDefinition(ranFuncDefinition);
1755    return ret;
1756 }
1757
1758 /*******************************************************************
1759  *
1760  * @brief Builds Ran function add list based on the procedure code
1761  *
1762  * @details
1763  *
1764  *    Function : BuildRanFunctionAddList 
1765  *
1766  *    Functionality: Building RAN addition addition list
1767  *       In case of ProcedureCodeE2_id_E2setup we add all the RAN Function list
1768  *       which is present in E2 database.
1769  *       In the case of other procedures, we just fill the RAN functions whose ID 
1770  *       is contained in recvList
1771  *
1772  * @params[in] 
1773  *       RAN Function list
1774  *       Procedure code
1775  *       Count of ran functions to be added in the list
1776  *       Received list of RAN functions
1777  *
1778  * @return ROK     - success
1779  *         RFAILED - failure
1780  *
1781  ******************************************************************/
1782
1783 uint8_t BuildRanFunctionAddList(RANfunctions_List_t *ranFunctionsList, uint8_t procedureCode, uint8_t count, RanFuncInfo *recvList)
1784 {
1785    uint16_t id;
1786    RanFunction *ranFuncDb;
1787    uint8_t ranFuncIdx;
1788    RANfunction_ItemIEs_t *ranFuncItemIe;
1789    
1790    /* For ProcedureCodeE2_id_E2setup, the number of RAN function list items is
1791     * equal to the number of ran function entries stored in the database.
1792     * For any other procedure, the RAN function list count is equal
1793     * to the count of ran functions obtained from the function's caller */
1794
1795    if(procedureCode == ProcedureCodeE2_id_E2setup)
1796       ranFunctionsList->list.count = duCb.e2apDb.numOfRanFunction;
1797    else
1798       ranFunctionsList->list.count = count;
1799
1800    ranFunctionsList->list.size = ranFunctionsList->list.count * sizeof(RANfunction_ItemIEs_t*);
1801    DU_ALLOC(ranFunctionsList->list.array, ranFunctionsList->list.size);
1802    if(ranFunctionsList->list.array == NULLP)
1803    {
1804       DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
1805       return RFAILED;
1806    }
1807
1808    for(ranFuncIdx = 0; ranFuncIdx< ranFunctionsList->list.count; ranFuncIdx++)
1809    {
1810       DU_ALLOC(ranFunctionsList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
1811       if(ranFunctionsList->list.array[ranFuncIdx] == NULLP)
1812       {
1813          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
1814          return RFAILED;
1815       }
1816       if(procedureCode == ProcedureCodeE2_id_E2setup) 
1817       {
1818          /* Getting all of the RAN function's information from DuCb one by one*/
1819          ranFuncDb = &duCb.e2apDb.ranFunction[ranFuncIdx];
1820       }
1821       else
1822       {
1823          /* Getting only the RAN function information from DuCb whose Id is
1824           * present in the received array */
1825          id =recvList[ranFuncIdx].id;
1826          ranFuncDb = &duCb.e2apDb.ranFunction[id-1];
1827       }
1828       ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncIdx];
1829       ranFuncItemIe->id = ProtocolIE_IDE2_id_RANfunction_Item;
1830       ranFuncItemIe->criticality = CriticalityE2_ignore;
1831       ranFuncItemIe->value.present = RANfunction_ItemIEs__value_PR_RANfunction_Item;
1832       BuildRanFunctionItem(&ranFuncItemIe->value.choice.RANfunction_Item, ranFuncDb);
1833    }
1834    return ROK;
1835 }   
1836
1837 /*******************************************************************
1838  *
1839  * @brief De Allocate E2 Setup Request Message
1840  *
1841  * @details
1842  *
1843  *    Function : FreeE2SetupReq
1844  *
1845  *    Functionality: De-Allocating E2 Setup request Message
1846  *
1847  * @params[in] E2AP_PDU_t *e2apMsg
1848  
1849  * @return void
1850  *
1851  * ****************************************************************/
1852
1853 void FreeE2SetupReq(E2AP_PDU_t *e2apMsg)
1854 {
1855    uint8_t arrIdx = 0;
1856    uint8_t e2NodeAddListIdx =0, ranFuncAddListIdx;
1857    E2setupRequest_t *e2SetupReq;
1858    E2nodeComponentConfigAddition_List_t *e2NodeAddList;
1859    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
1860    RANfunctions_List_t *ranFunctionsList;
1861    RANfunction_ItemIEs_t *ranFuncItemIe;
1862    RANfunction_Item_t  *ranFunItem;
1863
1864    /* De-allocating Memory */
1865    if(e2apMsg != NULLP)
1866    {
1867       if(e2apMsg->choice.initiatingMessage != NULLP)
1868       {
1869          e2SetupReq = &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest; 
1870          if(e2SetupReq->protocolIEs.list.array != NULLP)
1871          {
1872             for(arrIdx = 0; arrIdx < e2SetupReq->protocolIEs.list.count; arrIdx++)
1873             {
1874                if(e2SetupReq->protocolIEs.list.array[arrIdx] != NULLP)
1875                {
1876                   switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
1877                   {
1878                      case ProtocolIE_IDE2_id_TransactionID:
1879                           break;
1880                      case ProtocolIE_IDE2_id_GlobalE2node_ID:
1881                         {
1882                            if(e2SetupReq->protocolIEs.list.array[arrIdx]->\
1883                                  value.choice.GlobalE2node_ID.choice.gNB != NULLP)
1884                            {
1885                               GlobalE2node_gNB_ID_t *gNbId = NULLP;
1886                               gNbId = e2SetupReq->protocolIEs.list.array[arrIdx]->\
1887                                       value.choice.GlobalE2node_ID.choice.gNB;
1888                               if(gNbId->global_gNB_ID.plmn_id.buf != NULLP)
1889                               {
1890                                  DU_FREE(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf,\
1891                                        gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size);
1892                                  DU_FREE(gNbId->global_gNB_ID.plmn_id.buf,\
1893                                        gNbId->global_gNB_ID.plmn_id.size);
1894                               }
1895
1896                               if(gNbId->gNB_DU_ID != NULLP)
1897                               {
1898                                  DU_FREE( gNbId->gNB_DU_ID->buf, gNbId->gNB_DU_ID->size);
1899                                  DU_FREE(gNbId->gNB_DU_ID, sizeof(GNB_DU_ID_t));
1900                               }
1901                               DU_FREE(e2SetupReq->protocolIEs.list.array[arrIdx]->value.\
1902                                     choice.GlobalE2node_ID.choice.gNB, sizeof(GlobalE2node_gNB_ID_t));
1903                            }
1904                            break;
1905                         }
1906                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
1907                      {
1908                          e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;
1909                          if(e2NodeAddList->list.array)
1910                          {
1911                              for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
1912                              {
1913                                 e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
1914                                 
1915                                 /* Free E2 Node Component Request Part */
1916                                 DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\
1917                                       e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentRequestPart.size);
1918                                 
1919                                 /* Free E2 Node Component Response Part */
1920                                 DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.\
1921                                       e2nodeComponentResponsePart.buf, \
1922                                       e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentResponsePart.size);
1923                                  
1924                                  /* Free E2 Node Component ID */
1925                                 if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1)
1926                                 {
1927                                     DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
1928                                     e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
1929                                     e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
1930                                     e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
1931                                     DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\
1932                                     sizeof(E2nodeComponentInterfaceF1_t));
1933                                 }
1934                                 DU_FREE(e2NodeAddList->list.array[e2NodeAddListIdx], sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
1935                              }
1936                              DU_FREE(e2NodeAddList->list.array, e2NodeAddList->list.size);
1937                          }
1938                          break;
1939                      }
1940                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
1941                      {
1942                         ranFunctionsList = &(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List);  
1943                         if(ranFunctionsList->list.array)
1944                         {  
1945                            for(ranFuncAddListIdx= 0; ranFuncAddListIdx< ranFunctionsList->list.count; ranFuncAddListIdx++)
1946                            {
1947                               if(ranFunctionsList->list.array[ranFuncAddListIdx])
1948                               {
1949                                  ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncAddListIdx];
1950                                  ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
1951                                  DU_FREE(ranFunItem->ranFunctionOID.buf, ranFunItem->ranFunctionOID.size);
1952                                  DU_FREE(ranFunItem->ranFunctionDefinition.buf, ranFunItem->ranFunctionDefinition.size);
1953                                  DU_FREE(ranFunctionsList->list.array[ranFuncAddListIdx], sizeof(RANfunction_ItemIEs_t));
1954                               }
1955                            }
1956                            DU_FREE(ranFunctionsList->list.array, ranFunctionsList->list.size);
1957                         }
1958                         break;
1959                      }
1960
1961                      default:
1962                         DU_LOG("\nERROR  --> E2AP: Invalid event at e2SetupRequet %ld ",\
1963                               (e2SetupReq->protocolIEs.list.array[arrIdx]->id));
1964                         break;
1965                   }
1966                   DU_FREE(e2SetupReq->protocolIEs.list.array[arrIdx], sizeof(E2setupRequestIEs_t));
1967                }
1968             }
1969             DU_FREE(e2SetupReq->protocolIEs.list.array, e2SetupReq->protocolIEs.list.size);
1970          }
1971          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1972       }
1973       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1974    }
1975 }
1976
1977 /*******************************************************************
1978  *
1979  * @brief Builds and Send the E2SetupRequest
1980  *
1981  * @details
1982  *
1983  *    Function : BuildAndSendE2SetupReq
1984  *
1985  * Functionality:Fills the E2SetupRequest
1986  *
1987  * @return ROK     - success
1988  *         RFAILED - failure
1989  *
1990  ******************************************************************/
1991
1992 uint8_t BuildAndSendE2SetupReq()
1993 {
1994    uint8_t arrIdx = 0, elementCnt=0;
1995    uint8_t transId = 0, ret = RFAILED;
1996    bool memAllocFailed = false;
1997    E2AP_PDU_t        *e2apMsg = NULLP;
1998    E2setupRequest_t  *e2SetupReq = NULLP;
1999    asn_enc_rval_t     encRetVal;       /* Encoder return value */
2000
2001    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup Request\n");
2002    do
2003    {
2004       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2005       if(e2apMsg == NULLP)
2006       {
2007          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2008          break;
2009       }
2010       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
2011       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2012       if(e2apMsg->choice.initiatingMessage == NULLP)
2013       {
2014          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2015          break;
2016       }
2017       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2018       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2setup;
2019       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2setupRequest;
2020       e2SetupReq = &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest;
2021
2022       elementCnt = 4;
2023       e2SetupReq->protocolIEs.list.count = elementCnt;
2024       e2SetupReq->protocolIEs.list.size = elementCnt * sizeof(E2setupRequestIEs_t*);
2025
2026       /* Initialize the E2Setup members */
2027       DU_ALLOC(e2SetupReq->protocolIEs.list.array, \
2028             e2SetupReq->protocolIEs.list.size);
2029       if(e2SetupReq->protocolIEs.list.array == NULLP)
2030       {
2031          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
2032          break;
2033       }
2034       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
2035       {
2036          DU_ALLOC(e2SetupReq->protocolIEs.list.array[arrIdx],\
2037                sizeof(E2setupRequestIEs_t));
2038          if(e2SetupReq->protocolIEs.list.array[arrIdx] == NULLP)
2039          {
2040             memAllocFailed = true;
2041             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayarrIdx [%d]", arrIdx);
2042             break;
2043          }
2044       }
2045       if(memAllocFailed == true)
2046          break;
2047
2048       arrIdx = 0;
2049
2050       /* TransactionID */
2051       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2052       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2053       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
2054       transId = assignTransactionId();
2055       e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
2056
2057       arrIdx++;
2058       /* GlobalE2node_gNB_ID */
2059       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_GlobalE2node_ID;
2060       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2061       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_GlobalE2node_ID;
2062       e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.present = GlobalE2node_ID_PR_gNB;
2063
2064       DU_ALLOC(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.\
2065             GlobalE2node_ID.choice.gNB, sizeof(GlobalE2node_gNB_ID_t));
2066       if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.\
2067             GlobalE2node_ID.choice.gNB == NULLP)
2068       {
2069          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for gNbId");
2070          break;
2071       }
2072       else
2073       {
2074          ret = BuildGlobalgNBId(e2SetupReq->protocolIEs.list.array[arrIdx]->value.\
2075                choice.GlobalE2node_ID.choice.gNB);
2076          if(ret != ROK)
2077          {
2078              DU_LOG("\nERROR  -->  E2AP : Failed to build Global Gnb Id");
2079              break;
2080          }
2081       }
2082       
2083       /* RAN Functions Added List */
2084       arrIdx++;
2085       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAdded;
2086       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2087       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_RANfunctions_List;
2088       if(BuildRanFunctionAddList(&(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List), ProcedureCodeE2_id_E2setup, 0, NULL)!=ROK)      
2089       {
2090          DU_LOG("\nERROR  -->  E2AP : Failed to create RAN Function");
2091          break;
2092       }
2093
2094       /* E2 Node Component Configuration Addition List */
2095       arrIdx++;
2096       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition;
2097       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2098       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_E2nodeComponentConfigAddition_List;
2099       if(BuildE2NodeConfigAddList(&(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List), ProcedureCodeE2_id_E2setup, 0, NULL)!=ROK)
2100       {
2101          DU_LOG("\nERROR  -->  E2AP : Failed to create E2 Node config list");
2102          break;
2103       }
2104
2105
2106
2107       /* Prints the Msg formed */
2108       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2109
2110       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2111       encBufSize = 0;
2112       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
2113             encBuf);
2114       if(encRetVal.encoded == ENCODE_FAIL)
2115       {
2116          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupRequest structure (at %s)\n",\
2117                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2118          break;
2119       }
2120       else
2121       {
2122          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2SetupRequest\n");
2123 #ifdef DEBUG_ASN_PRINT
2124          for(int i=0; i< encBufSize; i++)
2125          {
2126             printf("%x",encBuf[i]);
2127          }
2128 #endif
2129       }
2130       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
2131       {
2132          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
2133       }
2134       break;
2135    }while(true);
2136
2137    duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
2138    duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
2139    
2140    FreeE2SetupReq(e2apMsg);
2141    return ret;
2142 }/* End of BuildAndSendE2SetupReq */
2143
2144 /*******************************************************************
2145  *
2146  * @brief Builds RIC Action Admitted List
2147  *
2148  * @details
2149  *
2150  *    Function : BuildRicActionAdmitList
2151  *
2152  *    Functionality: Builds RIC Action Admitted List
2153  *
2154  * @params[in] Pointer to RIC Action Admitted List to be filled
2155  *             Subscription Response information
2156  * @return ROK     - success
2157  *         RFAILED - failure
2158  *
2159  * ****************************************************************/
2160 uint8_t BuildRicActionAdmitList(RICaction_Admitted_List_t *admitList, PendingSubsRspInfo *subsRspInfo)
2161 {
2162    uint8_t idx = 0;
2163    uint8_t elementCnt = 0;  
2164    RICaction_Admitted_ItemIEs_t *admitItem = NULLP;
2165
2166    elementCnt = subsRspInfo->numOfAcceptedActions;
2167
2168    admitList->list.count = elementCnt;
2169    admitList->list.size  = elementCnt * sizeof(RICaction_Admitted_ItemIEs_t *);
2170
2171    DU_ALLOC(admitList->list.array, admitList->list.size);
2172    if(admitList->list.array == NULLP)
2173    {
2174       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2175       return RFAILED;
2176    }
2177
2178    for(idx=0; idx<elementCnt; idx++)
2179    {
2180       DU_ALLOC(admitList->list.array[idx], sizeof(RICaction_Admitted_ItemIEs_t));
2181       if(admitList->list.array[idx] == NULLP)
2182       {
2183          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2184          return RFAILED;
2185       }
2186
2187       admitItem = (RICaction_Admitted_ItemIEs_t *)admitList->list.array[idx];
2188       admitItem->id = ProtocolIE_IDE2_id_RICaction_Admitted_Item;
2189       admitItem->criticality = CriticalityE2_reject;
2190       admitItem->value.present = RICaction_Admitted_ItemIEs__value_PR_RICaction_Admitted_Item;
2191       admitItem->value.choice.RICaction_Admitted_Item.ricActionID = subsRspInfo->acceptedActionList[idx]; 
2192    }
2193    return ROK;
2194 }
2195
2196 /*******************************************************************
2197  *
2198  * @brief Builds RIC Action Not Admitted List
2199  *
2200  * @details
2201  *
2202  *    Function : BuildRicActionNotAdmitList
2203  *
2204  *    Functionality: Builds RIC Action Not Admitted List
2205  *
2206  * @params[in] Pointer to RIC Action Not Admitted List to be filled
2207  *             Subscription Response information
2208  * @return ROK     - success
2209  *         RFAILED - failure
2210  *
2211  * ****************************************************************/
2212 uint8_t BuildRicActionNotAdmitList(RICaction_NotAdmitted_List_t *notAdmitList, PendingSubsRspInfo *subsRspInfo)
2213 {
2214    uint8_t idx = 0;
2215    uint8_t elementCnt = 0;  
2216    RICaction_NotAdmitted_ItemIEs_t *notAdmitItem = NULLP;
2217
2218    elementCnt = subsRspInfo->numOfRejectedActions;
2219
2220    notAdmitList->list.count = elementCnt;
2221    notAdmitList->list.size  = elementCnt * sizeof(RICaction_NotAdmitted_ItemIEs_t *);
2222
2223    DU_ALLOC(notAdmitList->list.array, notAdmitList->list.size);
2224    if(notAdmitList->list.array == NULLP)
2225    {
2226       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2227       return RFAILED;
2228    }
2229
2230    for(idx=0; idx<elementCnt; idx++)
2231    {
2232       DU_ALLOC(notAdmitList->list.array[idx], sizeof(RICaction_NotAdmitted_ItemIEs_t));
2233       if(notAdmitList->list.array[idx] == NULLP)
2234       {
2235          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2236          return RFAILED;
2237       }
2238
2239       notAdmitItem = (RICaction_NotAdmitted_ItemIEs_t *)notAdmitList->list.array[idx];
2240       notAdmitItem->id = ProtocolIE_IDE2_id_RICaction_NotAdmitted_Item;
2241       notAdmitItem->criticality = CriticalityE2_reject;
2242       notAdmitItem->value.present = RICaction_NotAdmitted_ItemIEs__value_PR_RICaction_NotAdmitted_Item;
2243       notAdmitItem->value.choice.RICaction_NotAdmitted_Item.ricActionID = \
2244          subsRspInfo->rejectedActionList[idx].id; 
2245       fillE2Cause(&notAdmitItem->value.choice.RICaction_NotAdmitted_Item.cause, \
2246          subsRspInfo->rejectedActionList[idx].failureCause);
2247    }
2248    return ROK;
2249 }
2250
2251 /*******************************************************************
2252  *
2253  * @breif Deallocation of BuildAndSendRicSubscriptionRsp memory
2254  *
2255  * @details
2256  *
2257  *    Function : FreeRicSubscriptionRsp
2258  *
2259  * Functionality:Free the RicSubscriptionRsp
2260  *
2261  * @param[in] E2AP_PDU_t *e2apRicMsg
2262  *
2263  * @return void
2264  *      
2265  ******************************************************************/
2266 void FreeRicSubscriptionRsp(E2AP_PDU_t  *e2apRicMsg)
2267 {
2268    RICsubscriptionResponse_t  *ricSubscriptionRsp= NULLP;
2269    uint8_t idx=0;
2270    uint8_t listIdx=0;
2271    RICaction_Admitted_List_t *admitList = NULLP;
2272    RICaction_NotAdmitted_List_t *notAdmitList = NULLP;
2273
2274    if(e2apRicMsg != NULLP)
2275    {
2276       if(e2apRicMsg->choice.successfulOutcome != NULLP)
2277       {
2278          ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
2279          if(ricSubscriptionRsp)
2280          {
2281             if(ricSubscriptionRsp->protocolIEs.list.array != NULLP)
2282             {
2283                for(idx=0; idx<ricSubscriptionRsp->protocolIEs.list.count; idx++)
2284                {
2285                   if(ricSubscriptionRsp->protocolIEs.list.array[idx] != NULLP)
2286                   {
2287                      switch(ricSubscriptionRsp->protocolIEs.list.array[idx]->id)
2288                      {
2289                         case ProtocolIE_IDE2_id_RICactions_Admitted:
2290                            {
2291                               admitList = &ricSubscriptionRsp->protocolIEs.list.\
2292                                              array[idx]->value.choice.RICaction_Admitted_List;
2293                               if(admitList->list.array != NULLP)
2294                               {
2295                                  for(listIdx=0 ; listIdx < admitList->list.count; listIdx++)
2296                                  {
2297                                     DU_FREE(admitList->list.array[listIdx], sizeof(RICaction_Admitted_ItemIEs_t));
2298                                  }
2299                                  DU_FREE(admitList->list.array, admitList->list.size);   
2300                               }
2301                               break;
2302                            }
2303                         case ProtocolIE_IDE2_id_RICactions_NotAdmitted:
2304                            {
2305                               notAdmitList = &ricSubscriptionRsp->protocolIEs.list.\
2306                                              array[idx]->value.choice.RICaction_NotAdmitted_List;
2307                               if(notAdmitList->list.array != NULLP)
2308                               {
2309                                  for(listIdx=0 ; listIdx < notAdmitList->list.count; listIdx++)
2310                                  {
2311                                     DU_FREE(notAdmitList->list.array[listIdx], sizeof(RICaction_NotAdmitted_ItemIEs_t));
2312                                  }
2313                                  DU_FREE(notAdmitList->list.array, notAdmitList->list.size);     
2314                               }
2315                               break;
2316                            }
2317                         default:
2318                            break;
2319                      }
2320                      DU_FREE(ricSubscriptionRsp->protocolIEs.list.array[idx], sizeof(RICsubscriptionResponse_IEs_t));
2321                   }
2322                }
2323                DU_FREE(ricSubscriptionRsp->protocolIEs.list.array, ricSubscriptionRsp->protocolIEs.list.size);
2324             }
2325          }   
2326          DU_FREE(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2327       }         
2328       DU_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));        
2329    }
2330 }
2331
2332 /*******************************************************************
2333  *
2334  * @brief Fill RIC Subscription Response IEs
2335  *
2336  * @details
2337  *
2338  *    Function : fillRicSubscriptionRsp
2339  *
2340  * functionality: Fill RIC Subscription Response IEs
2341  *
2342  * @param  Pointer to RIC subscription response
2343  *         Subscription response information
2344  * @return ROK     - success
2345  *         RFAILED - failure
2346  *
2347  ******************************************************************/
2348 uint8_t fillRicSubscriptionRsp(RICsubscriptionResponse_t *ricSubscriptionRsp, PendingSubsRspInfo *subsRspInfo)
2349 {
2350    uint8_t ieIdx = 0;
2351    uint8_t elementCnt = 0;
2352    RICsubscriptionResponse_IEs_t *subsRspIe = NULLP;
2353
2354    elementCnt = 3;
2355    if(subsRspInfo->numOfRejectedActions)
2356       elementCnt++;
2357
2358    ricSubscriptionRsp->protocolIEs.list.count = elementCnt;
2359    ricSubscriptionRsp->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionResponse_IEs_t);
2360    DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array, ricSubscriptionRsp->protocolIEs.list.size);
2361    if(ricSubscriptionRsp->protocolIEs.list.array == NULLP)
2362    {
2363       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at %s : line %d", __func__, __LINE__);
2364       return RFAILED;
2365    }
2366
2367    for(ieIdx=0; ieIdx<ricSubscriptionRsp->protocolIEs.list.count; ieIdx++)
2368    {
2369       DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionResponse_IEs_t));
2370       if(ricSubscriptionRsp->protocolIEs.list.array[ieIdx] == NULLP)
2371       {
2372          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d] : ieIdx [%d]", __func__, __LINE__,ieIdx);
2373          return RFAILED;
2374       }
2375    }
2376
2377    /* RIC Request ID */
2378    ieIdx=0;
2379    subsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
2380    subsRspIe->id = ProtocolIE_IDE2_id_RICrequestID;
2381    subsRspIe->criticality = CriticalityE2_reject;
2382    subsRspIe->value.present = RICsubscriptionRequest_IEs__value_PR_RICrequestID;
2383    subsRspIe->value.choice.RICrequestID.ricRequestorID = subsRspInfo->requestId.requestorId;
2384    subsRspIe->value.choice.RICrequestID.ricInstanceID = subsRspInfo->requestId.instanceId;
2385
2386    /* RAN Function ID */
2387    ieIdx++;
2388    subsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
2389    subsRspIe->id = ProtocolIE_IDE2_id_RANfunctionID;
2390    subsRspIe->criticality = CriticalityE2_reject;
2391    subsRspIe->value.present = RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
2392    subsRspIe->value.choice.RANfunctionID = subsRspInfo->ranFuncId;
2393
2394    /* RIC Action Admitted List */
2395    ieIdx++;
2396    subsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
2397    subsRspIe->id = ProtocolIE_IDE2_id_RICactions_Admitted;
2398    subsRspIe->criticality = CriticalityE2_reject;
2399    subsRspIe->value.present = RICsubscriptionResponse_IEs__value_PR_RICaction_Admitted_List;
2400    if(BuildRicActionAdmitList(&subsRspIe->value.choice.RICaction_Admitted_List, subsRspInfo) != ROK)
2401    {
2402       DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Action Admitted List in RIC Subscription Response");
2403       return RFAILED;
2404    }
2405
2406    /* RIC Action Not Admitted List */
2407    if(subsRspInfo->numOfRejectedActions)
2408    {
2409       ieIdx++;
2410       subsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
2411       subsRspIe->id = ProtocolIE_IDE2_id_RICactions_NotAdmitted;
2412       subsRspIe->criticality = CriticalityE2_reject;
2413       subsRspIe->criticality = CriticalityE2_reject;
2414       subsRspIe->value.present = RICsubscriptionResponse_IEs__value_PR_RICaction_NotAdmitted_List;
2415       if(BuildRicActionNotAdmitList(&subsRspIe->value.choice.RICaction_NotAdmitted_List, subsRspInfo) != ROK)
2416       {
2417          DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Action Not Admitted List in RIC Subscription Response");
2418          return RFAILED;
2419       }
2420    }
2421
2422    return ROK;
2423 }
2424
2425 /*******************************************************************
2426  *
2427  * @brief Builds and Send the RicSubscriptionRsp
2428  *
2429  * @details
2430  *
2431  *    Function : BuildAndSendRicSubscriptionRsp
2432  *
2433  * Functionality:Fills the RicSubscriptionRsp
2434  *
2435  * @return ROK     - success
2436  *         RFAILED - failure
2437  *
2438  ******************************************************************/
2439
2440 uint8_t BuildAndSendRicSubscriptionRsp(PendingSubsRspInfo *subsRspInfo)
2441 {
2442    uint8_t      ret = RFAILED;
2443    E2AP_PDU_t   *e2apRicMsg = NULLP;
2444    RICsubscriptionResponse_t  *ricSubscriptionRsp=NULLP;
2445    asn_enc_rval_t encRetVal; 
2446
2447    while(true)
2448    {
2449       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Response\n");
2450
2451       DU_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t)); 
2452       if(e2apRicMsg == NULLP)
2453       {
2454          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2455          break;
2456       }
2457
2458       e2apRicMsg->present =  E2AP_PDU_PR_successfulOutcome;
2459       DU_ALLOC(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2460       if(e2apRicMsg->choice.successfulOutcome == NULLP)
2461       {
2462          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC subscription Response failed");
2463          break;
2464       }
2465
2466       e2apRicMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
2467       e2apRicMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
2468       e2apRicMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse;
2469
2470       ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
2471
2472       if(fillRicSubscriptionRsp(ricSubscriptionRsp, subsRspInfo) != ROK)
2473       {
2474          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICsubscriptionResponseIE failed");
2475          break;
2476       }
2477
2478       /* Prints the Msg formed */
2479       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
2480
2481       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2482       encBufSize = 0;
2483       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf, encBuf);
2484       if(encRetVal.encoded == ENCODE_FAIL)
2485       {
2486          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Response structure (at %s)\n",\
2487                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2488          break;
2489       }
2490       else
2491       {
2492          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RIC subscription response \n");
2493 #ifdef DEBUG_ASN_PRINT
2494          for(int i=0; i< encBufSize; i++)
2495          {
2496             printf("%x",encBuf[i]);
2497          } 
2498 #endif
2499       } 
2500
2501       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
2502       {
2503          DU_LOG("\nERROR  -->  E2AP : Sending RIC Subscription Response failed");      
2504          break;
2505       }
2506
2507       ret = ROK;
2508       break;
2509
2510    }
2511
2512    FreeRicSubscriptionRsp(e2apRicMsg);
2513    return ret;
2514 }
2515
2516 /******************************************************************
2517  *
2518  * @brief Deallocation of memory allocated by aper decoder for e2 setup response
2519  *
2520  * @details
2521  *
2522  *    Function : freeAperDecodingOfE2SetupRsp
2523  *
2524  *    Functionality: Deallocation of memory allocated by aper decoder for e2
2525  *    setup response
2526  *
2527  * @params[in] E2setupResponse_t *e2SetRspMsg;
2528  * @return void
2529  *
2530  * ****************************************************************/
2531 void freeAperDecodingOfE2SetupRsp(E2setupResponse_t *e2SetRspMsg)
2532 {
2533    uint8_t arrIdx, e2NodeConfigAddAckListIdx;
2534    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem;
2535    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAddAckList;
2536
2537    if(e2SetRspMsg)
2538    {
2539       if(e2SetRspMsg->protocolIEs.list.array)
2540       {
2541          for(arrIdx=0; arrIdx<e2SetRspMsg->protocolIEs.list.count; arrIdx++)
2542          {
2543             if(e2SetRspMsg->protocolIEs.list.array[arrIdx])
2544             {
2545                switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
2546                {
2547                   case ProtocolIE_IDE2_id_TransactionID:
2548                      break;
2549
2550                   case ProtocolIE_IDE2_id_GlobalRIC_ID:
2551                      {
2552                         free(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.pLMN_Identity.buf);
2553                         free(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID.buf);
2554                         break;
2555                      }
2556
2557                   case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
2558                      {
2559                         e2NodeConfigAddAckList = &e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
2560                         if(e2NodeConfigAddAckList->list.array )
2561                         {
2562                            for(e2NodeConfigAddAckListIdx = 0; e2NodeConfigAddAckListIdx< e2NodeConfigAddAckList->list.count; e2NodeConfigAddAckListIdx++)
2563                            {
2564                               if(e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx])
2565                               {
2566                                  e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx];
2567                                  free(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.\
2568                                        e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf);
2569                                  free(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.\
2570                                        e2nodeComponentInterfaceTypeF1);
2571                                  free(e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx]);
2572                               }
2573                            }
2574                            free(e2NodeConfigAddAckList->list.array);
2575                         }
2576                         break;
2577                      }
2578                }
2579                free(e2SetRspMsg->protocolIEs.list.array[arrIdx]);  
2580             }
2581          }
2582          free(e2SetRspMsg->protocolIEs.list.array);
2583       }
2584    }
2585 }
2586
2587 /******************************************************************
2588  *
2589  * @brief handling of e2 noe config update ack ies
2590  *
2591  * @details
2592  *
2593  *    Function :handleE2NodeConfigUpdateAckIes 
2594  *
2595  *    Functionality: handling of e2 noe config update ack ies
2596  *
2597  * @params[in] 
2598  *    Pointer to the E2 Node cfg
2599  *    Procedure code
2600  * @return void
2601 ******************************************************************/
2602
2603 void handleE2NodeConfigUpdateAckIes(PTR e2NodeCfg, uint8_t procedureCode)
2604 {
2605    CmLList         *node=NULLP;
2606    E2NodeComponent *e2NodeComponentInfo=NULLP;
2607    E2nodeComponentID_t *e2nodeComponentID=NULLP;
2608    E2nodeComponentConfigRemovalAck_Item_t *removalAckItem=NULLP;
2609    E2nodeComponentConfigUpdateAck_Item_t *updateAckItem=NULLP;
2610    E2nodeComponentConfigAdditionAck_Item_t *additionAckItem=NULLP;
2611
2612    switch(procedureCode)
2613    {
2614       case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
2615          {
2616             additionAckItem = (E2nodeComponentConfigAdditionAck_Item_t *)e2NodeCfg;
2617             e2nodeComponentID = &additionAckItem->e2nodeComponentID;
2618             break;
2619          }
2620       case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
2621          {
2622             updateAckItem = (E2nodeComponentConfigUpdateAck_Item_t*) e2NodeCfg;
2623             e2nodeComponentID = &updateAckItem->e2nodeComponentID;
2624             break;
2625          }
2626       case  ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
2627          {
2628             removalAckItem= (E2nodeComponentConfigRemovalAck_Item_t*)e2NodeCfg;
2629             e2nodeComponentID = &removalAckItem->e2nodeComponentID;
2630             break;
2631          }
2632    }
2633
2634    switch(e2nodeComponentID->present)
2635    {
2636       case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
2637          {
2638             e2NodeComponentInfo = fetchE2NodeComponentInfo(F1, e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0], &node);
2639             if(!e2NodeComponentInfo)
2640             {
2641                DU_LOG("\nERROR  --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__);
2642                return;
2643             }
2644             break;
2645          }
2646       default:
2647          break;
2648    }
2649    
2650    switch(procedureCode)
2651    {
2652       case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
2653          {
2654             DU_FREE(e2NodeComponentInfo->addConfiguration->componentRequestPart, e2NodeComponentInfo->addConfiguration->reqBufSize);
2655             DU_FREE(e2NodeComponentInfo->addConfiguration->componentResponsePart, e2NodeComponentInfo->addConfiguration->rspBufSize);
2656             DU_FREE(e2NodeComponentInfo->addConfiguration, sizeof(E2NodeConfig));
2657             break;
2658          }
2659       case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
2660          {
2661             DU_FREE(e2NodeComponentInfo->updateConfiguration->componentRequestPart, e2NodeComponentInfo->updateConfiguration->reqBufSize);
2662             DU_FREE(e2NodeComponentInfo->updateConfiguration->componentResponsePart, e2NodeComponentInfo->updateConfiguration->rspBufSize);
2663             DU_FREE(e2NodeComponentInfo->updateConfiguration, sizeof(E2NodeConfig));
2664             break;
2665          }
2666       case  ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
2667          {
2668             cmLListDelFrm(&duCb.e2apDb.e2NodeComponentList, node);
2669             if(e2NodeComponentInfo->addConfiguration)
2670             {
2671                DU_FREE(e2NodeComponentInfo->addConfiguration->componentRequestPart, e2NodeComponentInfo->addConfiguration->reqBufSize);
2672                DU_FREE(e2NodeComponentInfo->addConfiguration->componentResponsePart, e2NodeComponentInfo->addConfiguration->rspBufSize);
2673                DU_FREE(e2NodeComponentInfo->addConfiguration, sizeof(E2NodeConfig));
2674             }
2675             if(e2NodeComponentInfo->updateConfiguration)
2676             {
2677                DU_FREE(e2NodeComponentInfo->updateConfiguration->componentRequestPart, e2NodeComponentInfo->updateConfiguration->reqBufSize);
2678                DU_FREE(e2NodeComponentInfo->updateConfiguration->componentResponsePart, e2NodeComponentInfo->updateConfiguration->rspBufSize);
2679                DU_FREE(e2NodeComponentInfo->updateConfiguration, sizeof(E2NodeConfig));
2680             }
2681             DU_FREE(node, sizeof(CmLList));
2682             break;
2683          }
2684    }
2685 }
2686
2687 /******************************************************************
2688  *
2689  * @brief Processes E2 Setup Response sent by RIC
2690  *
2691  * @details
2692  *
2693  *    Function : procE2SetupRsp
2694  *
2695  *    Functionality: Processes E2 Setup Response sent by RIC
2696  *
2697  * @params[in] E2AP_PDU_t ASN decoded E2AP message
2698  * @return void
2699  *
2700  * ****************************************************************/
2701
2702 void procE2SetupRsp(E2AP_PDU_t *e2apMsg)
2703 {
2704    bool invalidTransId = false;
2705    uint8_t arrIdx =0, transId=0, idx=0; 
2706    uint32_t recvBufLen;             
2707    E2setupResponse_t *e2SetRspMsg=NULL;
2708    E2nodeComponentConfigAdditionAck_List_t *e2NodeCfgAckList=NULL;
2709    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem=NULL;
2710
2711    DU_LOG("\nINFO   -->  E2AP : E2 Setup Response received"); 
2712    duCb.e2Status = TRUE; //Set E2 status as true
2713    e2SetRspMsg = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
2714
2715    for(arrIdx=0; arrIdx<e2SetRspMsg->protocolIEs.list.count; arrIdx++)
2716    {
2717       switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
2718       {
2719          case ProtocolIE_IDE2_id_TransactionID:
2720             {
2721                transId = e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
2722                if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
2723                      (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
2724                {
2725                   memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
2726                }
2727                else
2728                {
2729                   DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
2730                   invalidTransId = true;
2731                }
2732                break;
2733             }
2734
2735          case ProtocolIE_IDE2_id_GlobalRIC_ID:
2736             {
2737                /* To store the Ric Id Params */
2738                recvBufLen = sizeof(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value\
2739                      .choice.GlobalRIC_ID.pLMN_Identity.size);
2740                memcpy(&duCb.e2apDb.ricId.plmnId, e2SetRspMsg->protocolIEs.list.array[arrIdx]\
2741                      ->value.choice.GlobalRIC_ID.pLMN_Identity.buf, recvBufLen);
2742                bitStringToInt(&e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID, &duCb.e2apDb.ricId);
2743                /*TODO : duCb.e2apDb.ricId.plmnId memory to be deallocated after the usage */
2744                break;
2745             }
2746
2747          case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
2748             {
2749                e2NodeCfgAckList = &e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
2750                for(idx =0; idx <e2NodeCfgAckList->list.count; idx++)
2751                {
2752                   e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeCfgAckList->list.array[idx];
2753                   handleE2NodeConfigUpdateAckIes((PTR)&e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item,\
2754                   ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck);
2755                }
2756                break;
2757             }
2758
2759          default:
2760             {
2761                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2SetupRsp:%ld",
2762                      e2SetRspMsg->protocolIEs.list.array[arrIdx]->id);
2763                break;
2764             }
2765       }
2766
2767       if(invalidTransId == true)
2768       {
2769          break;
2770       }
2771    }
2772    freeAperDecodingOfE2SetupRsp(e2SetRspMsg);
2773
2774    if(invalidTransId == false)
2775    {
2776       if(duSendE2NodeConfigurationUpdate() != ROK)
2777       {
2778          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 node config update");
2779       }
2780    }
2781 }
2782
2783 /*******************************************************************
2784  *
2785  * @brief Free RIC Subscription Request
2786  *
2787  * @details
2788  *
2789  *    Function : freeAperDecodingOfRicSubsReq
2790  *
2791  * Functionality : Free RIC Subscription Request
2792  *
2793  * @return void
2794  *
2795  ******************************************************************/
2796 void freeAperDecodingOfRicSubsReq(RICsubscriptionRequest_t *ricSubscriptionReq)
2797 {
2798    uint8_t idx = 0;
2799    uint8_t elementIdx = 0;
2800    RICsubscriptionDetails_t *subsDetails = NULLP;
2801    RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
2802
2803    if(ricSubscriptionReq->protocolIEs.list.array)
2804    {
2805       for(idx=0; idx < ricSubscriptionReq->protocolIEs.list.count; idx++)
2806       {
2807          switch(ricSubscriptionReq->protocolIEs.list.array[idx]->id)
2808          {
2809             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
2810                {
2811                   subsDetails = &(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails);
2812                   free(subsDetails->ricEventTriggerDefinition.buf);
2813
2814                   if(subsDetails->ricAction_ToBeSetup_List.list.array)
2815                   {
2816                      for(elementIdx = 0; elementIdx < subsDetails->ricAction_ToBeSetup_List.list.count; elementIdx++)
2817                      {
2818                         if(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
2819                         {
2820                            actionItem = (RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx];
2821                            if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
2822                            {
2823                               free(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf);
2824                               free(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition);
2825                            }
2826                            free(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx]);
2827                         }
2828                      }
2829                      free(subsDetails->ricAction_ToBeSetup_List.list.array);
2830                   }
2831                   break;
2832                }
2833          }
2834          free(ricSubscriptionReq->protocolIEs.list.array[idx]);
2835       }
2836       free(ricSubscriptionReq->protocolIEs.list.array);
2837    }
2838 }
2839
2840 /*******************************************************************
2841  *
2842  * @brief Free Event Trigger Definition
2843  *
2844  * @details
2845  *
2846  *    Function : freeAperDecodingOfEventTriggerDef
2847  *
2848  *    Functionality: Free Event Trigger Definition
2849  *
2850  * @params[in] E2SM-KPM Event Trigger Definition
2851  * @return void
2852  *
2853  * ****************************************************************/
2854 void  freeAperDecodingOfEventTriggerDef(E2SM_KPM_EventTriggerDefinition_t *eventTiggerDef)
2855 {
2856    if(eventTiggerDef)
2857    {
2858       switch(eventTiggerDef->eventDefinition_formats.present)
2859       {
2860          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING:
2861             break;
2862
2863          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1:
2864             free(eventTiggerDef->eventDefinition_formats.choice.eventDefinition_Format1);
2865             break;
2866       }
2867    }
2868 }
2869
2870 /*******************************************************************
2871  *
2872  * @brief Extract E2SM-KPM Event trigger definition
2873  *
2874  * @details
2875  *
2876  *    Function : extractEventTriggerDef
2877  *
2878  * Functionality : This function :
2879  *     - Decodes E2SM-KPM Event Trigger Definition
2880  *     - Validates that even trigger style is supported by E2 node
2881  *     - Stores event trigger details in local DB
2882  *
2883  * @params[in] RAN Function Database structure
2884  *             RIC Subscription Info to be added to RAN function
2885  *             RIC Event Trigger Definition buffer received from RIC
2886  * @return ROK     - success
2887  *         RFAILED - failure
2888  *
2889  ******************************************************************/
2890 uint8_t extractEventTriggerDef(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \
2891    RICeventTriggerDefinition_t *ricEventTriggerDef, E2FailureCause *failureCause)
2892 {
2893    uint8_t ret = RFAILED;
2894    uint8_t eventIdx = 0;
2895    asn_dec_rval_t rval ={0};
2896    E2SM_KPM_EventTriggerDefinition_t eventTiggerDef, *eventTiggerDefPtr = NULLP;
2897
2898    /* Decoding E2SM-KPM Even Trigger Definition */
2899    eventTiggerDefPtr = &eventTiggerDef;
2900    memset(eventTiggerDefPtr, 0, sizeof(E2SM_KPM_EventTriggerDefinition_t));
2901
2902    rval = aper_decode(0, &asn_DEF_E2SM_KPM_EventTriggerDefinition, (void **)&eventTiggerDefPtr, ricEventTriggerDef->buf,\
2903          ricEventTriggerDef->size, 0, 0);
2904    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
2905    {
2906       DU_LOG("\nERROR  -->  E2AP : ASN decode failed for E2SM-KPM Event Trigger Definition");
2907       failureCause->causeType = E2_PROTOCOL; 
2908       failureCause->cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE;
2909       return RFAILED;
2910    }
2911    printf("\n");
2912    xer_fprint(stdout, &asn_DEF_E2SM_KPM_EventTriggerDefinition, eventTiggerDefPtr);
2913
2914    /* Validating the received event trigger definition format */
2915    for(eventIdx = 0; eventIdx < ranFuncDb->numOfEventTriggerStyleSupported; eventIdx++)
2916    {
2917       if((eventTiggerDefPtr->eventDefinition_formats.present != \
2918          E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING) && \
2919          (eventTiggerDefPtr->eventDefinition_formats.present == ranFuncDb->eventTriggerStyleList[eventIdx].formatType))
2920       {
2921          ricSubscriptionInfo->eventTriggerDefinition.formatType = ranFuncDb->eventTriggerStyleList[eventIdx].formatType;
2922          ricSubscriptionInfo->eventTriggerDefinition.choice.format1.reportingPeriod = \
2923             eventTiggerDefPtr->eventDefinition_formats.choice.eventDefinition_Format1->reportingPeriod;
2924
2925          ret = ROK;
2926          break;
2927       }
2928    }
2929
2930    if(ret == RFAILED)
2931    {
2932       failureCause->causeType = E2_RIC_REQUEST;
2933       failureCause->cause = E2_EVENT_TRIGGER_NOT_SUPPORTED;
2934    }
2935    /* Free E2SM_KPM_EventTriggerDefinition_t */
2936    freeAperDecodingOfEventTriggerDef(eventTiggerDefPtr);
2937    return ret;
2938 }
2939
2940 /*******************************************************************
2941  *
2942  * @brief Free RIC Action Definition
2943  *
2944  * @details
2945  *
2946  *    Function :  freeAperDecodingOfRicActionDefinition
2947  *
2948  *    Functionality: Free RIC Action Definition
2949  *
2950  * @params[in] E2SM-KPM Action definition
2951  * @return void
2952  *
2953  * ****************************************************************/
2954 void  freeAperDecodingOfRicActionDefinition(E2SM_KPM_ActionDefinition_t *actionDef)
2955 {
2956    uint8_t  elementIdx = 0;
2957    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
2958    MeasurementInfoItem_t *measItem = NULLP;
2959
2960    switch(actionDef->actionDefinition_formats.present)
2961    {
2962       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
2963          {
2964             if(actionDef->actionDefinition_formats.choice.actionDefinition_Format1)
2965             {
2966                actionFormat1 = actionDef->actionDefinition_formats.choice.actionDefinition_Format1;
2967                if(actionFormat1->measInfoList.list.array)
2968                {
2969                   for(elementIdx = 0; elementIdx < actionFormat1->measInfoList.list.count; elementIdx++)
2970                   {
2971                      if(actionFormat1->measInfoList.list.array[elementIdx])
2972                      {
2973                         measItem = actionFormat1->measInfoList.list.array[elementIdx];
2974                         switch(measItem->measType.present)
2975                         {
2976                            case MeasurementType_PR_NOTHING:
2977                               break;
2978
2979                            case MeasurementType_PR_measName:
2980                            {
2981                               free(measItem->measType.choice.measName.buf);
2982                               break;
2983                            }
2984
2985                            case MeasurementType_PR_measID:
2986                               break;
2987                         }
2988                         free(measItem);
2989                      }
2990                   }
2991                   free(actionFormat1->measInfoList.list.array);
2992                }
2993                free(actionFormat1);
2994             }
2995             break;
2996          }
2997       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format2:
2998       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format3:
2999       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format4:
3000       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format5:
3001       default:
3002          break;   
3003    }
3004 }
3005
3006 /*******************************************************************
3007  *
3008  * @brief Extract Measurement Info list from action definition
3009  *
3010  * @details
3011  *
3012  *    Function : extractMeasInfoList
3013  *
3014  * Functionality : This function :
3015  *     - Traverses Measurement-to-be-subscribed list
3016  *     - Validates that each measurement in Measurement-to-be-subscribed
3017  *       list is supported in RAN-Function->Measurement-supported list.
3018  *     - If all measurements in an action is supported by RAN function,
3019  *       it is added to measurement-subscribed list in local DB
3020  *
3021  * @params[in] Measurement Info supported list by RAN function
3022  *             Measurement Info to be subscribed as requested by RIC
3023  *             Measurement Info finally subscribed
3024  *             Memory failure indicator
3025  * @return ROK     - success
3026  *         RFAILED - failure
3027  *
3028  ******************************************************************/
3029 uint8_t extractMeasInfoList(CmLListCp *measInfoSupportedList, MeasurementInfoList_t *measInfoToBeSubscribedList, \
3030    CmLListCp *measInfoSubscribedList, bool *memFailure)
3031 {
3032    uint8_t elementIdx = 0;
3033    MeasurementInfoForAction *measInfoSupportedDb = NULLP;
3034    MeasurementInfo *measInfoSubscribedDb = NULLP;
3035    CmLList *supportedMeasNode = NULLP, *measToAddNode = NULLP;
3036    MeasurementInfoItem_t *measItem = NULLP;
3037
3038    /* Validate Measurement list is supported by E2 node. 
3039     *
3040     * Traverse and compare the Measurement-Supported List in E2
3041     * node with Measurement-to-be-subscribed list received from RIC.
3042     * If a match is found, add it to measurement-subscription list.
3043     */
3044    for(elementIdx = 0; elementIdx < measInfoToBeSubscribedList->list.count; elementIdx++)
3045    {
3046       measInfoSubscribedDb = NULLP;
3047       measToAddNode = NULLP;
3048       measItem = measInfoToBeSubscribedList->list.array[elementIdx];
3049
3050       CM_LLIST_FIRST_NODE(measInfoSupportedList, supportedMeasNode);
3051       while(supportedMeasNode)
3052       {
3053          measInfoSupportedDb = (MeasurementInfoForAction*)supportedMeasNode->node;
3054          switch(measItem->measType.present)
3055          {
3056             case MeasurementType_PR_measName:
3057                {
3058                   if(!strcmp(measInfoSupportedDb->measurementTypeName, (char *)measItem->measType.choice.measName.buf))
3059                   {
3060                      DU_ALLOC(measInfoSubscribedDb, sizeof(MeasurementInfo));
3061                   }
3062                   break;
3063                }
3064
3065             case MeasurementType_PR_measID:
3066                {
3067                   if(measInfoSupportedDb->measurementTypeId == measItem->measType.choice.measID)
3068                   {
3069                      DU_ALLOC(measInfoSubscribedDb, sizeof(MeasurementInfo));
3070                   }
3071                   break;
3072                }
3073
3074             default:
3075                {
3076                   DU_LOG("\nERROR  ->  DUAPP: Invalid Measurement-type identifier in \
3077                         E2SM-KPM Action Definition Format");
3078                   break;
3079                }
3080          } /* End of switch, for measurement type identifier */
3081
3082          /* If measurement type is supported, add to measurement-subscription list */
3083          if(measInfoSubscribedDb)
3084          {
3085             measInfoSubscribedDb->measurementTypeId = measInfoSupportedDb->measurementTypeId;
3086             memcpy(measInfoSubscribedDb->measurementTypeName, measInfoSupportedDb->measurementTypeName, \
3087                   strlen(measInfoSupportedDb->measurementTypeName));
3088
3089             DU_ALLOC(measToAddNode, sizeof(CmLList));
3090             if(measToAddNode)
3091             {
3092                measToAddNode->node = (PTR) measInfoSubscribedDb;
3093                cmLListAdd2Tail(measInfoSubscribedList, measToAddNode);
3094
3095                /* Break out of while loop if measurement info is found in measurement-supported list  */
3096                break;
3097             }
3098             else
3099             {
3100                DU_FREE(measInfoSubscribedDb, sizeof(MeasurementInfo));
3101                measInfoSubscribedDb = NULLP;
3102                *memFailure = true;
3103                break;
3104             }
3105          }
3106
3107          supportedMeasNode = supportedMeasNode->next;  
3108
3109       } /* End of while for traversing measurement-supported list in a report style */
3110
3111       /* If a measurement-to-be-subscribed is not found in measurement-supported list in this report style
3112        * Then :
3113        * Delete all entries from measurement-subscription list and
3114        * Break out of for loop to search in next report style */
3115       if(!measInfoSubscribedDb)
3116       {
3117          deleteMeasurementInfoList(measInfoSubscribedList);
3118          break;
3119       }
3120
3121    } /* End of for loop , traversing measurement-to-be-subscribed list */
3122
3123    /* If all measurement-to-be-subscribed was found in measurement-supported list and 
3124     * was added to measurement-subscription list successfully, return from here */
3125    if(measInfoToBeSubscribedList->list.count == measInfoSubscribedList->count)
3126       return ROK;
3127
3128    return RFAILED;
3129 }
3130
3131 /*******************************************************************
3132  *
3133  * @brief Extract E2SM-KPM Action definition
3134  *
3135  * @details
3136  *
3137  *    Function : extractRicActionDef
3138  *
3139  * Functionality : This function :
3140  *     - Decodes E2SM-KPM Action Definition
3141  *     - Validates that action is supported by E2 node
3142  *     - Stores action details in local DB
3143  *
3144  * @params[in] RAN Function Database structure
3145  *             RIC subscription's Action definition to be added to 
3146  *                RAN function
3147  *             RIC Action Definition buffer received from RIC
3148  * @return ROK     - success
3149  *         RFAILED - failure
3150  *
3151  ******************************************************************/
3152 uint8_t extractRicActionDef(RanFunction *ranFuncDb, ActionDefinition *actionDefDb, RICactionDefinition_t *ricActionDef,\
3153    E2FailureCause *failureCause)
3154 {
3155    bool memFailure = false;
3156    uint8_t styleIdx = 0;
3157    asn_dec_rval_t rval ={0};
3158
3159    E2SM_KPM_ActionDefinition_t actionDef, *actionDefPtr = NULLP;
3160    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
3161    CmLListCp *measInfoSupportedList = NULLP;
3162    CmLListCp *measInfoSubscribedList = NULLP;
3163
3164    /* Decoding E2SM-KPM Action Definition */
3165    actionDefPtr = &actionDef;
3166    memset(actionDefPtr, 0, sizeof(E2SM_KPM_EventTriggerDefinition_t));
3167
3168    rval = aper_decode(0, &asn_DEF_E2SM_KPM_ActionDefinition, (void **)&actionDefPtr, ricActionDef->buf,\
3169          ricActionDef->size, 0, 0);
3170    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
3171    {
3172       DU_LOG("\nERROR  -->  E2AP : ASN decode failed for E2SM-KPM Action Definition");
3173       failureCause->causeType = E2_PROTOCOL;
3174       failureCause->cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE;
3175       return RFAILED;
3176    }
3177    printf("\n");
3178    xer_fprint(stdout, &asn_DEF_E2SM_KPM_ActionDefinition, actionDefPtr);
3179
3180
3181    /* Validate if Report style to subscribe is supported by E2 Node */
3182    for(styleIdx= 0; styleIdx < ranFuncDb->numOfReportStyleSupported; styleIdx++)
3183    {
3184       /* Validate Report style type and report style format type is supported by E2 Node */
3185       if((ranFuncDb->reportStyleList[styleIdx].reportStyle.styleType == actionDefPtr->ric_Style_Type) &&
3186             (ranFuncDb->reportStyleList[styleIdx].reportStyle.formatType == actionDefPtr->actionDefinition_formats.present))
3187       {
3188          /* Fetch Report stype type and format type */
3189          actionDefDb->styleType = actionDefPtr->ric_Style_Type;
3190          actionDefDb->formatType = actionDefPtr->actionDefinition_formats.present;
3191
3192          switch(actionDefPtr->actionDefinition_formats.present)
3193          {
3194             case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
3195                {
3196                   actionFormat1 = actionDefPtr->actionDefinition_formats.choice.actionDefinition_Format1; 
3197
3198                   /* Fetch granularity period */
3199                   actionDefDb->choice.format1.granularityPeriod = actionFormat1->granulPeriod;
3200
3201                   /* Validate and add the Measurement to subscription list */
3202                   measInfoSupportedList = &ranFuncDb->reportStyleList[styleIdx].measurementInfoList;
3203                   measInfoSubscribedList = &actionDefDb->choice.format1.measurementInfoList;
3204                   if(extractMeasInfoList(measInfoSupportedList, &actionFormat1->measInfoList, \
3205                      measInfoSubscribedList, &memFailure) == ROK)
3206                   {
3207                      if(!memFailure)
3208                      {
3209                         /* Free E2SM_KPM_ActionDefinition_t */
3210                         freeAperDecodingOfRicActionDefinition(actionDefPtr);
3211                         return ROK;
3212                      }
3213                   }
3214
3215                   break;  /* End of E2SM-KPM Action definition format 1 case */
3216                }
3217
3218             default :
3219                {
3220                   DU_LOG("\nERROR  ->  DUAPP: Only E2SM-KPM Action Definition Format 1 is supported");
3221                   break;
3222                }
3223          } /* End of switch for E2SM-KPM Action definition formats */
3224       }
3225
3226       if(memFailure)
3227       {
3228          failureCause->causeType = E2_MISCELLANEOUS;
3229          failureCause->cause = E2_MISCELLANEOUS_CAUSE_UNSPECIFIED; 
3230          break;
3231       }
3232    } /* End of for loop, traversing Report-styles-supported list in E2 node */
3233
3234    /* Memset action Db and Free E2SM_KPM_ActionDefinition_t */
3235    memset(actionDefDb, 0, sizeof(ActionDefinition));
3236    freeAperDecodingOfRicActionDefinition(actionDefPtr);
3237
3238    if(failureCause->causeType == E2_NOTHING)
3239    {
3240       failureCause->causeType = E2_RIC_REQUEST;
3241       failureCause->cause = E2_ACTION_NOT_SUPPORTED;
3242    }
3243    return RFAILED;
3244 }
3245
3246 /*******************************************************************
3247  *
3248  * @brief Extract RIC Action to be setup
3249  *
3250  * @details
3251  *
3252  *    Function : extractRicActionToBeSetup
3253  *
3254  * Functionality : This function :
3255  *     - Validates that each action-to-be-setup is supported by E2 node
3256  *     - Stores event trigger details in local DB
3257  *
3258  * @params[in] RAN Function Database structure
3259  *             RIC Subscription Info to be added to RAN function
3260  *             RIC Action To Be Setup List received from RIC
3261  * @return ROK     - success
3262  *         RFAILED - failure
3263  *
3264  ******************************************************************/
3265 uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \
3266    RICactions_ToBeSetup_List_t *actionList, E2FailureCause *failureCause, PendingSubsRspInfo *subsRsp)
3267 {
3268    uint8_t actionIdx = 0;
3269    uint8_t ricActionId = 0;
3270    RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
3271
3272    if(actionList->list.array)
3273    {
3274       for(actionIdx = 0; actionIdx < actionList->list.count; actionIdx++)
3275       {
3276          actionItem =(RICaction_ToBeSetup_ItemIEs_t *)actionList->list.array[actionIdx];
3277          switch(actionItem->id)
3278          {
3279             case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item:
3280                {
3281                   /* If Action type is REPORT and 
3282                    * If RIC action definition's extraction and validation passes, 
3283                    * Then : 
3284                    * This action is added to action sequence list of subscription info */
3285                   ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
3286
3287                   if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType == RICactionType_report)
3288                   {
3289                      ricSubscriptionInfo->actionSequence[ricActionId].actionId = ricActionId;
3290                      ricSubscriptionInfo->actionSequence[ricActionId].type = REPORT;
3291
3292                      if(extractRicActionDef(ranFuncDb, &ricSubscriptionInfo->actionSequence[ricActionId].definition, \
3293                         actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, failureCause) == ROK)
3294                      {
3295                         ricSubscriptionInfo->actionSequence[ricActionId].action = CONFIG_ADD;
3296                         ricSubscriptionInfo->numOfActions++;
3297                         break;
3298                      }
3299                   }
3300
3301                   /* In case of any failure, action is rejected
3302                    * Added to rejected-action-list in subscription response */
3303                   deleteActionSequence(&ricSubscriptionInfo->actionSequence[ricActionId]);
3304
3305                   subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].id = ricActionId;
3306                   if(failureCause->causeType == E2_NOTHING)
3307                   {
3308                      failureCause->causeType = E2_RIC_REQUEST;
3309                      failureCause->cause = E2_ACTION_NOT_SUPPORTED;
3310                   }
3311                   memcpy(&subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].failureCause, \
3312                         failureCause, sizeof(E2FailureCause));
3313                   subsRsp->numOfRejectedActions++;
3314                   break;
3315                }
3316             default:
3317                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id);
3318                break;
3319          }
3320       }
3321    }
3322
3323    /* If there is even 1 action that can be added, return ROK */
3324    if(ricSubscriptionInfo->numOfActions)
3325       return ROK;
3326
3327    if(failureCause->causeType == E2_NOTHING)
3328    {
3329       failureCause->causeType = E2_RIC_REQUEST;
3330       failureCause->cause = E2_ACTION_NOT_SUPPORTED;
3331    }
3332    return RFAILED;
3333 }
3334
3335 /******************************************************************
3336  *
3337  * @brief Processes RIC Subscription Req sent by RIC
3338  *
3339  * @details
3340  *
3341  *    Function : procRicSubscriptionRequest
3342  *
3343  *    Functionality: Processes RIC Subscription Request from RIC
3344  *
3345  * @params[in] E2AP_PDU_t ASN decoded E2AP message
3346  * @return ROK     - success
3347  *         RFAILED - failure
3348  *
3349  * ****************************************************************/
3350 uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg)
3351 {
3352    uint8_t idx = 0, actionIdx = 0; 
3353    uint8_t ret = ROK;
3354    uint16_t ranFuncId = 0;
3355    RicRequestId ricReqId;
3356    CmLList  *ricSubscriptionNode = NULLP;
3357    RanFunction *ranFuncDb = NULLP;
3358    RICsubscriptionRequest_t *ricSubsReq = NULLP;
3359    RICsubscriptionDetails_t *subsDetails = NULLP;
3360    RicSubscription *ricSubscriptionInfo = NULLP;
3361    E2FailureCause failureCause;
3362
3363    DU_LOG("\nINFO   -->  E2AP : RIC Subscription request received"); 
3364
3365    memset(&failureCause, 0, sizeof(E2FailureCause));
3366    memset(&ricReqId, 0, sizeof(RicRequestId));
3367
3368    ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
3369    for(idx=0; idx<ricSubsReq->protocolIEs.list.count; idx++)
3370    {
3371       if(ricSubsReq->protocolIEs.list.array[idx])
3372       {
3373          switch(ricSubsReq->protocolIEs.list.array[idx]->id)
3374          {
3375             case ProtocolIE_IDE2_id_RICrequestID:
3376                {
3377                   ricReqId.requestorId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID;
3378                   ricReqId.instanceId  = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID;
3379
3380                   break;
3381                }
3382
3383             case ProtocolIE_IDE2_id_RANfunctionID:
3384                {
3385                   ranFuncId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID; 
3386
3387                   /* Validating RAN Function id */
3388                   ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
3389
3390                   if(!ranFuncDb)
3391                   {
3392                      failureCause.causeType = E2_RIC_REQUEST;
3393                      failureCause.cause = E2_RAN_FUNCTION_ID_INVALID;
3394                      ret = RFAILED;
3395                      break;
3396                   }
3397
3398                   if(ranFuncDb->numPendingSubsRsp >= MAX_PENDING_SUBSCRIPTION_RSP)
3399                   {
3400                      failureCause.causeType = E2_RIC_REQUEST;
3401                      failureCause.cause = E2_FUNCTION_RESOURCE_LIMIT; 
3402                      ret = RFAILED;
3403                      break;
3404                   }
3405
3406                   DU_ALLOC(ricSubscriptionInfo, sizeof(RicSubscription));
3407                   if(!ricSubscriptionInfo)
3408                   {
3409                      DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for ricSubscriptionInfo");
3410                      failureCause.causeType = E2_MISCELLANEOUS;
3411                      failureCause.cause = E2_MISCELLANEOUS_CAUSE_UNSPECIFIED;
3412                      ret = RFAILED;
3413                      break;
3414                   }
3415                   ricSubscriptionInfo->requestId.requestorId = ricReqId.requestorId;
3416                   ricSubscriptionInfo->requestId.instanceId = ricReqId.instanceId;
3417                   ricSubscriptionInfo->ranFuncId = ranFuncId;
3418
3419                   for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
3420                   {
3421                      ricSubscriptionInfo->actionSequence[actionIdx].actionId = -1;
3422                   }
3423
3424                   memset(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp], 0, sizeof(PendingSubsRspInfo));
3425                   memcpy(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp].requestId, 
3426                         &ricReqId, sizeof(RicRequestId));
3427                   ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp].ranFuncId = ranFuncId;
3428                   break;
3429                }
3430
3431             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
3432                {
3433                   subsDetails = &ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails;
3434
3435                   /* Decode, Validate and record Event Trigger Definition */
3436                   if(extractEventTriggerDef(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricEventTriggerDefinition, \
3437                      &failureCause) != ROK)
3438                   {
3439                      ret = RFAILED;
3440                      break;
3441                   }
3442
3443                   /* Decode, Validate and record RIC actions */
3444                   if(extractRicActionToBeSetup(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricAction_ToBeSetup_List, \
3445                      &failureCause, &ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp]) != ROK)
3446                   {
3447                      ret = RFAILED;
3448                      break;
3449                   }
3450                }
3451                break;
3452
3453             default:
3454                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RIC SubsReq:%ld",
3455                      ricSubsReq->protocolIEs.list.array[idx]->id);
3456                break;
3457          }
3458
3459          if(ret == RFAILED)
3460             break;
3461       }
3462    }
3463
3464    freeAperDecodingOfRicSubsReq(ricSubsReq);
3465
3466    if(ret == ROK)
3467    {
3468       cmInitTimers(&(ricSubscriptionInfo->ricSubsReportTimer), 1);
3469       ricSubscriptionInfo->action = CONFIG_ADD;
3470
3471       /* Add RAN subcription detail to RAN function */
3472       DU_ALLOC(ricSubscriptionNode, sizeof(CmLList));
3473       if(ricSubscriptionNode)
3474       {
3475          ricSubscriptionNode->node = (PTR) ricSubscriptionInfo;
3476          cmLListAdd2Tail(&ranFuncDb->subscriptionList, ricSubscriptionNode);
3477       }
3478
3479       ranFuncDb->numPendingSubsRsp++;
3480
3481 #ifdef KPI_CALCULATION
3482       /* Send statistics request to other DU entities */
3483       BuildAndSendStatsReq(ricSubscriptionInfo);
3484 #endif      
3485    }
3486    else
3487    {
3488       DU_FREE(ricSubscriptionInfo, sizeof(RicSubscription));
3489
3490       if(ranFuncDb)
3491       {
3492          memset(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp], 0, sizeof(PendingSubsRspInfo));
3493       }
3494
3495       /* Send RIC Subcription Failure */
3496       BuildAndSendRicSubscriptionFailure(ricReqId, ranFuncId, failureCause);
3497    }
3498
3499    return ret;
3500 }
3501
3502 /******************************************************************
3503  *
3504  * @brief Free RIC Subscription Failure
3505  *
3506  * @details
3507  *
3508  *    Function : FreeRicSubscriptionFailure
3509  *
3510  *    Functionality: Free RIC Subscription Failure
3511  *
3512  * @params[in] E2AP PDU
3513  * @return void
3514  *
3515  * ****************************************************************/
3516 void FreeRicSubscriptionFailure(E2AP_PDU_t *e2apMsg)
3517 {
3518    uint8_t elemIdx = 0;
3519    RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP;
3520
3521    if(e2apMsg)
3522    {
3523       if(e2apMsg->choice.unsuccessfulOutcome)
3524       {
3525          ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
3526          if(ricSubscriptionFailure->protocolIEs.list.array)
3527          {
3528             for(elemIdx = 0; elemIdx < ricSubscriptionFailure->protocolIEs.list.count; elemIdx++)
3529             {
3530                DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t));
3531             }
3532             DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size);
3533          }
3534          DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
3535       }
3536       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3537    }
3538 }
3539
3540 /******************************************************************
3541  *
3542  * @brief Fill and Send RIC Subscription Failure to RIC
3543  *
3544  * @details
3545  *
3546  *    Function : BuildAndSendRicSubscriptionFailure
3547  *
3548  *    Functionality: Fill and Send RIC Subscription Failure to RIC
3549  *
3550  * @params[in] RIC Request ID
3551  *             RAN Function ID
3552  *             Cause of Failure
3553  * @return ROK     - success
3554  *         RFAILED - failure
3555  *
3556  * ****************************************************************/
3557 uint8_t BuildAndSendRicSubscriptionFailure(RicRequestId ricReqId, uint16_t ranFuncId, E2FailureCause failureCause)
3558 {
3559    uint8_t          ret = RFAILED;
3560    uint8_t          elementCnt = 0, elemIdx = 0;
3561    E2AP_PDU_t       *e2apMsg = NULLP;
3562    asn_enc_rval_t   encRetVal;        /* Encoder return value */
3563    RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP;
3564    RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
3565
3566    while(true)
3567    {
3568       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Failure\n");
3569
3570       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3571       if(e2apMsg == NULLP)
3572       {
3573          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
3574          break;
3575       }
3576
3577       e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome;
3578       DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
3579       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
3580       {
3581          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
3582          break;
3583       }
3584       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
3585       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
3586       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure;
3587
3588       ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
3589
3590       elementCnt = 3;
3591       ricSubscriptionFailure->protocolIEs.list.count = elementCnt;
3592       ricSubscriptionFailure->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionFailure_IEs_t *);
3593       DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size);
3594       if(!ricSubscriptionFailure->protocolIEs.list.array)
3595       {
3596          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
3597          break;
3598       }
3599
3600       for(elemIdx = 0; elemIdx < elementCnt; elemIdx++)
3601       {
3602          DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t));
3603          if(!ricSubscriptionFailure->protocolIEs.list.array[elemIdx])
3604          {
3605             DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d] for IE at index [%d]", \
3606                __func__, __LINE__, elemIdx);
3607             break;
3608          }
3609       }
3610       if(elemIdx < elementCnt)
3611          break;
3612
3613       elemIdx = 0;
3614
3615       /* RIC Request ID */
3616       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
3617       ricSubsFailIe->id = ProtocolIE_IDE2_id_RICrequestID;
3618       ricSubsFailIe->criticality = CriticalityE2_reject;
3619       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RICrequestID;
3620       ricSubsFailIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
3621       ricSubsFailIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
3622
3623       /* RAN Function ID */
3624       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
3625       ricSubsFailIe->id = ProtocolIE_IDE2_id_RANfunctionID;
3626       ricSubsFailIe->criticality = CriticalityE2_reject;
3627       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RANfunctionID;
3628       ricSubsFailIe->value.choice.RANfunctionID = ranFuncId;
3629
3630       /* Cause */
3631       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
3632       ricSubsFailIe->id = ProtocolIE_IDE2_id_CauseE2;
3633       ricSubsFailIe->criticality = CriticalityE2_reject;
3634       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_CauseE2;
3635       fillE2Cause(&ricSubsFailIe->value.choice.CauseE2, failureCause);
3636
3637       /* Prints the Msg formed */
3638       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3639       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3640       encBufSize = 0;
3641       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3642       if(encRetVal.encoded == ENCODE_FAIL)
3643       {
3644          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Failure Message (at %s)\n",\
3645                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3646          break;
3647       }
3648       else
3649       {
3650          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Failure Message \n");
3651 #ifdef DEBUG_ASN_PRINT
3652          for(int i=0; i< encBufSize; i++)
3653          {
3654             printf("%x",encBuf[i]);
3655          }
3656 #endif
3657       }
3658
3659       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
3660       {
3661          DU_LOG("\nINFO   -->  E2AP : Sending RIC Subscription Failure");
3662
3663       }
3664       ret = ROK;
3665       break;
3666    }
3667    FreeRicSubscriptionFailure(e2apMsg);
3668    return ret;
3669 }
3670
3671 /*******************************************************************
3672  *
3673  * @brief Free the RicIndication Message
3674  *
3675  * @details
3676  *
3677  *    Function : FreeRicIndication
3678  *
3679  * Functionality: Free the RicIndication Message
3680  *
3681  * @return void
3682  *         
3683  *
3684  ******************************************************************/
3685 void FreeRicIndication(E2AP_PDU_t  *e2apMsg) 
3686 {
3687    uint8_t idx = 0;
3688    RICindication_t *ricIndicationMsg= NULLP;
3689
3690    if(e2apMsg != NULLP)
3691    {
3692       if(e2apMsg->choice.initiatingMessage != NULLP)
3693       {
3694          ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
3695          if(ricIndicationMsg!= NULLP)
3696          {
3697             if(ricIndicationMsg->protocolIEs.list.array != NULLP)
3698             {
3699                for(idx=0; idx<ricIndicationMsg->protocolIEs.list.count; idx++)
3700                {
3701                   if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP)
3702                   {
3703                      switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
3704                      {
3705                         case ProtocolIE_IDE2_id_RICrequestID:
3706                         case ProtocolIE_IDE2_id_RANfunctionID:
3707                         case ProtocolIE_IDE2_id_RICactionID:
3708                         case ProtocolIE_IDE2_id_RICindicationType:
3709                            break;
3710
3711                         case ProtocolIE_IDE2_id_RICindicationHeader:
3712                            {
3713                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\
3714                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
3715                               break;
3716                            }
3717                         case ProtocolIE_IDE2_id_RICindicationMessage:
3718                            {
3719                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\
3720                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
3721                               break;
3722                            }
3723                         default:
3724                            break;
3725                      }
3726                      DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t));
3727                   }
3728                }
3729                DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size);
3730             }
3731          }
3732          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3733       }
3734       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3735    }
3736 }
3737
3738 /*******************************************************************
3739  *
3740  * @brief Free measurement record
3741  *
3742  * @details
3743  *
3744  *    Function : freeMeasRecord
3745  *
3746  * Functionality: Free all measurement recorded for a measurement
3747  *    within an action in a RIC subscription
3748  *
3749  * @param  Measurement data to be freed
3750  * @return void
3751  *
3752  ******************************************************************/
3753 void freeMeasData(MeasurementData_t *measData)
3754 {
3755    uint8_t measIdx = 0, measRecIdx = 0;
3756    MeasurementRecord_t *measRecord = NULLP;
3757
3758    if(measData->list.array)
3759    {
3760       for(measIdx = 0; measIdx < measData->list.count; measIdx++)
3761       {
3762          if(measData->list.array[measIdx])
3763          {
3764             measRecord = &measData->list.array[measIdx]->measRecord;
3765             if(measRecord->list.array)
3766             {
3767                for(measRecIdx = 0; measRecIdx < measRecord->list.count; measRecIdx++)
3768                {
3769                   DU_FREE(measRecord->list.array[measRecIdx], sizeof(MeasurementRecordItem_t));
3770                }
3771                DU_FREE(measRecord->list.array, measRecord->list.size);
3772             }
3773             DU_FREE(measData->list.array[measIdx], sizeof(MeasurementDataItem_t));
3774          }
3775       }
3776       DU_FREE(measData->list.array, measData->list.size);
3777    }
3778 }
3779
3780 /*******************************************************************
3781  *
3782  * @brief Fill measurement info list
3783  *
3784  * @details
3785  *
3786  *    Function : freeMeasInfoList
3787  *
3788  * Functionality: Fills all measurement info within an action 
3789  *    in a RIC subscription
3790  *
3791  * @param  Measurement Info list to be freed
3792  * @return void
3793  *
3794  ******************************************************************/
3795 void freeMeasInfoList(MeasurementInfoList_t *measInfoList)
3796 {
3797    uint8_t measInfoIdx = 0;
3798
3799    if(measInfoList->list.array)
3800    {
3801       for(measInfoIdx = 0; measInfoIdx < measInfoList->list.count; measInfoIdx++)
3802       {
3803          if(measInfoList->list.array[measInfoIdx])
3804          {
3805             DU_FREE(measInfoList->list.array[measInfoIdx]->measType.choice.measName.buf, \
3806                   measInfoList->list.array[measInfoIdx]->measType.choice.measName.size);
3807
3808             DU_FREE(measInfoList->list.array[measInfoIdx], measInfoList->list.size);
3809          }
3810       }
3811       DU_FREE(measInfoList->list.array, measInfoList->list.size);
3812    }
3813 }
3814
3815 /*******************************************************************
3816  *
3817  * @brief Free E2SM-KPM Indication Message
3818  *
3819  * @details
3820  *
3821  *    Function : FreeE2smKpmIndicationMessage
3822  *
3823  * Functionality: Free E2SM-KPM Indication Message
3824  *
3825  * @param  E2SM-KPM Indication message to be freed
3826  * @return void
3827  *
3828  ******************************************************************/
3829 void FreeE2smKpmIndicationMessage(E2SM_KPM_IndicationMessage_t *e2smKpmIndMsg)
3830 {
3831    E2SM_KPM_IndicationMessage_Format1_t *format1Msg = NULLP;
3832
3833    switch(e2smKpmIndMsg->indicationMessage_formats.present)
3834    {
3835       case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format1:
3836          {
3837             if(e2smKpmIndMsg->indicationMessage_formats.choice.indicationMessage_Format1)
3838             {
3839                format1Msg = e2smKpmIndMsg->indicationMessage_formats.choice.indicationMessage_Format1;
3840                
3841                /* Measurement Data */
3842                freeMeasData(&format1Msg->measData);
3843
3844                /* Measurement Info List */
3845                if(format1Msg->measInfoList)
3846                {
3847                   freeMeasInfoList(format1Msg->measInfoList);
3848                   DU_FREE(format1Msg->measInfoList, sizeof(MeasurementInfoList_t));
3849                }
3850
3851                /* Granularity Period */
3852                DU_FREE(format1Msg->granulPeriod, sizeof(GranularityPeriod_t));
3853
3854                DU_FREE(format1Msg, sizeof(E2SM_KPM_IndicationMessage_Format1_t));
3855             }
3856             break;
3857          }
3858
3859       case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_NOTHING:
3860       case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format2:
3861       default:
3862          break;
3863    }
3864 }
3865
3866 /*******************************************************************
3867  *
3868  * @brief Fill measurement record
3869  *
3870  * @details
3871  *
3872  *    Function : fillMeasRecord
3873  *
3874  * Functionality: Fills all measurement value for a measurement
3875  *    within an action in a RIC subscription
3876  *
3877  * @param  Measurement record to be filled
3878  *         Measurement database with measurement records
3879  * @return ROK     - success
3880  *         RFAILED - failure
3881  *
3882  ******************************************************************/
3883 uint8_t fillMeasRecord(MeasurementRecord_t *measRecord, MeasurementInfo *measInfoDb)
3884 {
3885    uint8_t measRecIdx = 0;
3886    CmLList *measValNode = NULLP;
3887    double  measVal = 0;
3888
3889    measRecord->list.count = measInfoDb->measuredValue.count;
3890    measRecord->list.size = measRecord->list.count * sizeof(MeasurementRecordItem_t *);
3891
3892    DU_ALLOC(measRecord->list.array, measRecord->list.size);
3893    if(!measRecord->list.array)
3894    {
3895       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3896       return RFAILED;
3897    }
3898
3899    for(measRecIdx = 0; measRecIdx < measRecord->list.count; measRecIdx++)
3900    {
3901       DU_ALLOC(measRecord->list.array[measRecIdx], sizeof(MeasurementRecordItem_t));
3902       if(!measRecord->list.array[measRecIdx])
3903       {
3904          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3905          return RFAILED;
3906       }
3907    }
3908
3909    measRecIdx = 0;
3910    CM_LLIST_FIRST_NODE(&measInfoDb->measuredValue, measValNode);
3911    while(measValNode)
3912    {
3913      measVal = *(double *)measValNode->node;
3914      if(measVal == (int)measVal)
3915      {
3916         measRecord->list.array[measRecIdx]->present = MeasurementRecordItem_PR_integer;
3917         measRecord->list.array[measRecIdx]->choice.integer = (int)measVal;
3918      }
3919      else
3920      {
3921          measRecord->list.array[measRecIdx]->present = MeasurementRecordItem_PR_real;
3922          measRecord->list.array[measRecIdx]->choice.real = measVal;
3923      }
3924      measRecIdx++;
3925      measValNode= measValNode->next;  
3926      /* Once the measurement record is added to the message, delete it from DB */
3927      measVal = 0;
3928    }
3929    deleteMeasuredValueList(&measInfoDb->measuredValue);
3930    return ROK;
3931 }
3932
3933 /*******************************************************************
3934  *
3935  * @brief Fills measuerement data
3936  *
3937  * @details
3938  *
3939  *    Function : fillMeasData
3940  *
3941  * Functionality: Fill all measurement recorded for all measurements
3942  *    in an action in a RIC subscription
3943  *
3944  * @param  Measurement data to be filled
3945  *         Measurement info list from an action DB
3946  * @return ROK     - success
3947  *         RFAILED - failure
3948  *
3949  ******************************************************************/
3950 uint8_t fillMeasData(MeasurementData_t *measData, CmLListCp *measInfoListDb)
3951 {
3952   uint8_t measIdx = 0;
3953   CmLList *measInfoNode = NULLP;
3954   MeasurementInfo *measInfoDb = NULLP;
3955   MeasurementRecord_t *measRecord = NULLP;
3956
3957   measData->list.count = measInfoListDb->count;
3958   measData->list.size = measData->list.count * sizeof(MeasurementDataItem_t *);
3959
3960   DU_ALLOC(measData->list.array, measData->list.size);
3961   if(!measData->list.array)
3962   {
3963      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3964      return RFAILED;
3965   }
3966
3967   measIdx = 0;
3968   CM_LLIST_FIRST_NODE(measInfoListDb, measInfoNode);
3969   while(measInfoNode)
3970   {
3971      measInfoDb = (MeasurementInfo *)measInfoNode->node;
3972      if(measInfoDb)
3973      {
3974         DU_ALLOC(measData->list.array[measIdx], sizeof(MeasurementDataItem_t));
3975         if(!measData->list.array[measIdx])
3976         {
3977            DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3978            return RFAILED;
3979         }
3980
3981         measRecord = &measData->list.array[measIdx]->measRecord;
3982         if(fillMeasRecord(measRecord, measInfoDb) != ROK)
3983         {
3984            DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement record");
3985            return RFAILED;
3986         }
3987         measIdx++;
3988      }
3989      measInfoNode = measInfoNode->next;
3990   }
3991
3992   return ROK;
3993 }
3994
3995 /*******************************************************************
3996  *
3997  * @brief Fill all measurement info
3998  *
3999  * @details
4000  *
4001  *    Function : fillMeasInfoList
4002  *
4003  * Functionality: Fills all measurement info belonging to an action
4004  *  in a RIC subscription
4005  *
4006  * @param   Measurement Info list to be filled
4007  *          Measurement Info list from E2AP DB
4008  * @return ROK     - success
4009  *         RFAILED - failure
4010  *
4011  ******************************************************************/
4012 uint8_t fillMeasInfoList(MeasurementInfoList_t *measInfoList, CmLListCp *measInfoListDb)
4013 {
4014    uint8_t measInfoIdx = 0;
4015    CmLList *measInfoNode = NULLP;
4016    MeasurementInfo *measInfoDb = NULLP;
4017    MeasurementInfoItem_t *measInfoItem = NULLP;
4018
4019    measInfoList->list.count = measInfoListDb->count;
4020    measInfoList->list.size = measInfoList->list.count * sizeof(MeasurementInfoItem_t *);
4021
4022    DU_ALLOC(measInfoList->list.array, measInfoList->list.size);
4023    if(!measInfoList->list.array)
4024    {
4025       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4026       return RFAILED;
4027    }
4028
4029    measInfoIdx = 0;
4030    CM_LLIST_FIRST_NODE(measInfoListDb, measInfoNode);
4031    while(measInfoNode)
4032    {
4033       DU_ALLOC(measInfoList->list.array[measInfoIdx], sizeof(MeasurementInfoItem_t));
4034       if(!measInfoList->list.array[measInfoIdx])
4035       {
4036          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4037          return RFAILED;
4038       }
4039
4040       measInfoItem = measInfoList->list.array[measInfoIdx];
4041       measInfoDb = (MeasurementInfo *)measInfoNode->node;
4042       if(measInfoDb)
4043       {
4044          /* Measurement Type */
4045          measInfoItem->measType.present = MeasurementType_PR_measName;
4046          measInfoItem->measType.choice.measName.size = strlen(measInfoDb->measurementTypeName);
4047
4048          DU_ALLOC(measInfoItem->measType.choice.measName.buf, measInfoItem->measType.choice.measName.size);
4049          if(!measInfoItem->measType.choice.measName.buf)
4050          {
4051             DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4052             return RFAILED;
4053          }
4054
4055          memcpy(measInfoItem->measType.choice.measName.buf, measInfoDb->measurementTypeName,\
4056             measInfoItem->measType.choice.measName.size);
4057
4058          measInfoIdx++;
4059       }
4060       measInfoNode = measInfoNode->next;
4061       measInfoDb = NULLP;
4062    }
4063
4064    return ROK;
4065 }
4066
4067  /*******************************************************************
4068  *
4069  * @brief Fill E2SM-KPM Indication Message Format 1
4070  *
4071  * @details
4072  *
4073  *    Function : fillE2smKpmIndMsgFormat1
4074  *
4075  * Functionality: Fill E2SM-KPM Indication Message Format 1
4076  *
4077  * @param  Format 1 Message to be filled
4078  *         Action Definition format 1 from E2AP DB
4079  * @return ROK     - success
4080  *         RFAILED - failure
4081  *
4082  ******************************************************************/
4083 uint8_t fillE2smKpmIndMsgFormat1(E2SM_KPM_IndicationMessage_Format1_t *format1Msg, ActionDefFormat1 *format1)
4084 {
4085   /* Measurement Data */
4086   if(fillMeasData(&format1Msg->measData, &format1->measurementInfoList) != ROK)
4087   {
4088      DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement data");
4089      return RFAILED;
4090   }
4091
4092   /* Measurement Information */
4093   DU_ALLOC(format1Msg->measInfoList, sizeof(MeasurementInfoList_t));
4094   if(!format1Msg->measInfoList)
4095   {
4096      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4097      return RFAILED;
4098   }
4099
4100   if(fillMeasInfoList(format1Msg->measInfoList, &format1->measurementInfoList) != ROK)
4101   {
4102      DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement information list");
4103      return RFAILED;
4104   }
4105
4106   /* Granularity Period */
4107   DU_ALLOC(format1Msg->granulPeriod, sizeof(GranularityPeriod_t));
4108   if(!format1Msg->granulPeriod)
4109   {
4110      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4111      return RFAILED;
4112   }
4113   *(format1Msg->granulPeriod) = format1->granularityPeriod;
4114
4115   return ROK;
4116 }
4117
4118 /*******************************************************************
4119  *
4120  * @brief Fill RIC Indication Message buffer
4121  *
4122  * @details
4123  *
4124  *    Function : fillRicIndMsgBuf
4125  *
4126  * Functionality: Fill E2SM-KPM Indication Message
4127  *    Encode this message and copy to RIC Indication Message buffer
4128  * 
4129  * @param  RIC Indication Message buffer to be filled
4130  *         Source action info from E2AP DB
4131  * @return ROK     - success
4132  *         RFAILED - failure
4133  *
4134  ******************************************************************/
4135 uint8_t fillRicIndMsgBuf(RICindicationMessage_t *ricIndMsgBuf, ActionInfo *actionInfo)
4136 {
4137    uint8_t ret = RFAILED;
4138    bool failedInFormat = false;
4139    E2SM_KPM_IndicationMessage_t e2smKpmIndMsg;
4140    asn_enc_rval_t   encRetVal;        /* Encoder return value */
4141
4142    memset(&e2smKpmIndMsg, 0, sizeof(E2SM_KPM_IndicationMessage_t));
4143
4144    while(true)
4145    {
4146       /* E2SM-KPM Indication message format type */
4147       e2smKpmIndMsg.indicationMessage_formats.present = actionInfo->definition.formatType;
4148       switch(e2smKpmIndMsg.indicationMessage_formats.present)
4149       {
4150          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format1:
4151             {
4152                /* E2SM-KPM Indication message format 1 */
4153                DU_ALLOC(e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1, \
4154                      sizeof(E2SM_KPM_IndicationMessage_Format1_t));
4155                if(!e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1)
4156                {
4157                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4158                   failedInFormat = true;
4159                   break;
4160                }
4161
4162                if(fillE2smKpmIndMsgFormat1(e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1, \
4163                   &actionInfo->definition.choice.format1) != ROK)
4164                {
4165                   DU_LOG("\nERROR  -->  E2AP : Failed to fill E2SM-KPM Indication message format 1");
4166                   failedInFormat = true;
4167                   break;
4168                }
4169                break;
4170             }
4171
4172          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_NOTHING:
4173          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format2:
4174          default:
4175             {
4176                DU_LOG("\nERROR  -->  E2AP : fillRicIndMsgBuf: Only Format 1 supported");
4177                failedInFormat = true;
4178                break;
4179             }
4180       }
4181
4182       if(failedInFormat)
4183          break;
4184
4185       /* Encode E2SM-KPM Indication Message */
4186       xer_fprint(stdout, &asn_DEF_E2SM_KPM_IndicationMessage, &e2smKpmIndMsg);
4187       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4188       encBufSize = 0;
4189       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_IndicationMessage, 0, &e2smKpmIndMsg, PrepFinalEncBuf, encBuf);
4190       if(encRetVal.encoded == ENCODE_FAIL)
4191       {
4192          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM Indication Message (at %s)\n",\
4193                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4194          break;
4195       }
4196       else
4197       {
4198          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SM-KPM Indication Message \n");
4199 #ifdef DEBUG_ASN_PRINT
4200          for(int i=0; i< encBufSize; i++)
4201          {
4202             printf("%x",encBuf[i]);
4203          } 
4204 #endif
4205       }
4206
4207       /* Copy encoded string to RIC Indication Message buffer */
4208       ricIndMsgBuf->size = encBufSize;
4209       DU_ALLOC(ricIndMsgBuf->buf, ricIndMsgBuf->size);
4210       if(!ricIndMsgBuf->buf)
4211       {
4212          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4213          break;
4214       }
4215       memset(ricIndMsgBuf->buf, 0, ricIndMsgBuf->size);
4216       memcpy(ricIndMsgBuf->buf, encBuf, encBufSize);
4217
4218       ret = ROK;
4219       break;
4220    }
4221
4222    /* Free E2SM-KPM Indication Message */
4223    FreeE2smKpmIndicationMessage(&e2smKpmIndMsg);
4224
4225    return ret;
4226 }
4227
4228 /*******************************************************************
4229  *
4230  * @brief Free E2SM-KPM Indication Header
4231  *
4232  * @details
4233  *
4234  *    Function : FreeE2smKpmIndicationHeader
4235  *
4236  * Functionality: Free E2SM-KPM Indication Header
4237  * 
4238  * @param  E2SM-KPM Indication Header to be free
4239  * @return void
4240  *
4241  ******************************************************************/
4242 void FreeE2smKpmIndicationHeader(E2SM_KPM_IndicationHeader_t *e2smKpmIndHdr)
4243 {
4244    E2SM_KPM_IndicationHeader_Format1_t *format1 = NULLP;
4245
4246    if(e2smKpmIndHdr)
4247    {
4248       switch(e2smKpmIndHdr->indicationHeader_formats.present)
4249       {
4250          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_indicationHeader_Format1:
4251             {
4252                if(e2smKpmIndHdr->indicationHeader_formats.choice.indicationHeader_Format1)
4253                {
4254                   format1 = e2smKpmIndHdr->indicationHeader_formats.choice.indicationHeader_Format1;
4255
4256                   DU_FREE(format1->colletStartTime.buf, format1->colletStartTime.size);
4257                   DU_FREE(format1, sizeof(E2SM_KPM_IndicationHeader_Format1_t));
4258                }
4259                break;
4260             }
4261          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_NOTHING:
4262          default:
4263             break;
4264       }
4265    }
4266 }
4267
4268 /*******************************************************************
4269  *
4270  * @brief Fill RIC Indication Header buffer
4271  *
4272  * @details
4273  *
4274  *    Function : fillRicIndHeader
4275  *
4276  * Functionality: Fill E2SM-KPM Indication Header
4277  *    Encode this message and copy to RIC Indication Header buffer
4278  * 
4279  * @param  RIC Indication Header buffer to be filled
4280  *         Source RIC subscription info from E2AP DB
4281  * @return ROK     - success
4282  *         RFAILED - failure
4283  *
4284  ******************************************************************/
4285 uint8_t fillRicIndHeader(RICindicationHeader_t *ricIndHdr, RicSubscription *ricSubsInfo)
4286 {
4287    uint8_t ret = RFAILED;
4288    uint8_t secBufIdx = 0, milliSecBufIdx = 0;
4289    int8_t byteIdx = 0;
4290    bool formatFailure = false;
4291    RanFunction *ranFunc = NULLP;
4292    ReportStartTime *startTime = NULLP;
4293    E2SM_KPM_IndicationHeader_t e2smKpmIndHdr;
4294    E2SM_KPM_IndicationHeader_Format1_t *format1 = NULLP;
4295    asn_enc_rval_t   encRetVal;        /* Encoder return value */
4296
4297    while(true)
4298    {
4299       ranFunc = fetchRanFuncFromRanFuncId(ricSubsInfo->ranFuncId);
4300       if(ranFunc == NULLP)
4301       {
4302          DU_LOG("\nERROR  -->  E2AP : RAN Function ID [%d] not found", ricSubsInfo->ranFuncId);
4303          break;
4304       }
4305
4306       memset(&e2smKpmIndHdr, 0, sizeof(E2SM_KPM_IndicationHeader_t));
4307
4308       e2smKpmIndHdr.indicationHeader_formats.present = ranFunc->ricIndicationHeaderFormat;
4309       switch(e2smKpmIndHdr.indicationHeader_formats.present)
4310       {
4311          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_indicationHeader_Format1:
4312             {
4313                DU_ALLOC(e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1, \
4314                      sizeof(E2SM_KPM_IndicationHeader_Format1_t));
4315                if(!e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1)
4316                {
4317                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4318                   formatFailure = true;
4319                   break;
4320                }
4321                format1 = e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1;
4322
4323                /* Fetch reporting period start time from DB */
4324                switch(ricSubsInfo->eventTriggerDefinition.formatType)
4325                {
4326                   case 1:
4327                   {
4328                      startTime = &ricSubsInfo->eventTriggerDefinition.choice.format1.startTime;
4329                   }
4330                }
4331
4332                format1->colletStartTime.size = 8 * sizeof(uint8_t);
4333                DU_ALLOC(format1->colletStartTime.buf, format1->colletStartTime.size);
4334                if(!format1->colletStartTime.buf)
4335                {
4336                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4337                   formatFailure = true;
4338                   break;
4339                }
4340
4341                /* As per O-RAN.WG3.E2SM-KPM-R003-v03.00, section 8.3.12 and
4342                 * RFC 5905, section 6 :
4343                 * Time stamp has a 64-bit format where first 32-bit is seconds
4344                 * and next 32-bit is fraction in picosecond-level.
4345                 * This fraction has been rounded in microseconds.
4346                 *
4347                 * Hence,
4348                 * Storing 32-bit seconds at MSB 0-3 and
4349                 * 32-bit milliseconds at next 4 bytes i.e. bytes 4-7
4350                 */
4351                secBufIdx = 0;
4352                milliSecBufIdx = 4;
4353                for(byteIdx = 3; byteIdx >= 0; byteIdx--)
4354                {
4355                   format1->colletStartTime.buf[secBufIdx++] = startTime->timeInSec >> (8*byteIdx);
4356                   format1->colletStartTime.buf[milliSecBufIdx++] = startTime->timeInMilliSec >> (8*byteIdx);
4357                }
4358                break;
4359             }
4360
4361          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_NOTHING:
4362          default:
4363          {
4364              DU_LOG("\nERROR  -->  E2AP : Only E2SM-KPM Indication Header Format 1 supported");
4365              formatFailure = true;
4366              break;
4367          }
4368       }
4369
4370       if(formatFailure)
4371          break;
4372
4373       /* Encode E2SM-KPM Indication Header */
4374       xer_fprint(stdout, &asn_DEF_E2SM_KPM_IndicationHeader, &e2smKpmIndHdr);
4375       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4376       encBufSize = 0;
4377       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_IndicationHeader, 0, &e2smKpmIndHdr, PrepFinalEncBuf, encBuf);
4378       if(encRetVal.encoded == ENCODE_FAIL)
4379       {
4380          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM Indication Header (at %s)\n",\
4381                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4382          break;
4383       }
4384       else
4385       {
4386          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SM-KPM Indication Header \n");
4387 #ifdef DEBUG_ASN_PRINT
4388          for(int i=0; i< encBufSize; i++)
4389          {
4390             printf("%x",encBuf[i]);
4391          } 
4392 #endif
4393       }
4394
4395       /* Copy encoded string to RIC Indication Header buffer */
4396       ricIndHdr->size = encBufSize;
4397       DU_ALLOC(ricIndHdr->buf, ricIndHdr->size);
4398       if(!ricIndHdr->buf)
4399       {
4400          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4401          break;
4402       }
4403       memset(ricIndHdr->buf, 0, ricIndHdr->size);
4404       memcpy(ricIndHdr->buf, encBuf, encBufSize);
4405       ret = ROK;
4406       break;
4407    }
4408
4409    /* Free E2SM-KPM Indication Header */
4410    FreeE2smKpmIndicationHeader(&e2smKpmIndHdr);
4411
4412    return ret;
4413 }
4414
4415 /*******************************************************************
4416  *
4417  * brief Fill the RIC Indication Message
4418  *
4419  * @details
4420  *
4421  *    Function : fillRicIndication
4422  *
4423  * Functionality: Fills the RIC Indication Message
4424  *
4425  * @param  RIC Indication Message to be filled
4426  *         RIC Subscription DB
4427  *         Action DB
4428  * @return ROK     - success
4429  *         RFAILED - failure
4430  *
4431  ******************************************************************/
4432 uint8_t fillRicIndication(RICindication_t *ricIndicationMsg, RicSubscription *ricSubscriptionInfo, ActionInfo *actionInfo)
4433 {
4434    uint8_t elementCnt = 0, idx = 0;
4435    uint8_t ret = ROK;
4436
4437    elementCnt = 6;
4438
4439    ricIndicationMsg->protocolIEs.list.count = elementCnt;
4440    ricIndicationMsg->protocolIEs.list.size  = elementCnt * sizeof(RICindication_IEs_t *);
4441
4442    /* Initialize the Ric Indication members */
4443    DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, ricIndicationMsg->protocolIEs.list.size);
4444    if(ricIndicationMsg->protocolIEs.list.array == NULLP)
4445    {
4446       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4447       return RFAILED;
4448    }
4449
4450    for(idx=0; idx<elementCnt; idx++)
4451    {
4452       DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx], sizeof(RICindication_IEs_t));
4453       if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
4454       {
4455          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
4456          return RFAILED;
4457       }
4458    }
4459
4460    /* RIC Request ID */
4461    idx = 0;
4462    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
4463    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4464    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICrequestID;
4465    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID = \
4466       ricSubscriptionInfo->requestId.requestorId;
4467    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID = \
4468       ricSubscriptionInfo->requestId.instanceId;
4469
4470    /* RAN Function ID */
4471    idx++;
4472    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
4473    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4474    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RANfunctionID;
4475    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ricSubscriptionInfo->ranFuncId;
4476
4477    /* RIC Action ID */
4478    idx++;
4479    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
4480    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4481    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICactionID;
4482    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = actionInfo->actionId;
4483
4484    /* RIC Indication Type */
4485    idx++;
4486    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
4487    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4488    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationType;
4489    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = actionInfo->type;
4490
4491    /* RIC Indication Header */
4492    idx++;
4493    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
4494    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4495    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationHeader;
4496    if(fillRicIndHeader(&ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader, \
4497       ricSubscriptionInfo) != ROK)
4498    {
4499       DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication header");
4500       return RFAILED;
4501    }
4502
4503    /* RIC Indication Message */
4504    idx++;
4505    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
4506    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4507    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationMessage;
4508    if(fillRicIndMsgBuf(&ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage, \
4509       actionInfo) != ROK)
4510    {
4511       DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication Message");
4512       return RFAILED;
4513    }
4514
4515    return ret;
4516 }
4517
4518 /*******************************************************************
4519  *
4520  * @brief Builds and Send the RicIndication Message
4521  *
4522  * @details
4523  *
4524  *    Function : BuildAndSendRicIndication
4525  *
4526  * Functionality:Fills the RicIndication Message
4527  *
4528  * @return ROK     - success
4529  *         RFAILED - failure
4530  *
4531  ******************************************************************/
4532
4533 uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo, ActionInfo *actionInfo)
4534 {
4535    uint8_t          ret = RFAILED; 
4536    E2AP_PDU_t       *e2apMsg = NULLP;
4537    RICindication_t  *ricIndicationMsg = NULLP;
4538    asn_enc_rval_t   encRetVal;        /* Encoder return value */
4539
4540    while(true)
4541    {
4542       DU_LOG("\nINFO   -->  E2AP : Building RIC Indication Message\n");
4543
4544       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4545       if(e2apMsg == NULLP)
4546       {
4547          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4548          break;
4549       }
4550
4551       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4552       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4553       if(e2apMsg->choice.initiatingMessage == NULLP)
4554       {
4555          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4556          break;
4557       }
4558       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
4559       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4560       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication;
4561
4562       ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
4563
4564       if(fillRicIndication(ricIndicationMsg, ricSubscriptionInfo, actionInfo) != ROK)
4565       {
4566          DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication message");
4567          break;
4568       }
4569
4570       /* Prints the Msg formed */
4571       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4572       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4573       encBufSize = 0;
4574       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4575             encBuf);
4576       if(encRetVal.encoded == ENCODE_FAIL)
4577       {
4578          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Indication Message (at %s)\n",\
4579                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4580          break;
4581       }
4582       else
4583       {
4584          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Indication Message \n");
4585 #ifdef DEBUG_ASN_PRINT
4586          for(int i=0; i< encBufSize; i++)
4587          {
4588             printf("%x",encBuf[i]);
4589          } 
4590 #endif
4591       }
4592
4593       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
4594       {
4595          DU_LOG("\nINFO   -->  E2AP : Sending RIC Indication Message");      
4596
4597       }
4598       ret = ROK;
4599       break;
4600    }
4601    FreeRicIndication(e2apMsg);  
4602    return ret;
4603 }
4604
4605 /*******************************************************************
4606  *
4607  * @brief free e2 node component configuration req and rsp
4608  *
4609  * @details
4610  *
4611  *    Function : freeE2NodeComponentConfiguration 
4612  *
4613  *    Functionality:
4614  *       - free e2 node component configuration req and rsp
4615  *
4616  * @params[in] E2nodeComponentConfiguration_t *e2nodeComponentConfiguration
4617  * @return ROK     - success
4618  *         RFAILED - failure
4619  *
4620  * ****************************************************************/
4621
4622 void freeE2NodeComponentConfiguration(E2nodeComponentConfiguration_t *e2nodeComponentConfiguration)
4623 {
4624    /* Free E2 Node Component Request Part */
4625    DU_FREE(e2nodeComponentConfiguration->e2nodeComponentRequestPart.buf, e2nodeComponentConfiguration->e2nodeComponentRequestPart.size);
4626
4627    /* Free E2 Node Component Response Part */
4628    DU_FREE(e2nodeComponentConfiguration->e2nodeComponentResponsePart.buf, e2nodeComponentConfiguration->e2nodeComponentResponsePart.size);
4629                                  
4630 }
4631
4632 /*******************************************************************
4633  *
4634  * @brief free e2 node component component identifier
4635  *
4636  * @details
4637  *
4638  *    Function : freeE2NodeComponentIdentifier
4639  *
4640  *    Functionality:
4641  *       - free e2 node component component identifier
4642  *
4643  * @params[in] E2nodeComponentID_t  *componentID 
4644  * @return ROK     - success
4645  *         RFAILED - failure
4646  *
4647  * ****************************************************************/
4648
4649 void freeE2NodeComponentIdentifier(E2nodeComponentID_t *componentID)
4650 {
4651    if(componentID->choice.e2nodeComponentInterfaceTypeF1)
4652    {
4653       DU_FREE(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf, componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
4654       DU_FREE(componentID->choice.e2nodeComponentInterfaceTypeF1, sizeof(E2nodeComponentInterfaceF1_t));
4655    }
4656                                  
4657 }
4658
4659 /*******************************************************************
4660  *
4661  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
4662  *
4663  * @details
4664  *
4665  *    Function : FreeE2NodeConfigUpdate 
4666  *
4667  *    Functionality:
4668  *       - freeing the memory allocated for E2nodeConfigurationUpdate
4669  *
4670  * @params[in] E2AP_PDU_t *e2apMsg 
4671  * @return ROK     - success
4672  *         RFAILED - failure
4673  *
4674  * ****************************************************************/
4675
4676 void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg)
4677 {
4678    uint8_t arrIdx =0, e2NodeUpdateListIdx=0, e2NodeRemovalListIdx=0, e2NodeAddListIdx=0;
4679    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate =NULL;
4680    E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList  =NULL;
4681    E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItem =NULL;
4682    E2nodeComponentConfigRemoval_List_t *e2NodeRemovalList =NULL;
4683    E2nodeComponentConfigRemoval_ItemIEs_t *e2NodeRemovalItem =NULL;
4684    E2nodeComponentConfigAddition_List_t *e2NodeAddList =NULL;
4685    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem =NULL;
4686
4687    if(e2apMsg != NULLP)
4688    {
4689       if(e2apMsg->choice.initiatingMessage != NULLP)
4690       {
4691          e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
4692          if(e2NodeConfigUpdate->protocolIEs.list.array != NULLP)
4693          {
4694             for(arrIdx = 0; arrIdx < e2NodeConfigUpdate->protocolIEs.list.count; arrIdx++)
4695             {
4696                if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx])
4697                {
4698
4699                   switch(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id)
4700                   {
4701                      case ProtocolIE_IDE2_id_TransactionID:
4702                         break;
4703
4704                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
4705                      {
4706                          e2NodeAddList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;
4707                          if(e2NodeAddList->list.array)
4708                          {
4709                              for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
4710                              {
4711                                 e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
4712                                  
4713                                 freeE2NodeComponentConfiguration(&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration);
4714                                 freeE2NodeComponentIdentifier(&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID);
4715                                 DU_FREE(e2NodeAddItem, sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
4716                              }
4717                              DU_FREE(e2NodeAddList->list.array, e2NodeAddList->list.size);
4718                          }
4719                          break;
4720                      }
4721                      case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate:
4722                         {
4723                            e2NodeUpdateList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdate_List;
4724                            if(e2NodeUpdateList->list.array)
4725                            {
4726                               for(e2NodeUpdateListIdx = 0; e2NodeUpdateListIdx< e2NodeUpdateList->list.count; e2NodeUpdateListIdx++)
4727                               {
4728                                  e2NodeUpdateItem = (E2nodeComponentConfigUpdate_ItemIEs_t *) e2NodeUpdateList->list.array[e2NodeUpdateListIdx];
4729                                  
4730                                  freeE2NodeComponentConfiguration(&e2NodeUpdateItem->value.choice.E2nodeComponentConfigUpdate_Item.e2nodeComponentConfiguration);
4731                                  freeE2NodeComponentIdentifier(&e2NodeUpdateItem->value.choice.E2nodeComponentConfigUpdate_Item.e2nodeComponentID);
4732                                  DU_FREE(e2NodeUpdateItem, sizeof(E2nodeComponentConfigUpdate_ItemIEs_t));
4733                               }
4734                               DU_FREE(e2NodeUpdateList->list.array, e2NodeUpdateList->list.size);
4735                            }
4736                            break;
4737                         }
4738                      case ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval:
4739                         {
4740                            e2NodeRemovalList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemoval_List;
4741                            if(e2NodeRemovalList->list.array)
4742                            {
4743                               for(e2NodeRemovalListIdx = 0; e2NodeRemovalListIdx< e2NodeRemovalList->list.count; e2NodeRemovalListIdx++)
4744                               {
4745                                  e2NodeRemovalItem = (E2nodeComponentConfigRemoval_ItemIEs_t *) e2NodeRemovalList->list.array[e2NodeRemovalListIdx];
4746
4747                                  freeE2NodeComponentIdentifier(&e2NodeRemovalItem->value.choice.E2nodeComponentConfigRemoval_Item.e2nodeComponentID);
4748                                  DU_FREE(e2NodeRemovalItem, sizeof(E2nodeComponentConfigRemoval_ItemIEs_t));
4749                               }
4750                               DU_FREE(e2NodeRemovalList->list.array, e2NodeRemovalList->list.size);
4751                            }
4752                            break;
4753                         }
4754                            
4755                      default:
4756                         break;
4757                   }
4758                   DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
4759                }
4760             }
4761             DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
4762          }
4763          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4764       }
4765       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4766    }
4767 }
4768
4769 /*******************************************************************
4770  *
4771  * @brief Buld and send the E2 node config update msg 
4772  *
4773  * @details
4774  *
4775  *    Function : BuildAndSendE2NodeConfigUpdate
4776  *
4777  *    Functionality:
4778  *         - Buld and send the E2 node config update msg
4779  *
4780  * @params[in] 
4781  * @return ROK     - success
4782  *         RFAILED - failure
4783  *
4784  * ****************************************************************/
4785
4786 uint8_t BuildAndSendE2NodeConfigUpdate(E2NodeConfigList *e2NodeList)
4787 {
4788    uint8_t ret = RFAILED;
4789    uint8_t arrIdx = 0,elementCnt = 0, transId=0;
4790    E2AP_PDU_t  *e2apMsg = NULLP;
4791    asn_enc_rval_t     encRetVal;       /* Encoder return value */
4792    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate = NULLP;
4793
4794    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update\n");
4795    do
4796    {
4797       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4798       if(e2apMsg == NULLP)
4799       {
4800          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4801          break;
4802       }
4803
4804       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4805       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4806       if(e2apMsg->choice.initiatingMessage == NULLP)
4807       {
4808          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4809          break;
4810       }
4811       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4812       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
4813       e2apMsg->choice.initiatingMessage->value.present = \
4814       InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate;
4815       e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
4816       
4817       elementCnt =1;
4818       if(e2NodeList->addE2NodeCount)
4819          elementCnt++;
4820       if(e2NodeList->updateE2NodeCount)
4821          elementCnt++;
4822       if(e2NodeList->removeE2NodeCount)
4823          elementCnt++;
4824
4825       e2NodeConfigUpdate->protocolIEs.list.count = elementCnt;
4826       e2NodeConfigUpdate->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdate_IEs_t*);
4827       DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
4828       if(e2NodeConfigUpdate->protocolIEs.list.array == NULLP)
4829       {
4830          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
4831          break;
4832       }
4833       
4834       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
4835       {
4836          DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
4837          if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx] == NULLP)
4838          {
4839             
4840             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
4841             break;
4842          }
4843       }
4844       
4845       if(arrIdx<elementCnt)
4846          break;
4847
4848       arrIdx = 0;
4849       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4850       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4851       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_TransactionID;
4852       transId = assignTransactionId();
4853       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
4854
4855       if(e2NodeList->addE2NodeCount)
4856       {
4857          arrIdx++;
4858          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition;
4859          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4860          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigAddition_List;
4861          if(BuildE2NodeConfigAddList(&(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List),\
4862          ProcedureCodeE2_id_E2nodeConfigurationUpdate, e2NodeList->addE2NodeCount, e2NodeList->addE2Node)!=ROK)
4863          {
4864             DU_LOG("\nERROR  -->  E2AP : Failed to create E2 Node config list");
4865             break;
4866          }
4867       }
4868       
4869       if(e2NodeList->updateE2NodeCount)
4870       {
4871          arrIdx++;
4872          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate;
4873          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4874          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigUpdate_List;
4875          if(BuildE2NodeConfigUpdateList(&e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdate_List,\
4876          e2NodeList->updateE2NodeCount, e2NodeList->updateE2Node) != ROK)
4877          {
4878
4879             DU_LOG("\nERROR  -->  E2AP : Failed to update the E2 node configuration");
4880             break;
4881          }
4882       }
4883       
4884       if(e2NodeList->removeE2NodeCount)
4885       {
4886          arrIdx++;
4887          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval;
4888          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4889          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigRemoval_List;
4890          if(BuildE2NodeConfigRemoveList(&e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemoval_List,\
4891          e2NodeList->removeE2NodeCount, e2NodeList->removeE2Node) != ROK)
4892          {
4893
4894             DU_LOG("\nERROR  -->  E2AP : Failed to remove the E2 node configuration");
4895             break;
4896          }
4897       }
4898
4899       /* Prints the Msg formed */
4900       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4901
4902       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4903       encBufSize = 0;
4904       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
4905       if(encRetVal.encoded == ENCODE_FAIL)
4906       {
4907          DU_LOG("\nERROR  -->  E2AP : Could not encode E2nodeConfigurationUpdate structure (at %s)\n",\
4908                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4909          break;
4910       }
4911       else
4912       {
4913          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2nodeConfigurationUpdate\n");
4914 #ifdef DEBUG_ASN_PRINT
4915          for(int i=0; i< encBufSize; i++)
4916          {
4917             printf("%x",encBuf[i]);
4918          }
4919 #endif
4920       }
4921       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize))
4922       {
4923          DU_LOG("\nERROR  -->  E2AP : Sending E2 node config update failed");
4924          break;
4925       }
4926
4927       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
4928       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
4929       memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.e2NodeConfigUpdate.configList, e2NodeList, sizeof(E2NodeConfigList));
4930       ret = ROK;
4931       break;
4932    }while(true);
4933    
4934    FreeE2NodeConfigUpdate(e2apMsg);
4935    return ret;
4936 }
4937
4938 /*******************************************************************
4939  *
4940  * @brief Deallocate the memory allocated for E2ResetRequest msg
4941  *
4942  * @details
4943  *
4944  *    Function : FreeE2ResetRequest
4945  *
4946  *    Functionality:
4947  *       - freeing the memory allocated for E2ResetRequest
4948  *
4949  * @params[in] E2AP_PDU_t *e2apMsg
4950  * @return ROK     - success
4951  *         RFAILED - failure
4952  *
4953  * ****************************************************************/
4954 void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg)
4955 {
4956    uint8_t ieIdx =0;
4957    ResetRequestE2_t  *resetReq = NULLP;
4958
4959    if(e2apMsg != NULLP)
4960    {
4961       if(e2apMsg->choice.initiatingMessage != NULLP)
4962       {
4963          resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4964          if(resetReq->protocolIEs.list.array)
4965          {
4966             for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
4967             {
4968                DU_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4969             }
4970             DU_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4971          }
4972          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4973       }
4974       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4975    }
4976 }
4977
4978 /*******************************************************************
4979  *
4980  * @brief Build and send the E2 reset request msg
4981  *
4982  * @details
4983  *
4984  *    Function : BuildAndSendE2ResetRequest
4985  *
4986  *    Functionality:
4987  *         - Buld and send the E2 reset request msg to RIC
4988  *
4989  * @params[in]
4990  *    Reset cause
4991  * @return ROK     - success
4992  *         RFAILED - failure
4993  *
4994  * ****************************************************************/
4995 uint8_t BuildAndSendE2ResetRequest(E2FailureCause resetCause)
4996 {
4997    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
4998    uint8_t ret = RFAILED;
4999    E2AP_PDU_t        *e2apMsg = NULLP;
5000    ResetRequestE2_t  *resetReq = NULLP;
5001    asn_enc_rval_t     encRetVal;       /* Encoder return value */
5002
5003    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Request\n");
5004
5005    do
5006    {
5007       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
5008       if(e2apMsg == NULLP)
5009       {
5010          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for E2AP-PDU failed");
5011          break;
5012       }
5013
5014       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
5015       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5016       if(e2apMsg->choice.initiatingMessage == NULLP)
5017       {
5018          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for initiatingMessage");
5019          break;
5020       }
5021
5022       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
5023       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
5024       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
5025       resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
5026
5027       elementCnt = 2;
5028       resetReq->protocolIEs.list.count = elementCnt;
5029       resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
5030
5031       DU_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
5032       if(!resetReq->protocolIEs.list.array)
5033       {
5034          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
5035             Reset Request IE array");
5036          break;
5037       }
5038
5039       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
5040       {
5041          DU_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
5042          if(!resetReq->protocolIEs.list.array[ieIdx])
5043          {
5044             DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
5045             Reset Request IE array element");
5046             break;
5047          }
5048       }
5049
5050       /* In case of failure */
5051       if(ieIdx < elementCnt)
5052          break;
5053
5054       ieIdx = 0;
5055       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
5056       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
5057       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
5058       transId = assignTransactionId();
5059       resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
5060
5061       ieIdx++;
5062       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
5063       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
5064       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
5065       fillE2Cause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, resetCause);
5066
5067       /* Prints the Msg formed */
5068       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5069
5070       memset(encBuf, 0, ENC_BUF_MAX_LEN);
5071       encBufSize = 0;
5072       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
5073             encBuf);
5074       if(encRetVal.encoded == ENCODE_FAIL)
5075       {
5076          DU_LOG("\nERROR  -->  E2AP : Could not encode reset request structure (at %s)\n",\
5077                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
5078          break;
5079       }
5080       else
5081       {
5082          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for reset request\n");
5083 #ifdef DEBUG_ASN_PRINT
5084          for(int i=0; i< encBufSize; i++)
5085          {
5086             printf("%x",encBuf[i]);
5087          }
5088 #endif
5089       }
5090       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
5091       {
5092          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
5093          break;
5094       }
5095
5096       /* In case the message is sent successfully, store the transaction info to
5097        * be used when response is received */
5098       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
5099       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5100
5101       ret = ROK;
5102       break;
5103    }while(true);
5104
5105    /* Free all memory */
5106    FreeE2ResetRequest(e2apMsg);
5107    return ret;
5108 }
5109
5110 /*******************************************************************
5111  *
5112  * @brief Deallocate the memory allocated for Reset Response msg
5113  *
5114  * @details
5115  *
5116  *    Function : freeAperDecodingOfE2ResetRsp
5117  *
5118  *    Functionality:
5119  *       - freeing the memory allocated for Reset response
5120  *
5121  * @params[in] ResetResponseE2_t *resetResponse
5122  * @return void
5123  *
5124  * ****************************************************************/
5125 void freeAperDecodingOfE2ResetRsp(ResetResponseE2_t *resetResponse)
5126 {
5127    uint8_t ieIdx;
5128
5129    if(resetResponse)
5130    {
5131       if(resetResponse->protocolIEs.list.array)
5132       {
5133          for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
5134          {
5135             if(resetResponse->protocolIEs.list.array[ieIdx])
5136             {
5137                switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
5138                {
5139                   case ProtocolIE_IDE2_id_TransactionID:
5140                      break;
5141
5142                   case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
5143                      break;
5144                }
5145                free(resetResponse->protocolIEs.list.array[ieIdx]);
5146             }
5147          }
5148          free(resetResponse->protocolIEs.list.array);
5149       }
5150    }
5151 }
5152
5153 /******************************************************************
5154  *
5155  * @brief Processes E2 Reset Response sent by RIC
5156  *
5157  * @details
5158  *
5159  *    Function : procResetResponse
5160  *
5161  *    Functionality: Processes E2 Reset Response sent by RIC
5162  *
5163  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5164  * @return void
5165  *
5166  * ****************************************************************/
5167 void procResetResponse(E2AP_PDU_t *e2apMsg)
5168 {
5169    bool invalidTransId=false;
5170    uint8_t ieIdx =0, transId =0;
5171    uint16_t ranFuncIdx=0;
5172    ResetResponseE2_t *resetResponse =NULLP;
5173
5174    DU_LOG("\nINFO   -->  E2AP : E2 Reset Response received");
5175    resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;;
5176
5177    for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
5178    {
5179       switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
5180       {
5181          case ProtocolIE_IDE2_id_TransactionID:
5182             {
5183                transId = resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
5184                if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) && \
5185                      (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
5186                {
5187                   memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
5188                }
5189                else
5190                {
5191                   DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
5192                   invalidTransId = true;
5193                }
5194                break;
5195             }
5196          case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
5197             {
5198                for(ranFuncIdx=0; ranFuncIdx<MAX_RAN_FUNCTION; ranFuncIdx++)
5199                {
5200                   if(duCb.e2apDb.ranFunction[ranFuncIdx].id >0)
5201                   {
5202                      deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList));
5203                      memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo));
5204                   }
5205                }
5206                break;
5207             }
5208          default:
5209             {
5210                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2 Reset Response : %ld",
5211                      resetResponse->protocolIEs.list.array[ieIdx]->id);
5212                break;
5213             }
5214       }
5215
5216       if(invalidTransId == true)
5217       {
5218          break;
5219       }
5220    }
5221
5222    freeAperDecodingOfE2ResetRsp(resetResponse);
5223 }
5224
5225 /******************************************************************
5226  *
5227  * @brief Deallocation of memory allocated by aper decoder for e2 setup Failure
5228  *
5229  * @details
5230  *
5231  *    Function : freeAperDecodingOfE2SetupFailure
5232  *
5233  *    Functionality: Deallocation of memory allocated by aper decoder for e2
5234  *    setup Failure
5235  *
5236  * @params[in] E2setupFailure_t *e2SetupFailure;
5237  * @return void
5238  *
5239  * ****************************************************************/
5240 void freeAperDecodingOfE2SetupFailure(E2setupFailure_t *e2SetupFailure)
5241 {
5242    uint8_t arrIdx;
5243
5244    if(e2SetupFailure)
5245    {
5246       if(e2SetupFailure->protocolIEs.list.array)
5247       {
5248          for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
5249          {
5250             if(e2SetupFailure->protocolIEs.list.array[arrIdx])
5251             {
5252                free(e2SetupFailure->protocolIEs.list.array[arrIdx]);  
5253             }
5254          }
5255          free(e2SetupFailure->protocolIEs.list.array);
5256       }
5257    }
5258 }
5259 /******************************************************************
5260  *
5261  * @brief Processes E2 Setup Failure sent by RIC
5262  *
5263  * @details
5264  *
5265  *    Function : procE2SetupFailure
5266  *
5267  *    Functionality: Processes E2 Setup failure sent by RIC
5268  *
5269  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5270  * @return ROK     - success
5271  *         RFAILED - failure
5272  *
5273  * ****************************************************************/
5274 void procE2SetupFailure(E2AP_PDU_t *e2apMsg)
5275 {
5276    uint8_t arrIdx =0, transId =0, timerValue=0; 
5277    E2setupFailure_t *e2SetupFailure;
5278
5279    DU_LOG("\nINFO   -->  E2AP : E2 Setup failure received"); 
5280    e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
5281
5282    for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
5283    {
5284       switch(e2SetupFailure->protocolIEs.list.array[arrIdx]->id)
5285       {
5286          case ProtocolIE_IDE2_id_TransactionID:
5287          {
5288             transId = e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
5289             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
5290                   (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
5291             {
5292                memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
5293             }
5294             else
5295             {
5296                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
5297                return ;
5298             }
5299             break;
5300          }
5301          case ProtocolIE_IDE2_id_TimeToWaitE2:
5302             {
5303                timerValue = convertE2WaitTimerEnumToValue(e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
5304                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR)) == FALSE)
5305                {
5306                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR, timerValue);
5307                }
5308                else
5309                {
5310                   DU_LOG("\nERROR   -->  E2AP : EVENT_E2_SETUP_TMR timer is already running");
5311                   return;
5312                }
5313                break; 
5314             }
5315       }
5316    }
5317
5318    freeAperDecodingOfE2SetupFailure(e2SetupFailure);
5319 }
5320 /******************************************************************
5321  *
5322  * @brief Deallocation of memory allocated by aper decoder for RIC service Query
5323  *
5324  * @details
5325  *
5326  *    Function : freeAperDecodingOfRicServiceQuery
5327  *
5328  *    Functionality: Deallocation of memory allocated by aper decoder for RIC
5329  *    service Query
5330  *
5331  * @params[in] RICserviceQuery_t *ricServiceQuery;
5332  * @return void
5333  *
5334  * ****************************************************************/
5335
5336 void freeAperDecodingOfRicServiceQuery(RICserviceQuery_t *ricServiceQuery)
5337 {
5338    uint8_t arrIdx,ranFuncIdx;
5339     RANfunctionsID_List_t *ranFuncAddedList;
5340
5341    if(ricServiceQuery)
5342    {
5343       if(ricServiceQuery->protocolIEs.list.array)
5344       {
5345          for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
5346          {
5347             if(ricServiceQuery->protocolIEs.list.array[arrIdx])
5348             {
5349                switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
5350                {
5351                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5352                   {
5353                      ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5354                      if(ranFuncAddedList->list.array)
5355                      {
5356                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
5357                         {
5358                            free(ranFuncAddedList->list.array[ranFuncIdx]);
5359                         }
5360                         free(ranFuncAddedList->list.array);;
5361                      }
5362                      break;
5363                   }
5364                   default:
5365                      break;
5366                }
5367                free(ricServiceQuery->protocolIEs.list.array[arrIdx]);
5368             }
5369          }
5370          free(ricServiceQuery->protocolIEs.list.array);
5371       }
5372    }
5373 }
5374 /*******************************************************************
5375  *
5376  * @brief Build RanFunction Delete List
5377  *
5378  * @details
5379  *
5380  *    Function : BuildRanFunctionDeleteList
5381  *
5382  * Functionality:  Build RanFunction Delete List
5383  *
5384  * @params[in]
5385  *    RANfunctionsID List
5386  *    Count of the RAN function
5387  *    Received RAN function list
5388  *
5389  * @return ROK     - success
5390  *         RFAILED - failure
5391  *
5392  ******************************************************************/
5393
5394 uint8_t BuildRanFunctionDeleteList(RANfunctionsID_List_t *deleteList, uint8_t count, RanFuncInfo *recvdRanFunc)
5395 {
5396    uint8_t ranFuncIdx=0;
5397    RANfunctionID_ItemIEs_t *delRanFuncItem;
5398
5399    if(count)
5400    {
5401       deleteList->list.count = count;
5402       deleteList->list.size = deleteList->list.count * sizeof(RANfunctionID_ItemIEs_t*);
5403       DU_ALLOC(deleteList->list.array, deleteList->list.size);
5404       if(deleteList->list.array == NULLP)
5405       {
5406          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
5407          return RFAILED;
5408       }
5409       for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
5410       {
5411          DU_ALLOC(deleteList->list.array[ranFuncIdx], sizeof(RANfunctionID_ItemIEs_t));
5412          if(deleteList->list.array[ranFuncIdx] == NULLP)
5413          {
5414             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
5415             return RFAILED;
5416          }
5417          delRanFuncItem= (RANfunctionID_ItemIEs_t *) deleteList->list.array[ranFuncIdx];
5418          delRanFuncItem->id = ProtocolIE_IDE2_id_RANfunctionID_Item;
5419          delRanFuncItem->criticality = CriticalityE2_ignore;
5420          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionID = recvdRanFunc[ranFuncIdx].id;
5421          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionRevision = recvdRanFunc[ranFuncIdx].revisionCounter;
5422
5423       }
5424    }
5425    return ROK;
5426 }
5427 /*******************************************************************
5428  *
5429  * @brief De Allocate  Ric Service Update message
5430  *
5431  * @details
5432  *
5433  *    Function : FreeRicServiceUpdate
5434  *
5435  *    Functionality: De-Allocating Ric Service Update message
5436  *
5437  * @params[in] E2AP_PDU_t *e2apMsg
5438
5439  * @return void
5440  *
5441  * ****************************************************************/
5442
5443 void FreeRicServiceUpdate(E2AP_PDU_t *e2apMsg)
5444 {
5445    uint8_t arrIdx = 0;
5446    uint8_t ranFuncAddListIdx=0, ranFuncDelIdx=0;
5447    RICserviceUpdate_t *ricServiceUpdate;
5448    RANfunctions_List_t *ranFunctionsList;
5449    RANfunction_ItemIEs_t *ranFuncItemIe;
5450    RANfunction_Item_t  *ranFunItem;
5451    RANfunctionsID_List_t *deleteList;
5452
5453    /* De-allocating Memory */
5454    if(e2apMsg != NULLP)
5455    {
5456       if(e2apMsg->choice.initiatingMessage != NULLP)
5457       {
5458          ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
5459          if(ricServiceUpdate->protocolIEs.list.array != NULLP)
5460          {
5461             for(arrIdx = 0; arrIdx < ricServiceUpdate->protocolIEs.list.count; arrIdx++)
5462             {
5463                if(ricServiceUpdate->protocolIEs.list.array[arrIdx] != NULLP)
5464                {
5465                   switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
5466                   {
5467                      case ProtocolIE_IDE2_id_TransactionID:
5468                         break;
5469
5470                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
5471                      case ProtocolIE_IDE2_id_RANfunctionsModified:
5472                         {
5473                            ranFunctionsList = &(ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List);
5474                            if(ranFunctionsList->list.array)
5475                            {
5476                               for(ranFuncAddListIdx= 0; ranFuncAddListIdx< ranFunctionsList->list.count; ranFuncAddListIdx++)
5477                               {
5478                                  if(ranFunctionsList->list.array[ranFuncAddListIdx])
5479                                  {
5480                                     ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncAddListIdx];
5481                                     ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
5482                                     DU_FREE(ranFunItem->ranFunctionOID.buf, ranFunItem->ranFunctionOID.size);
5483                                     DU_FREE(ranFunItem->ranFunctionDefinition.buf, ranFunItem->ranFunctionDefinition.size);
5484                                     DU_FREE(ranFunctionsList->list.array[ranFuncAddListIdx], sizeof(RANfunction_ItemIEs_t));
5485                                  }
5486                               }
5487                               DU_FREE(ranFunctionsList->list.array, ranFunctionsList->list.size);
5488                            }
5489                            break;
5490                         }
5491                      case ProtocolIE_IDE2_id_RANfunctionsDeleted:
5492                         {
5493                            deleteList= &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5494                            if(deleteList->list.array)
5495                            {
5496                               for(ranFuncDelIdx = 0; ranFuncDelIdx< deleteList->list.count; ranFuncDelIdx++)
5497                               {
5498                                  DU_FREE(deleteList->list.array[ranFuncDelIdx], sizeof(RANfunctionID_ItemIEs_t));
5499                               }
5500                               DU_FREE(deleteList->list.array, deleteList->list.size);
5501   
5502                            }
5503                            break;
5504                         }
5505                      default:
5506                         DU_LOG("\nERROR  --> E2AP: Invalid event at ricServiceUpdate %ld ",\
5507                               (ricServiceUpdate->protocolIEs.list.array[arrIdx]->id));
5508                         break;
5509                   }
5510                   DU_FREE(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
5511                }
5512             }
5513             DU_FREE(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
5514          }
5515          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5516       }
5517       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
5518    }
5519 }
5520
5521 /*******************************************************************
5522  *
5523  * @brief Builds and Send the RicServiceUpdateuest
5524  *
5525  * @details
5526  *
5527  *    Function : BuildAndSendRicServiceUpdate
5528  *
5529  * Functionality:Fills the RicServiceUpdateuest
5530  *
5531  * @return ROK     - success
5532  *         RFAILED - failure
5533  *
5534  ******************************************************************/
5535
5536 uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate)
5537 {
5538    uint8_t arrIdx = 0, elementCnt=0;
5539    uint8_t transId = 0, ret = RFAILED;
5540    bool memAllocFailed =false;
5541    E2AP_PDU_t        *e2apMsg = NULLP;
5542    RICserviceUpdate_t  *ricServiceUpdate = NULLP;
5543    asn_enc_rval_t     encRetVal;       /* Encoder return value */
5544
5545    DU_LOG("\nINFO   -->  E2AP : Building Ric Service Update\n");
5546    do
5547    {
5548       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
5549       if(e2apMsg == NULLP)
5550       {
5551          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
5552          break;
5553       }
5554       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
5555       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5556       if(e2apMsg->choice.initiatingMessage == NULLP)
5557       {
5558          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
5559          break;
5560       }
5561       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
5562       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
5563       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceUpdate;
5564       ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
5565       
5566       /* For TransId IE, set elementCnt to 1.
5567       If there is any item in the RAN function add list, RAN function modification list, or RAN function delete list, increment the elementCnt.*/
5568
5569       elementCnt =1;
5570       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5571         elementCnt++;
5572       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
5573          elementCnt++;
5574       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
5575          elementCnt++;
5576        
5577       ricServiceUpdate->protocolIEs.list.count = elementCnt;
5578       ricServiceUpdate->protocolIEs.list.size = elementCnt * sizeof(RICserviceUpdate_IEs_t*);
5579
5580       /* Initialize the E2Setup members */
5581       DU_ALLOC(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
5582       if(ricServiceUpdate->protocolIEs.list.array == NULLP)
5583       {
5584          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
5585          break;
5586       }
5587       
5588       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
5589       {
5590          DU_ALLOC(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
5591          if(ricServiceUpdate->protocolIEs.list.array[arrIdx] == NULLP)
5592          {
5593             memAllocFailed = true;
5594             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayIdx [%d]", arrIdx);
5595             break;
5596          }
5597       }
5598       if(memAllocFailed == true)
5599          break;
5600
5601       arrIdx = 0;
5602
5603       /* TransactionID */
5604       ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
5605       ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5606       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
5607       if(serviceUpdate.dir == E2_NODE_INITIATED)
5608          transId = assignTransactionId();
5609       else
5610         transId = serviceUpdate.transId;
5611       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
5612
5613       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5614       {
5615          arrIdx++;
5616          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAdded;
5617          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5618          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
5619          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,\
5620          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded, serviceUpdate.recvRanFuncList.ranFunToBeAdded) !=ROK)
5621          {
5622             break;
5623          }
5624       }
5625
5626       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
5627       {
5628          arrIdx++;
5629          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsModified;
5630          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5631          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
5632          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,
5633          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeModified, serviceUpdate.recvRanFuncList.ranFunToBeModified) !=ROK)
5634          {
5635             break;
5636          }
5637       }
5638
5639       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
5640       {
5641          arrIdx++;
5642          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsDeleted;
5643          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5644          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctionsID_List;
5645          if(BuildRanFunctionDeleteList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List,\
5646          serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted, serviceUpdate.recvRanFuncList.ranFunToBeDeleted) != ROK)
5647          {
5648             break;
5649          }
5650       }
5651       /* Prints the Msg formed */
5652       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5653
5654       memset(encBuf, 0, ENC_BUF_MAX_LEN);
5655       encBufSize = 0;
5656       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
5657       if(encRetVal.encoded == ENCODE_FAIL)
5658       {
5659          DU_LOG("\nERROR  -->  E2AP : Could not encode RicServiceUpdateuest structure (at %s)\n",\
5660                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
5661          break;
5662       }
5663       else
5664       {
5665          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RicServiceUpdateuest\n");
5666 #ifdef DEBUG_ASN_PRINT
5667          for(int i=0; i< encBufSize; i++)
5668          {
5669             printf("%x",encBuf[i]);
5670          }
5671 #endif
5672       }
5673       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
5674       {
5675          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
5676          break;
5677       }
5678       ret = ROK;
5679       break;
5680    }while(true);
5681    
5682    if(ret == ROK)
5683    {
5684       if(serviceUpdate.dir == E2_NODE_INITIATED)
5685       {
5686          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
5687          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5688       }
5689       else
5690       {
5691          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId = transId;
5692          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5693       }
5694       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.dir = serviceUpdate.dir;
5695       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.transId =transId;
5696       memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.recvRanFuncList, &serviceUpdate.recvRanFuncList, sizeof(E2TmpRanFunList));
5697    }
5698    FreeRicServiceUpdate(e2apMsg);
5699    return ret;
5700 }
5701 /******************************************************************
5702  *
5703  * @brief Processes RIC service Query sent by RIC
5704  *
5705  * @details
5706  *
5707  *    Function : procRicServiceQuery
5708  *
5709  *    Functionality: Processes RIC service Query sent by RIC
5710  *
5711  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5712  * @return ROK     - success
5713  *         RFAILED - failure
5714  *
5715  * ****************************************************************/
5716
5717 void procRicServiceQuery(E2AP_PDU_t *e2apMsg)
5718 {
5719    ConfigType action;
5720    uint16_t arrIdx =0, ranFuncIdx=0,tmpIdx=0;
5721    uint16_t id,revisionCcounter;
5722    bool tmpArray[MAX_RAN_FUNCTION] = {false};
5723    RICserviceQuery_t *ricServiceQuery=NULL;
5724    RicServiceUpdate ricUpdate;
5725    RANfunctionID_ItemIEs_t *ranFuncAddedItemIe;
5726    RANfunctionsID_List_t *ranFuncAddedList;
5727
5728    DU_LOG("\nINFO   -->  E2AP : RIC Service Query received");
5729    memset(&ricUpdate, 0, sizeof(RicServiceUpdate));
5730    ricUpdate.dir = RIC_INITIATED;
5731    ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
5732
5733    for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
5734    {
5735       switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
5736       {
5737          /* TODO completing in next patch/gerrit */
5738          case ProtocolIE_IDE2_id_TransactionID:
5739          {
5740             ricUpdate.transId = ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
5741             break;
5742          }
5743
5744          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5745          {
5746             ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5747             if(ranFuncAddedList->list.array)
5748             {
5749                for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
5750                {
5751                   if(ranFuncAddedList->list.array[ranFuncIdx])
5752                   {
5753                      /* Using the RAN function Id, identify the RAN function to be modified or deleted.  */
5754                      
5755                      ranFuncAddedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAddedList->list.array[ranFuncIdx];
5756                      id = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionID;
5757                      revisionCcounter = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision;
5758                      
5759                      if((id != duCb.e2apDb.ranFunction[id-1].id))
5760                      {
5761                         action = CONFIG_DEL;
5762                      }
5763                      else if((id == duCb.e2apDb.ranFunction[id-1].id)&&(revisionCcounter!=duCb.e2apDb.ranFunction[id-1].revisionCounter))
5764                      {
5765                         action = CONFIG_MOD;
5766                      }
5767
5768                      if(action == CONFIG_DEL)
5769                      {
5770                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].id = id;
5771                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].revisionCounter = revisionCcounter;
5772                         ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted++;
5773                      }
5774                      else if(action == CONFIG_MOD)
5775                      {
5776                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].id = id;
5777                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].revisionCounter = revisionCcounter;
5778                         ricUpdate.recvRanFuncList.numOfRanFunToBeModified++;
5779                      }
5780
5781                      /* If any ID is set to true, it means that the ID has been used in either modification or deletion list. 
5782                       * Else we will add the IDs into the added list */
5783                      tmpArray[id-1] = true;
5784                   }
5785                }
5786             }
5787             break;
5788          }
5789       }
5790    }
5791
5792    /*  Traversing the whole RAN function list in ducb to check if any new Ran function ids have been added. */
5793    for(arrIdx =0; arrIdx<MAX_RAN_FUNCTION; arrIdx++)
5794    {
5795       tmpIdx= ricUpdate.recvRanFuncList.numOfRanFunToBeAdded;
5796       if((duCb.e2apDb.ranFunction[arrIdx].id >0)&&(!tmpArray[arrIdx]))
5797       {
5798          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[arrIdx].id;
5799          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[arrIdx].revisionCounter;
5800          ricUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
5801       }
5802    }
5803
5804    if(BuildAndSendRicServiceUpdate(ricUpdate)!= ROK)
5805    {
5806       DU_LOG("\nERROR  -->  E2AP : Failed to build and send ric service update message");
5807    }
5808
5809    freeAperDecodingOfRicServiceQuery(ricServiceQuery);
5810 }
5811
5812 /******************************************************************
5813  *
5814  * @brief Deallocation of memory allocated by aper decoder for 
5815  *    RIC service update ack
5816  *
5817  * @details
5818  *
5819  *    Function : freeAperDecodingOfRicServiceUpdateAck
5820  *
5821  *    Functionality: Deallocation of memory allocated by aper decoder 
5822  *    for RIC service update ack
5823  *
5824  * @params[in] RICserviceUpdateAck_t *ricServiceAck;
5825  * @return void
5826  *
5827  * ****************************************************************/
5828
5829 void freeAperDecodingOfRicServiceUpdateAck(RICserviceUpdateAcknowledge_t *ricServiceAck)
5830 {
5831    uint8_t arrIdx=0,ranFuncIdx=0;
5832    RANfunctionsID_List_t *ranFuncAddedList=NULL;
5833
5834    if(ricServiceAck)
5835    {
5836       if(ricServiceAck->protocolIEs.list.array)
5837       {
5838          for(arrIdx=0; arrIdx<ricServiceAck->protocolIEs.list.count; arrIdx++)
5839          {
5840             if(ricServiceAck->protocolIEs.list.array[arrIdx])
5841             {
5842                switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id)
5843                {
5844                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5845                   {
5846                      ranFuncAddedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5847                      if(ranFuncAddedList->list.array)
5848                      {
5849                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
5850                         {
5851                            free(ranFuncAddedList->list.array[ranFuncIdx]);
5852                         }
5853                         free(ranFuncAddedList->list.array);
5854                      }
5855                      break;
5856                   }
5857                   default:
5858                      break;
5859                }
5860                free(ricServiceAck->protocolIEs.list.array[arrIdx]);  
5861             }
5862          }
5863          free(ricServiceAck->protocolIEs.list.array);
5864       }
5865    }
5866 }
5867
5868 /******************************************************************
5869  *
5870  * @brief Processes RIC service update ack sent by RIC
5871  *
5872  * @details
5873  *
5874  *    Function : procRicServiceUpdateAck
5875  *
5876  *    Functionality: Processes RIC service update ack sent by RIC
5877  *
5878  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5879  * @return ROK     - success
5880  *         RFAILED - failure
5881  *
5882  * ****************************************************************/
5883
5884 void procRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
5885 {
5886    uint8_t arrIdx =0, transId =0; 
5887    uint16_t id =0, tmpIdx=0, ranFuncIdx=0;
5888    RicServiceUpdate serviceUpdate;
5889    RANfunctionsIDcause_List_t *rejectedList=NULL;
5890    RICserviceUpdateAcknowledge_t *ricServiceAck=NULL;
5891    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
5892    
5893    DU_LOG("\nINFO   -->  E2AP : RIC service update ack received"); 
5894    memset(&serviceUpdate, 0, sizeof(RicServiceUpdate));
5895    ricServiceAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
5896    
5897    for(arrIdx=0; arrIdx<ricServiceAck->protocolIEs.list.count; arrIdx++)
5898    {
5899       switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id)
5900       {
5901          case ProtocolIE_IDE2_id_TransactionID:
5902          {
5903             transId = ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
5904             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
5905             (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
5906             {
5907               memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
5908             }
5909             else if((duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId == transId) &&\
5910             (duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
5911             {
5912               memset(&duCb.e2apDb.e2TransInfo.ricInitTransaction[transId], 0, sizeof(E2TransInfo));
5913             }
5914             else
5915             {
5916                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
5917                return ;
5918             }
5919             break;
5920          }
5921          
5922          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5923             break;
5924
5925          case ProtocolIE_IDE2_id_RANfunctionsRejected:
5926          {
5927             rejectedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
5928             if(rejectedList->list.array)
5929             {
5930                for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
5931                {
5932                   ranFuncRejectedItemIe =  (RANfunctionIDcause_ItemIEs_t*)rejectedList->list.array[ranFuncIdx];
5933                   id = ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID;
5934                   tmpIdx= serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded;
5935                   serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[id-1].id;
5936                   serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[id-1].revisionCounter;
5937                   serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
5938                }
5939             }
5940             break;
5941          }
5942
5943       }
5944    }
5945
5946    if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5947    {
5948       serviceUpdate.dir = E2_NODE_INITIATED;
5949       BuildAndSendRicServiceUpdate(serviceUpdate);
5950    }
5951    freeAperDecodingOfRicServiceUpdateAck(ricServiceAck);
5952 }
5953
5954 /******************************************************************
5955  *
5956  * @brief Deallocation of memory allocated by aper decoder for 
5957  *       RIC service update failure
5958  *
5959  * @details
5960  *
5961  *    Function : freeAperDecodingOfRicServiceUpdateFailure
5962  *
5963  *    Functionality: Deallocation of memory allocated by aper decoder 
5964  *    for RIC service update failure
5965  *
5966  * @params[in] RICserviceUpdateFailure_t *ricServiceFailure;
5967  * @return void
5968  *
5969  * ****************************************************************/
5970
5971 void freeAperDecodingOfRicServiceUpdateFailure(RICserviceUpdateFailure_t *ricServiceFailure)
5972 {
5973    uint8_t arrIdx=0;
5974
5975    if(ricServiceFailure)
5976    {
5977       if(ricServiceFailure->protocolIEs.list.array)
5978       {
5979          for(arrIdx=0; arrIdx<ricServiceFailure->protocolIEs.list.count; arrIdx++)
5980          {
5981             if(ricServiceFailure->protocolIEs.list.array[arrIdx])
5982             {
5983                free(ricServiceFailure->protocolIEs.list.array[arrIdx]);  
5984             }
5985          }
5986          free(ricServiceFailure->protocolIEs.list.array);
5987       }
5988    }
5989 }
5990
5991 /******************************************************************
5992  *
5993  * @brief Processes RIC service update failure sent by RIC
5994  *
5995  * @details
5996  *
5997  *    Function : procRicServiceUpdateFailure
5998  *
5999  *    Functionality: Processes RIC service update failure sent by RIC
6000  *
6001  * @params[in] E2AP_PDU_t ASN decoded E2AP message
6002  * @return ROK     - success
6003  *         RFAILED - failure
6004  *
6005  * ****************************************************************/
6006
6007 void procRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
6008 {
6009    uint8_t arrIdx =0, timerValue=0; 
6010    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
6011
6012    DU_LOG("\nINFO   -->  E2AP : RIC service update failure received"); 
6013    ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
6014
6015    for(arrIdx=0; arrIdx<ricServiceFailure->protocolIEs.list.count; arrIdx++)
6016    {
6017       switch(ricServiceFailure->protocolIEs.list.array[arrIdx]->id)
6018       {
6019          case ProtocolIE_IDE2_id_TransactionID:
6020             {
6021                break;
6022             }
6023          case ProtocolIE_IDE2_id_TimeToWaitE2:
6024             {
6025                timerValue = convertE2WaitTimerEnumToValue(ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
6026                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR)) == FALSE)
6027                {
6028                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR, timerValue);
6029                }
6030                else
6031                {
6032                   DU_LOG("\nERROR   -->  E2AP : EVENT_RIC_SERVICE_UPDATE_TMR  timer is already running");
6033                   return;
6034                }
6035                break; 
6036             }
6037          case ProtocolIE_IDE2_id_CauseE2:
6038             {
6039                break;
6040             }
6041       }
6042    }
6043
6044    freeAperDecodingOfRicServiceUpdateFailure(ricServiceFailure);
6045 }
6046
6047 /******************************************************************
6048  *
6049  * @brief DU Send E2 Node Configuration Update
6050  *
6051  * @details
6052  *
6053  *    Function : duSendE2NodeConfigurationUpdate 
6054  *
6055  *    Functionality: DU Send E2 Node Configuration Update
6056  *
6057  * @return ROK     - success
6058  *         RFAILED - failure
6059  *
6060  * ****************************************************************/
6061
6062 uint8_t duSendE2NodeConfigurationUpdate()
6063 {
6064    E2NodeConfigList e2NodeList;
6065    CmLList *node =NULL;
6066    E2NodeComponent *e2NodeComponentInfo=NULL;
6067
6068    memset(&e2NodeList, 0, sizeof(E2NodeConfigList));
6069    CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node);
6070    while(node)
6071    {
6072       e2NodeComponentInfo = (E2NodeComponent*)node->node;
6073
6074       if(e2NodeComponentInfo->addConfiguration)
6075       {
6076          e2NodeList.addE2Node[e2NodeList.addE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
6077          e2NodeList.addE2Node[e2NodeList.addE2NodeCount].componentId= e2NodeComponentInfo->componentId;
6078          e2NodeList.addE2NodeCount++;
6079          break;
6080       }
6081       if(e2NodeComponentInfo->updateConfiguration)
6082       {
6083          e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
6084          e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].componentId= e2NodeComponentInfo->componentId;
6085          e2NodeList.updateE2NodeCount++;
6086          break;
6087       }
6088       if(e2NodeComponentInfo->deleteConfiguration == true)
6089       {
6090          e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
6091          e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].componentId = e2NodeComponentInfo->componentId;
6092          e2NodeList.removeE2NodeCount++;
6093          break;
6094       }
6095       node = node->next;
6096    }
6097
6098    if(BuildAndSendE2NodeConfigUpdate(&e2NodeList) !=ROK)
6099    {
6100       DU_LOG("\nERROR  -->  E2AP : Failed to build and send e2 node config update message to RIC_stub");
6101       return RFAILED;
6102    }
6103    return ROK;
6104 }
6105
6106 /*******************************************************************
6107  *
6108  * @brief Free RIC Subscription Modification Required
6109  *
6110  * @details
6111  *
6112  *    Function : FreeRicSubsModRequired
6113  *
6114  * Functionality: Freqq RIC Subscription Modification required
6115  *
6116  * @param  E2AP Message PDU to be freed
6117  * @return void
6118  *
6119  ******************************************************************/
6120 void FreeRicSubsModRequired(E2AP_PDU_t *e2apMsg)
6121 {
6122    uint8_t ieIdx = 0, arrIdx = 0;
6123    RICsubscriptionModificationRequired_t  *ricSubsModReqd = NULLP;
6124    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
6125    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
6126    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
6127
6128    if(e2apMsg)
6129    {
6130       if(e2apMsg->choice.initiatingMessage)
6131       {
6132          ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired;
6133          if(ricSubsModReqd->protocolIEs.list.array)
6134          {
6135             for(ieIdx = 0; ieIdx < ricSubsModReqd->protocolIEs.list.count; ieIdx++)
6136             {
6137                if(ricSubsModReqd->protocolIEs.list.array[ieIdx])
6138                {
6139                   ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6140                   switch(ricSubsModReqdIe->id)
6141                   {
6142                      case ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List:
6143                         {
6144                            actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
6145                            if(actionToBeModList->list.array)
6146                            {
6147                               for(arrIdx = 0; arrIdx < actionToBeModList->list.count; arrIdx++)
6148                               { 
6149                                  DU_FREE(actionToBeModList->list.array[arrIdx], \
6150                                     sizeof(RICaction_RequiredToBeModified_ItemIEs_t));
6151                               }
6152                               DU_FREE(actionToBeModList->list.array, actionToBeModList->list.size);
6153                            }
6154                            break;
6155                         }
6156
6157                      case ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List:
6158                         {
6159                            actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
6160                            if(actionToBeRmvList->list.array)
6161                            {
6162                               for(arrIdx = 0; arrIdx < actionToBeRmvList->list.count; arrIdx++)
6163                               { 
6164                                  DU_FREE(actionToBeRmvList->list.array[arrIdx], \
6165                                     sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t));
6166                               }
6167                               DU_FREE(actionToBeRmvList->list.array, actionToBeRmvList->list.size);
6168                            }
6169                            break;
6170                         }
6171
6172                      default:
6173                         break;
6174                   }
6175                   DU_FREE(ricSubsModReqd->protocolIEs.list.array[ieIdx], \
6176                         sizeof(RICsubscriptionModificationRequired_IEs_t));
6177                }
6178             }
6179             DU_FREE(ricSubsModReqd->protocolIEs.list.array, ricSubsModReqd->protocolIEs.list.size);
6180          }
6181          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
6182       }
6183       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
6184    }
6185 }
6186
6187 /* A RIC Subscription includes RIC subsequent action only for RIC Insert service.
6188  * However, E2SM-KPM supports only RIC Report service.
6189  * Hence there is no subsequent action in RIC subscription that may require modification.
6190  * So commenting the action-modification IEs for the time being
6191  */
6192 #if 0
6193 /*******************************************************************
6194  *
6195  * @brief Fill Action required to be modified list
6196  *
6197  * @details
6198  *
6199  *    Function : FillActionReqdToBeModList
6200  *
6201  * Functionality: Fill Action required to be modified list
6202  *
6203  * @param  RIC Actions Required To Be Modified List to be filled
6204  *         Number of actions to be modified
6205  *         RIC Subscription DB
6206  * @return ROK     - success
6207  *         RFAILED - failure
6208  *
6209  ******************************************************************/
6210 uint8_t FillActionReqdToBeModList(RICactions_RequiredToBeModified_List_t *actionToBeModList, uint8_t numActionsMod, \
6211    RicSubscription *ricSubscription)
6212 {
6213    uint8_t arrIdx = 0, actionIdx = 0;
6214    RICaction_RequiredToBeModified_ItemIEs_t *actionToBeMod = NULL;
6215
6216    actionToBeModList->list.count = numActionsMod;
6217    actionToBeModList->list.size = numActionsMod * sizeof(RICaction_RequiredToBeModified_ItemIEs_t *);
6218    DU_ALLOC(actionToBeModList->list.array, actionToBeModList->list.size);
6219    if(!actionToBeModList->list.array)
6220    {
6221       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6222       return RFAILED;
6223    }
6224
6225    arrIdx = 0;
6226    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
6227    {
6228       if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD)
6229       {
6230          DU_ALLOC(actionToBeModList->list.array[arrIdx], sizeof(RICaction_RequiredToBeModified_ItemIEs_t));
6231          if(!actionToBeModList->list.array[arrIdx])
6232          {
6233             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6234             return RFAILED;
6235          }
6236          actionToBeMod = (RICaction_RequiredToBeModified_ItemIEs_t *)actionToBeModList->list.array[arrIdx];
6237
6238          actionToBeMod->id = ProtocolIE_IDE2_id_RICaction_RequiredToBeModified_Item;
6239          actionToBeMod->criticality = CriticalityE2_reject;
6240          actionToBeMod->value.present = \
6241             RICaction_RequiredToBeModified_ItemIEs__value_PR_RICaction_RequiredToBeModified_Item;
6242          actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricActionID = \
6243             ricSubscription->actionSequence[actionIdx].actionId;
6244          actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricTimeToWait = RICtimeToWait_w5ms;
6245
6246          arrIdx++;
6247       }
6248    }
6249
6250    return ROK;
6251 }
6252 #endif
6253
6254 /*******************************************************************
6255  *
6256  * @brief Fill Action required to be removed list
6257  *
6258  * @details
6259  *
6260  *    Function : FillActionReqdToBeRmvList
6261  *
6262  * Functionality: Fill Action required to be removed list
6263  *
6264  * @param  RIC Actions Required To Be Removed List to be filled
6265  *         Number of actions to be removed
6266  *         RIC Subscription DB
6267  * @return ROK     - success
6268  *         RFAILED - failure
6269  *
6270  ******************************************************************/
6271 uint8_t FillActionReqdToBeRmvList(RICactions_RequiredToBeRemoved_List_t *actionToBeRmvList, uint8_t numActionsRmv, \
6272    RicSubscription *ricSubscription)
6273 {
6274    uint8_t arrIdx = 0, actionIdx = 0;
6275    RICaction_RequiredToBeRemoved_ItemIEs_t *actionToBeRmv = NULL;
6276
6277    actionToBeRmvList->list.count = numActionsRmv;
6278    actionToBeRmvList->list.size = numActionsRmv * sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t *);
6279    DU_ALLOC(actionToBeRmvList->list.array, actionToBeRmvList->list.size);
6280    if(!actionToBeRmvList->list.array)
6281    {
6282       DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6283       return RFAILED;
6284    }
6285
6286    arrIdx = 0;
6287    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
6288    {
6289       if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL)
6290       {
6291          DU_ALLOC(actionToBeRmvList->list.array[arrIdx], sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t));
6292          if(!actionToBeRmvList->list.array[arrIdx])
6293          {
6294             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6295             return RFAILED;
6296          }
6297          actionToBeRmv = (RICaction_RequiredToBeRemoved_ItemIEs_t *)actionToBeRmvList->list.array[arrIdx];
6298
6299          actionToBeRmv->id = ProtocolIE_IDE2_id_RICaction_RequiredToBeRemoved_Item;
6300          actionToBeRmv->criticality = CriticalityE2_reject;
6301          actionToBeRmv->value.present = \
6302             RICaction_RequiredToBeRemoved_ItemIEs__value_PR_RICaction_RequiredToBeRemoved_Item;
6303          actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.ricActionID = \
6304             ricSubscription->actionSequence[actionIdx].actionId;
6305          fillE2Cause(&actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.cause, \
6306             ricSubscription->actionSequence[actionIdx].failureCause);
6307
6308          arrIdx++;
6309       }
6310    }
6311
6312    return ROK;
6313 }
6314
6315 /*******************************************************************
6316  *
6317  * @brief Fill RIC Subscription Modification Required IEs
6318  *
6319  * @details
6320  *
6321  *    Function : FillRicSubsModRequired
6322  *
6323  * Functionality: Fill RIC Subscription Modification Required IEs
6324  *
6325  * @param  RIC Subscription Modification Required IEs to be filled
6326  *         RIC Subscription DB
6327  * @return ROK     - success
6328  *         RFAILED - failure
6329  *
6330  ******************************************************************/
6331 uint8_t FillRicSubsModRequired(RICsubscriptionModificationRequired_t *ricSubsModReqd, RicSubscription *ricSubscription)
6332 {
6333    uint8_t ieIdx = 0, elementCnt=0, actionIdx = 0;
6334    uint8_t numActionsMod = 0, numActionsRmv = 0;
6335    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
6336    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
6337
6338 /* Unused in case of E2SM-KPM */
6339 #if 0
6340    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
6341 #endif
6342
6343    /* Count number of Actions to be modified or deleted */
6344    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
6345    {
6346       if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD)
6347          numActionsMod++;
6348       else if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL)
6349          numActionsRmv++;
6350    }
6351
6352    /* Count number of IEs to be added to messages */
6353    elementCnt = 2;
6354    if(numActionsMod)
6355       elementCnt++;
6356    if(numActionsRmv)
6357       elementCnt++;
6358
6359    ricSubsModReqd->protocolIEs.list.count = elementCnt;
6360    ricSubsModReqd->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationRequired_IEs_t *);
6361    DU_ALLOC(ricSubsModReqd->protocolIEs.list.array, ricSubsModReqd->protocolIEs.list.size);
6362    if(!ricSubsModReqd->protocolIEs.list.array)
6363    {
6364       DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6365       return RFAILED;
6366    }
6367
6368    for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
6369    {
6370       DU_ALLOC(ricSubsModReqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRequired_IEs_t));
6371       if(!ricSubsModReqd->protocolIEs.list.array[ieIdx])
6372       {
6373          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6374          return RFAILED;
6375       }
6376    }
6377
6378    /* RIC Request ID */
6379    ieIdx = 0;
6380    ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6381    ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICrequestID;
6382    ricSubsModReqdIe->criticality = CriticalityE2_reject;
6383    ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RICrequestID;
6384    ricSubsModReqdIe->value.choice.RICrequestID.ricRequestorID = ricSubscription->requestId.requestorId;
6385    ricSubsModReqdIe->value.choice.RICrequestID.ricInstanceID = ricSubscription->requestId.instanceId;
6386
6387    /* RAN Function ID */
6388    ieIdx++;
6389    ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6390    ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RANfunctionID;
6391    ricSubsModReqdIe->criticality = CriticalityE2_reject;
6392    ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RANfunctionID;
6393    ricSubsModReqdIe->value.choice.RANfunctionID = ricSubscription->ranFuncId;
6394
6395 /* A RIC Subscription includes RIC subsequent action only for RIC Insert service.
6396  * However, E2SM-KPM supports only RIC Report service.
6397  * Hence there is no subsequent action in RIC subscription that may require modification.
6398  * So commenting the action-modification IEs for the time being
6399  */
6400 #if 0
6401    /* RIC Actions Required to be Modified */
6402    if(numActionsMod)
6403    {
6404       ieIdx++;
6405       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6406       ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List;
6407       ricSubsModReqdIe->criticality = CriticalityE2_reject;
6408       ricSubsModReqdIe->value.present = \
6409          RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeModified_List;
6410       actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
6411
6412       if(FillActionReqdToBeModList(actionToBeModList, numActionsMod, ricSubscription) != ROK)
6413       {
6414          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill actions required to be modified list", __func__);
6415          return RFAILED;
6416       }
6417    }
6418 #endif
6419
6420    /* RIC Actions Required to be removed */
6421    if(numActionsRmv)
6422    {
6423       ieIdx++;
6424       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
6425       ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List;
6426       ricSubsModReqdIe->criticality = CriticalityE2_reject;
6427       ricSubsModReqdIe->value.present = \
6428          RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeRemoved_List;
6429       actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
6430
6431       if(FillActionReqdToBeRmvList(actionToBeRmvList, numActionsRmv, ricSubscription) != ROK)
6432       {
6433          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill actions required to be removed list", __func__);
6434          return RFAILED;
6435       }
6436    }
6437
6438    return ROK;
6439 }
6440
6441 /*******************************************************************
6442  *
6443  * @brief Builds and Send RIC Subscription Modification Required
6444  *        message
6445  *
6446  * @details
6447  *
6448  *    Function : BuildAndSendRicSubsModRequired
6449  *
6450  * Functionality:  Builds and Send RIC Subscription Modification 
6451  *    Required message
6452  *
6453  * @param  RIC Subscription DB
6454  * @return ROK     - success
6455  *         RFAILED - failure
6456  *
6457  ******************************************************************/
6458 uint8_t BuildAndSendRicSubsModRequired(RicSubscription *ricSubscription)
6459 {
6460    uint8_t ret = RFAILED;
6461    E2AP_PDU_t        *e2apMsg = NULLP;
6462    RICsubscriptionModificationRequired_t  *ricSubsModReqd = NULLP;
6463    asn_enc_rval_t     encRetVal;       /* Encoder return value */
6464
6465    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Required \n");
6466    while(true)
6467    {
6468       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
6469       if(e2apMsg == NULLP)
6470       {
6471          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6472          break;
6473       }
6474
6475       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
6476       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
6477       if(e2apMsg->choice.initiatingMessage == NULLP)
6478       {
6479          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
6480          break;
6481       }
6482       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
6483       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired;
6484       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionModificationRequired;
6485
6486       ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired;
6487
6488       if(FillRicSubsModRequired(ricSubsModReqd, ricSubscription) != ROK)
6489       {
6490          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Subscription Modification Required IEs", __func__);
6491          break;
6492       }
6493       
6494       /* Encode */
6495       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6496
6497       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6498       encBufSize = 0;
6499       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6500       if(encRetVal.encoded == ENCODE_FAIL)
6501       {
6502          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Modifiction Required structure (at %s)\n",\
6503                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6504          break;
6505       }
6506       else
6507       {
6508          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RIC Subscription Modification Required \n");
6509 #ifdef DEBUG_ASN_PRINT
6510          for(int i=0; i< encBufSize; i++)
6511          {
6512             printf("%x",encBuf[i]);
6513          }
6514 #endif
6515       }
6516       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
6517       {
6518          DU_LOG("\nERROR  -->  E2AP : Sending RIC Subscription Modification Required failed");
6519       }
6520
6521       ret = ROK;
6522       break;
6523    }
6524
6525    /* Free RIC Subscription modification required */
6526    FreeRicSubsModRequired(e2apMsg);
6527    return ret;
6528 }
6529
6530 /*******************************************************************
6531  *
6532  * @brief Free APER decoding of RIC Subscription Modification Confirm
6533  *
6534  * @details
6535  *
6536  *    Function : freeAperDecodingOfRicSubsModConfirm
6537  *
6538  * Functionality:  Free APER decoding of RIC Subscription 
6539  *   Modification Confirm
6540  *
6541  * @param  E2AP Message PDU
6542  * @return void
6543  *
6544  ******************************************************************/
6545 void freeAperDecodingOfRicSubsModConfirm(E2AP_PDU_t *e2apMsg)
6546 {
6547    uint8_t ieIdx = 0, arrIdx=0;
6548    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
6549    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
6550    RICactions_ConfirmedForModification_List_t *modCfmList = NULLP;
6551    RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP;
6552    RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP;
6553    RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP;
6554
6555    if(e2apMsg && e2apMsg->choice.successfulOutcome)
6556    {
6557       ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
6558       if(ricSubsModCfm->protocolIEs.list.array)
6559       {
6560          for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++)
6561          {
6562             if(ricSubsModCfm->protocolIEs.list.array[ieIdx])
6563             {
6564                ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
6565                switch(ricSubsModCfmIe->id)
6566                {
6567                   case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List:
6568                      {
6569                         modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List;
6570                         if(modCfmList->list.array)
6571                         {
6572                            for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
6573                            {
6574                               if(modCfmList->list.array[arrIdx])
6575                                  free(modCfmList->list.array[arrIdx]);
6576                            }
6577                            free(modCfmList->list.array);
6578                         }
6579                         break;
6580                      }
6581
6582                   case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List:
6583                      {
6584                         modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List;
6585                         if(modRefusedList->list.array)
6586                         {
6587                            for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
6588                            {
6589                               if(modRefusedList->list.array[arrIdx])
6590                                  free(modRefusedList->list.array[arrIdx]);
6591                            }
6592                            free(modRefusedList->list.array);
6593                         }
6594                         break;
6595                      }
6596
6597                   case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List:
6598                      {
6599                         rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List;
6600                         if(rmvCfmList->list.array)
6601                         {
6602                            for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
6603                            {
6604                               if(rmvCfmList->list.array[arrIdx])
6605                                  free(rmvCfmList->list.array[arrIdx]);
6606                            }
6607                            free(rmvCfmList->list.array);
6608                         }
6609                         break;
6610                      }
6611
6612                   case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List:
6613                      {
6614                         rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List;
6615                         if(rmvFailList->list.array)
6616                         {
6617                            for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
6618                            {
6619                               if(rmvFailList->list.array[arrIdx])
6620                                  free(rmvFailList->list.array[arrIdx]);
6621                            }
6622                            free(rmvFailList->list.array);
6623                         }
6624                         break;
6625                      }
6626
6627                   default:
6628                      break;
6629
6630                }
6631                free(ricSubsModCfmIe);
6632             }
6633          }
6634          free(ricSubsModCfm->protocolIEs.list.array);
6635       }
6636    }
6637 }
6638
6639 /*******************************************************************
6640  *
6641  * @brief Process RIC Subscription Modification Confirm Message
6642  *
6643  * @details
6644  *
6645  *    Function : procRicSubscriptionModificationConfirm
6646  *
6647  * Functionality:  Process RIC Subscription Modification Confirm
6648  *    Message received from RIC. 
6649  *
6650  * @param  E2AP Message PDU
6651  * @return void
6652  *
6653  ******************************************************************/
6654 void procRicSubscriptionModificationConfirm(E2AP_PDU_t *e2apMsg)
6655 {
6656    uint8_t actionId = 0, ieIdx = 0, arrIdx = 0;
6657    uint16_t ranFuncId = 0;
6658    bool procFailure = false;
6659    RicRequestId ricReqId;
6660    RanFunction *ranFuncDb = NULLP;
6661    CmLList *ricSubsNode = NULLP;
6662    RicSubscription *ricSubsDb = NULLP;
6663    ActionInfo *actionDb = NULLP;
6664
6665    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
6666    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
6667
6668 /* Not used in case of E2SM-KPM */
6669 #if 0
6670    RICactions_ConfirmedForModification_List_t *modCfmList = NULLP;
6671    RICaction_ConfirmedForModification_ItemIEs_t *modCfmListItem = NULLP;
6672
6673    RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP;
6674    RICaction_RefusedToBeModified_ItemIEs_t *modRefusedListItem = NULLP;
6675 #endif
6676
6677    RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP;
6678    RICaction_ConfirmedForRemoval_ItemIEs_t *rmvCfmListItem = NULLP;
6679
6680    RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP;
6681    RICaction_RefusedToBeRemoved_ItemIEs_t *rmvFailListItem = NULLP;
6682
6683    DU_LOG("\nINFO   -->  E2AP : %s: Received RIC Subscription Modification Confirm", __func__);
6684
6685    do{
6686       if(!e2apMsg)
6687       {
6688          DU_LOG("\nERROR  -->  E2AP : %s: E2AP Message is NULL", __func__);
6689          break;
6690       }
6691
6692       if(!e2apMsg->choice.successfulOutcome)
6693       {
6694          DU_LOG("\nERROR  -->  E2AP : %s: Successful Outcome in E2AP message is NULL", __func__);
6695          break;
6696       }
6697
6698       ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
6699       if(!ricSubsModCfm->protocolIEs.list.array)
6700       {
6701          DU_LOG("\nERROR  -->  E2AP : %s: Array conatining E2AP message IEs is null", __func__);
6702          break;
6703       }
6704
6705       for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++)
6706       {
6707          if(!ricSubsModCfm->protocolIEs.list.array[ieIdx])
6708          {
6709             DU_LOG("\nERROR  -->  E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx);
6710             break;
6711          }
6712
6713          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
6714          switch(ricSubsModCfmIe->id)
6715          {
6716             case ProtocolIE_IDE2_id_RICrequestID:
6717                {
6718                   memset(&ricReqId, 0, sizeof(RicRequestId));
6719                   ricReqId.requestorId = ricSubsModCfmIe->value.choice.RICrequestID.ricRequestorID;
6720                   ricReqId.instanceId = ricSubsModCfmIe->value.choice.RICrequestID.ricInstanceID;
6721                   break;
6722                }
6723
6724             case ProtocolIE_IDE2_id_RANfunctionID:
6725                {
6726                   ranFuncId = ricSubsModCfmIe->value.choice.RANfunctionID;
6727                   ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
6728                   if(!ranFuncDb)
6729                   {
6730                      DU_LOG("\nERROR  -->  E2AP : %s: RAN Function ID [%d] not found", __func__, ranFuncId);
6731                      procFailure = true;
6732                      break;
6733                   }
6734
6735                   ricSubsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode); 
6736                   if(!ricSubsDb)
6737                   {
6738                      DU_LOG("\nERROR  -->  E2AP : %s: RIC Subscription not found for Requestor_ID [%d] Instance_ID [%d]",\
6739                            __func__, ricReqId.requestorId, ricReqId.instanceId);
6740                      procFailure = true;
6741                      break;
6742                   }
6743
6744                   break;
6745                }
6746
6747 /* A RIC Subscription includes RIC subsequent action only for RIC Insert service. 
6748  * However, E2SM-KPM supports only RIC Report service. 
6749  * Hence there is no subsequent action in RIC subscription that may require modification. 
6750  * So commenting the action-modification IEs for the time being 
6751  */
6752 #if 0
6753             case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List:
6754                {
6755                   modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List;
6756                   for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
6757                   {
6758                      modCfmListItem = (RICaction_ConfirmedForModification_ItemIEs_t *)modCfmList->list.array[arrIdx];
6759                      actionId = modCfmListItem->value.choice.RICaction_ConfirmedForModification_Item.ricActionID;
6760
6761                      actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6762                      if(!actionDb)
6763                      {
6764                         DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6765                      }
6766                      else
6767                      {
6768                         actionDb->action = CONFIG_UNKNOWN;
6769                         /* Further handling can be added here in future once the
6770                          * use case of this procedure is identified */
6771                      }
6772                      actionDb = NULLP;
6773                   }
6774                   break;
6775                }
6776
6777             case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List:
6778                {
6779                   modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List;
6780                   for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
6781                   {
6782                     modRefusedListItem = (RICaction_RefusedToBeModified_ItemIEs_t *)modRefusedList->list.array[arrIdx];
6783                     actionId = modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.ricActionID;
6784                     actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6785                     if(!actionDb)
6786                     {
6787                        DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6788                     }
6789                     else
6790                     {
6791                        /* Spec doesnt mention if in case of failure, DU should retry for modify action 
6792                         * Hence, chaging the action from CONFIG_MOD to CONFIG_UNKNOWN
6793                         */
6794                         actionDb->action = CONFIG_UNKNOWN;
6795                     }
6796                     actionDb = NULLP;
6797                   }
6798                   break;
6799                }
6800 #endif
6801
6802             case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List:
6803                {
6804                   rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List;
6805                   for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
6806                   {
6807                      rmvCfmListItem = (RICaction_ConfirmedForRemoval_ItemIEs_t *)rmvCfmList->list.array[arrIdx];
6808                      actionId = rmvCfmListItem->value.choice.RICaction_ConfirmedForRemoval_Item.ricActionID;
6809                      actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6810                      if(!actionDb)
6811                      {
6812                         DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6813                      }
6814                      else
6815                      {
6816                         deleteActionSequence(actionDb);
6817                         actionDb =NULLP;
6818                         ricSubsDb->numOfActions--;
6819                         /* Further handling can include :
6820                          * Deletion of this action from all DU layers 
6821                          */
6822                      }
6823                      actionDb = NULLP;
6824                   }
6825                   break;
6826                }
6827
6828             case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List:
6829                {
6830                   rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List;
6831                   for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
6832                   {
6833                      rmvFailListItem = (RICaction_RefusedToBeRemoved_ItemIEs_t *)rmvFailList->list.array[arrIdx];
6834                      actionId = rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.ricActionID;
6835                      actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6836                      if(!actionDb)
6837                      {
6838                         DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6839                      }
6840                      else
6841                      {
6842                         actionDb->action = CONFIG_UNKNOWN;
6843                      }
6844                      actionDb = NULLP;
6845                   }
6846                   break;
6847                }
6848
6849             default:
6850                break;
6851          } /* End of switch for Protocol IE Id */
6852
6853          if(procFailure)
6854             break;
6855       } /* End of for loop for Protocol IE list */
6856
6857       break;
6858    }while(true);
6859
6860    freeAperDecodingOfRicSubsModConfirm(e2apMsg);
6861    return;
6862 }
6863
6864 /******************************************************************
6865 * @brief Deallocate the memory allocated for E2 Reset Response
6866 *
6867 * @details
6868 *
6869 *    Function : FreeE2ResetResponse
6870 *
6871 *    Functionality:
6872 *       - freeing the memory allocated for E2ResetResponse
6873 *
6874 * @params[in] E2AP_PDU_t *e2apMsg
6875 * @return ROK     - success
6876 *         RFAILED - failure
6877 *
6878 * ****************************************************************/
6879 void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg)
6880 {
6881    uint8_t ieIdx =0;
6882    ResetResponseE2_t *resetResponse;
6883
6884    if(e2apMsg != NULLP)
6885    {
6886       if(e2apMsg->choice.successfulOutcome != NULLP)
6887       {
6888          resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
6889          if(resetResponse->protocolIEs.list.array)
6890          {
6891             for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
6892             {
6893                if(resetResponse->protocolIEs.list.array[ieIdx])
6894                {
6895                   DU_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
6896                }
6897             }
6898             DU_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
6899          }
6900
6901          DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
6902       }
6903       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
6904    }
6905 }
6906
6907 /*******************************************************************
6908  *
6909  * @brief Buld and send the E2 Reset Response msg
6910  *
6911  * @details
6912  *
6913  *    Function : BuildAndSendE2ResetResponse
6914  *
6915  *    Functionality:
6916  *         - Buld and send the E2 Reset Response Message
6917  *
6918  * @params[in] Trans Id
6919  * @return ROK     - success
6920  *         RFAILED - failure
6921  *
6922  * ****************************************************************/
6923 uint8_t BuildAndSendResetResponse(uint8_t transId)
6924 {
6925    uint8_t           ieIdx = 0, elementCnt = 0;
6926    uint8_t           ret = RFAILED;
6927    E2AP_PDU_t        *e2apMsg = NULLP;
6928    ResetResponseE2_t *resetResponse;
6929    asn_enc_rval_t    encRetVal;       /* Encoder return value */
6930
6931    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
6932    do
6933    {
6934       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
6935       if(e2apMsg == NULLP)
6936       {
6937          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
6938          break;
6939       }
6940       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
6941
6942       DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
6943       if(e2apMsg->choice.successfulOutcome == NULLP)
6944       {
6945          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
6946          break;
6947       }
6948
6949       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
6950       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
6951       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
6952       resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
6953
6954       elementCnt = 1;
6955       resetResponse->protocolIEs.list.count = elementCnt;
6956       resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
6957       DU_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
6958       if(!resetResponse->protocolIEs.list.array)
6959       {
6960          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
6961          break;
6962       }
6963
6964       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
6965       {
6966          DU_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
6967          if(!resetResponse->protocolIEs.list.array[ieIdx])
6968          {
6969             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
6970             break;
6971          }
6972       }
6973       if(ieIdx < elementCnt)
6974          break;
6975
6976       ieIdx = 0;
6977       resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
6978       resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6979       resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
6980       resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
6981
6982       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6983
6984       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6985       encBufSize = 0;
6986       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6987       if(encRetVal.encoded == ENCODE_FAIL)
6988       {
6989          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
6990                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6991          break;
6992       }
6993       else
6994       {
6995          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
6996          for(int i=0; i< encBufSize; i++)
6997          {
6998             DU_LOG("%x",encBuf[i]);
6999          }
7000       }
7001
7002       /* Sending msg */
7003       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
7004       {
7005          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
7006          break;
7007       }
7008
7009       ret = ROK;
7010       break;
7011    }while(true);
7012
7013    FreeE2ResetResponse(e2apMsg);
7014    return ret;
7015 }
7016
7017 /******************************************************************
7018  *
7019  * @brief Deallocation of memory allocated by aper decoder for reset req
7020  *
7021  * @details
7022  *
7023  *    Function : freeAperDecodingOfE2ResetReq
7024  *
7025  *    Functionality: Deallocation of memory allocated by aper decoder for
7026  *    reset req
7027  *
7028  * @params[in] Pointer to resetReq
7029  * @return void
7030  *
7031  * ****************************************************************/
7032 void freeAperDecodingOfE2ResetReq(ResetRequestE2_t *resetReq)
7033 {
7034    uint8_t arrIdx=0;
7035
7036    if(resetReq)
7037    {
7038       if(resetReq->protocolIEs.list.array)
7039       {
7040          for(arrIdx=0; arrIdx<resetReq->protocolIEs.list.count; arrIdx++)
7041          {
7042             if(resetReq->protocolIEs.list.array[arrIdx])
7043             {
7044                free(resetReq->protocolIEs.list.array[arrIdx]);
7045             }
7046          }
7047          free(resetReq->protocolIEs.list.array);
7048       }
7049    }
7050 }
7051
7052 /*******************************************************************
7053  *
7054  * @brief Process reset req received from RIC
7055  *
7056  * @details
7057  *
7058  *    Function : procE2ResetRequest
7059  *
7060  * Functionality: Process reset req received from RIC
7061  *
7062  * @param  E2AP_PDU_t  *e2apMsg
7063  * @return void
7064  *
7065  ******************************************************************/
7066
7067 void procE2ResetRequest(E2AP_PDU_t  *e2apMsg)
7068 {
7069    uint16_t ranFuncIdx=0;
7070    uint8_t arrIdx =0, transId =0;
7071    ResetRequestE2_t *resetReq;
7072
7073    DU_LOG("\nINFO   -->  E2AP : E2 Reset request received");
7074    resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
7075
7076    for(arrIdx=0; arrIdx<resetReq->protocolIEs.list.count; arrIdx++)
7077    {
7078       switch(resetReq->protocolIEs.list.array[arrIdx]->id)
7079       {
7080          case ProtocolIE_IDE2_id_TransactionID:
7081             {
7082                transId = resetReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
7083                break;
7084             }
7085
7086          case ProtocolIE_IDE2_id_CauseE2:
7087             {
7088                for(ranFuncIdx=0; ranFuncIdx<MAX_RAN_FUNCTION; ranFuncIdx++)
7089                {
7090                   if(duCb.e2apDb.ranFunction[ranFuncIdx].id >0)
7091                   {
7092                      deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList));
7093                      memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo));
7094                   }
7095                }
7096                break;
7097             }
7098       }
7099    }
7100    if(BuildAndSendResetResponse(transId) != ROK)
7101    {
7102       DU_LOG("\nERROR  -->  E2AP : Failed to build and send reset response");
7103    }
7104    freeAperDecodingOfE2ResetReq(resetReq);
7105 }
7106
7107 /*******************************************************************
7108  *
7109  * @brief Free APER decoding of RIC Subscription Modification Refuse
7110  *
7111  * @details
7112  *
7113  *    Function : freeAperDecodingOfRicSubsModRefuse
7114  *
7115  * Functionality:  Free APER decoding of RIC Subscription 
7116  *   Modification Refuse
7117  *
7118  * @param  E2AP Message PDU
7119  * @return void
7120  *
7121  ******************************************************************/
7122 void freeAperDecodingOfRicSubsModRefuse(E2AP_PDU_t *e2apMsg)
7123 {
7124    uint8_t ieIdx =0;
7125    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
7126
7127    if(e2apMsg && e2apMsg->choice.unsuccessfulOutcome)
7128    {
7129       ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
7130       if(ricSubsModRefuse->protocolIEs.list.array)
7131       {
7132          for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++)
7133          {
7134             if(ricSubsModRefuse->protocolIEs.list.array[ieIdx])
7135                free(ricSubsModRefuse->protocolIEs.list.array[ieIdx]);
7136          }
7137          free(ricSubsModRefuse->protocolIEs.list.array);
7138       }
7139    }
7140 }
7141
7142 /*******************************************************************
7143  *
7144  * @brief Process RIC Subscription Modification Refuse Message
7145  *
7146  * @details
7147  *
7148  *    Function : procRicSubscriptionModificationRefuse
7149  *
7150  * Functionality:  Process RIC Subscription Modification Refuse
7151  *    Message received from RIC. 
7152  *
7153  * @param  E2AP Message PDU
7154  * @return void
7155  *
7156  ******************************************************************/
7157 void procRicSubscriptionModificationRefuse(E2AP_PDU_t *e2apMsg)
7158 {
7159    uint8_t ieIdx = 0;
7160    uint16_t ranFuncId = 0;
7161    RicRequestId ricReqId;
7162    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
7163    RICsubscriptionModificationRefuse_IEs_t *ricSubsModRefuseIe = NULLP;
7164    CauseE2_t *cause = NULLP;
7165
7166    DU_LOG("\nINFO   -->  E2AP : %s: Received RIC Subscription Modification Refuse", __func__);
7167
7168    do{
7169       if(!e2apMsg)
7170       {
7171          DU_LOG("\nERROR  -->  E2AP : %s: E2AP Message is NULL", __func__);
7172          break;
7173       }
7174
7175       if(!e2apMsg->choice.unsuccessfulOutcome)
7176       {
7177          DU_LOG("\nERROR  -->  E2AP : %s: Unsuccessful Outcome in E2AP message is NULL", __func__);
7178          break;
7179       }
7180
7181       ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
7182       if(!ricSubsModRefuse->protocolIEs.list.array)
7183       {
7184          DU_LOG("\nERROR  -->  E2AP : %s: Array conatining E2AP message IEs is null", __func__);
7185          break;
7186       }
7187
7188       for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++)
7189       {
7190          if(!ricSubsModRefuse->protocolIEs.list.array[ieIdx])
7191          {
7192             DU_LOG("\nERROR  -->  E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx);
7193             break;
7194          }
7195
7196          ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
7197          switch(ricSubsModRefuseIe->id)
7198          {
7199             case ProtocolIE_IDE2_id_RICrequestID:
7200                {
7201                   memset(&ricReqId, 0, sizeof(RicRequestId));
7202                   ricReqId.requestorId = ricSubsModRefuseIe->value.choice.RICrequestID.ricRequestorID;
7203                   ricReqId.instanceId = ricSubsModRefuseIe->value.choice.RICrequestID.ricInstanceID;
7204                   break;
7205                }
7206
7207             case ProtocolIE_IDE2_id_RANfunctionID:
7208                {
7209                   ranFuncId = ricSubsModRefuseIe->value.choice.RANfunctionID;
7210                   break;
7211                }
7212
7213             case ProtocolIE_IDE2_id_CauseE2:
7214                {
7215                   DU_LOG("\nDEBUG  -->  E2AP : %s: RIC subscriptiom modification refused for RIC_Requestor_ID [%d] \
7216                         RIC_Instance_ID [%d] RAN_Function_ID [%d] ", __func__, ricReqId.requestorId, \
7217                         ricReqId.instanceId, ranFuncId);
7218
7219                   cause = &ricSubsModRefuseIe->value.choice.CauseE2;
7220                   printE2ErrorCause(cause);
7221                }
7222
7223             default:
7224                break;
7225          } /* End of switch for Protocol IE Id */
7226       } /* End of for loop for Protocol IE list */
7227
7228       break;
7229    }while(true);
7230
7231    freeAperDecodingOfRicSubsModRefuse(e2apMsg);
7232    return;
7233 }
7234
7235 /*******************************************************************
7236  *
7237  * @brief Free RIC Subscription Delete Required Message
7238  *
7239  * @details
7240  *
7241  *    Function : FreeRicSubscriptionDeleteRequired
7242  *
7243  * Functionality:  Free RIC Subscription Delete Required
7244  *
7245  * @param  E2AP Message PDU
7246  * @return void
7247  *
7248  ******************************************************************/
7249 void FreeRicSubscriptionDeleteRequired(E2AP_PDU_t *e2apMsg, CmLListCp *ricSubsToBeDelList)
7250 {
7251    uint8_t ieIdx = 0, arrIdx = 0;
7252    RICsubscriptionDeleteRequired_t *ricSubsDelRqd = NULLP;
7253    RICsubscriptionDeleteRequired_IEs_t *ricSubsDelRqdIe = NULLP;
7254    RICsubscription_List_withCause_t *ricSubsList = NULLP;
7255    CmLList *subsNode = NULLP;
7256
7257    if(e2apMsg)
7258    {
7259       if(e2apMsg->choice.initiatingMessage)
7260       {
7261          ricSubsDelRqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired;
7262          if(ricSubsDelRqd->protocolIEs.list.array)
7263          {
7264             for(ieIdx = 0; ieIdx < ricSubsDelRqd->protocolIEs.list.count; ieIdx++)
7265             {
7266                if(ricSubsDelRqd->protocolIEs.list.array[ieIdx])
7267                {
7268                   ricSubsDelRqdIe = ricSubsDelRqd->protocolIEs.list.array[ieIdx];
7269                   switch(ricSubsDelRqdIe->id)
7270                   {
7271                      case ProtocolIE_IDE2_id_RICsubscriptionToBeRemoved:
7272                         {
7273                            ricSubsList = &ricSubsDelRqdIe->value.choice.RICsubscription_List_withCause;
7274                            if(ricSubsList->list.array)
7275                            {
7276                               for(arrIdx = 0; arrIdx < ricSubsList->list.count; arrIdx++)
7277                               {
7278                                  DU_FREE(ricSubsList->list.array[ieIdx], sizeof(RICsubscription_withCause_ItemIEs_t));
7279                               }
7280                               DU_FREE(ricSubsList->list.array, ricSubsList->list.size);
7281                            }
7282                            break;
7283                         }
7284                   }
7285                   DU_FREE(ricSubsDelRqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequired_IEs_t));
7286                }
7287             }
7288             DU_FREE(ricSubsDelRqd->protocolIEs.list.array, ricSubsDelRqd->protocolIEs.list.size);
7289          }
7290          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
7291       }
7292       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));;
7293    }
7294
7295    if(ricSubsToBeDelList)
7296    {
7297       CM_LLIST_FIRST_NODE(ricSubsToBeDelList, subsNode);
7298       while(subsNode)
7299       {
7300          cmLListDelFrm(ricSubsToBeDelList, subsNode);
7301          DU_FREE(subsNode, sizeof(CmLList));
7302          CM_LLIST_FIRST_NODE(ricSubsToBeDelList, subsNode);
7303       }
7304    }
7305 }
7306
7307 /*******************************************************************
7308  *
7309  * @brief Fill list of RIC subscriptions required to be deleted
7310  *    with the cause of deletion
7311  *
7312  * @details
7313  *
7314  *    Function : fillRicSubsListWithCause
7315  *
7316  * Functionality:  Fill list of RIC subscriptions required to be 
7317  *    deleted with the cause of deletion
7318  *
7319  * @param  E2AP Message PDU
7320  * @return void
7321  *
7322  ******************************************************************/
7323 uint8_t fillRicSubsListWithCause(RICsubscription_List_withCause_t *ricSubsList, CmLListCp ricSubsToBeDelList)
7324 {
7325    uint16_t ieIdx = 0;
7326    CmLList *subsNode = NULLP;
7327    RicSubscription *subsInfo = NULLP;
7328    RICsubscription_withCause_ItemIEs_t *subsItemIe = NULLP;
7329    RICsubscription_withCause_Item_t *subsItem = NULLP;
7330
7331    ricSubsList->list.count = ricSubsToBeDelList.count;
7332    ricSubsList->list.size = ricSubsList->list.count * sizeof(RICsubscription_withCause_ItemIEs_t *);
7333    DU_ALLOC(ricSubsList->list.array, ricSubsList->list.size);
7334    if(!ricSubsList->list.array)
7335    {
7336       DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7337       return RFAILED;
7338    }
7339
7340    CM_LLIST_FIRST_NODE(&ricSubsToBeDelList, subsNode);
7341    while(subsNode && (ieIdx < ricSubsList->list.count))
7342    {
7343       subsInfo = (RicSubscription *)subsNode->node;
7344       DU_ALLOC(ricSubsList->list.array[ieIdx], sizeof(RICsubscription_withCause_ItemIEs_t));
7345       if(!ricSubsList->list.array[ieIdx])
7346       {
7347          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7348          return RFAILED;
7349       }
7350
7351       subsItemIe = (RICsubscription_withCause_ItemIEs_t *)ricSubsList->list.array[ieIdx];
7352       subsItemIe->id = ProtocolIE_IDE2_id_RICsubscription_withCause_Item;
7353       subsItemIe->criticality = CriticalityE2_ignore;
7354       subsItemIe->value.present = RICsubscription_withCause_ItemIEs__value_PR_RICsubscription_withCause_Item;
7355
7356       subsItem = & subsItemIe->value.choice.RICsubscription_withCause_Item;
7357       subsItem->ricRequestID.ricRequestorID = subsInfo->requestId.requestorId;
7358       subsItem->ricRequestID.ricInstanceID = subsInfo->requestId.instanceId;
7359       subsItem->ranFunctionID = subsInfo->ranFuncId;
7360       fillE2Cause(&subsItem->cause, subsInfo->failureCause);
7361
7362       ieIdx++;
7363       subsNode = subsNode->next;
7364    }
7365
7366    return ROK;   
7367 }
7368
7369 /*******************************************************************
7370  *
7371  * @brief Builds and Send RIC Subscription delete required
7372  *
7373  * @details
7374  *
7375  *    Function : BuildAndSendRicSubscriptionDeleteRequired
7376  *
7377  * Functionality: Build and send RIC subscription delete required.
7378  *    There can be 2 approaches to trigger following. One of these
7379  *    approaches may/may not be implemented in future:
7380  *    1. It can be triggerred immediately when a RIC subscription's
7381  *       End Time has expired. In this case, only this subscription's
7382  *       info will be sent in this message.
7383  *       Since we have not yet added support to execute RIC 
7384  *       Subscription based on Start Time and End Timer, this message is 
7385  *       not triggered anywhere from DU APP yet.
7386  *    2. Another approach is to have a periodic timer to check subscription
7387  *       status running in background.
7388  *       When RIC Subscription End Time expires, this subscription is
7389  *       marked to be deleted. Later when this background timer expires,
7390  *       a RIC Subscription delete required is sent with all the 
7391  *       subscription's info which is marked to be deleted.
7392  *    The following function is implemented keeping in mind the second 
7393  *    approach.
7394  *
7395  * @params[in] 
7396  * @return ROK     - success
7397  *         RFAILED - failure
7398  *
7399  ******************************************************************/
7400 uint8_t BuildAndSendRicSubscriptionDeleteRequired()
7401 {
7402    uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED;
7403    E2AP_PDU_t         *e2apMsg = NULLP;
7404    RICsubscriptionDeleteRequired_t *ricSubsDelRqd = NULLP;
7405    RICsubscriptionDeleteRequired_IEs_t *ricSubsDelRqdIe = NULLP;
7406    asn_enc_rval_t     encRetVal;        /* Encoder return value */
7407    CmLListCp ricSubsToBeDelList;
7408
7409    while(true)
7410    {
7411       /* Check if there are any RIC subscriptions to be deleted */
7412       cmLListInit(&ricSubsToBeDelList);
7413       fetchRicSubsToBeDeleted(&ricSubsToBeDelList);
7414       if(ricSubsToBeDelList.count == 0)
7415       {
7416          DU_LOG("\nDEBUG  -->  E2AP : %s: No RIC subscriptions are required to be deleted", __func__);
7417          return ROK;
7418       }
7419
7420       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Delete Required Message\n");
7421
7422       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
7423       if(e2apMsg == NULLP)
7424       {
7425          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7426          break;
7427       }
7428
7429       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
7430       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
7431       if(e2apMsg->choice.initiatingMessage == NULLP)
7432       {
7433          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
7434          break;
7435       }
7436       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionDeleteRequired;
7437       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
7438       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequired;
7439
7440       ricSubsDelRqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired;
7441       
7442       elementCnt = 1;
7443       ricSubsDelRqd->protocolIEs.list.count = elementCnt;
7444       ricSubsDelRqd->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionDeleteRequired_IEs_t *);
7445
7446       DU_ALLOC(ricSubsDelRqd->protocolIEs.list.array, ricSubsDelRqd->protocolIEs.list.size);
7447       if(ricSubsDelRqd->protocolIEs.list.array == NULLP)
7448       {
7449          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__);
7450          break;
7451       }
7452       
7453       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
7454       {
7455          DU_ALLOC(ricSubsDelRqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequired_IEs_t));
7456          if(ricSubsDelRqd->protocolIEs.list.array[ieIdx] == NULLP)
7457          {
7458             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for index [%d] at line %d", \
7459                __func__, ieIdx, __LINE__);
7460             break;
7461          }
7462       }
7463       if(ieIdx < elementCnt)
7464          break;
7465
7466       ieIdx = 0;
7467       ricSubsDelRqdIe = ricSubsDelRqd->protocolIEs.list.array[ieIdx];
7468       ricSubsDelRqdIe->id = ProtocolIE_IDE2_id_RICsubscriptionToBeRemoved;
7469       ricSubsDelRqdIe->criticality = CriticalityE2_ignore;
7470       ricSubsDelRqdIe->value.present = RICsubscriptionDeleteRequired_IEs__value_PR_RICsubscription_List_withCause;
7471       if(fillRicSubsListWithCause(&ricSubsDelRqdIe->value.choice.RICsubscription_List_withCause, ricSubsToBeDelList)\
7472             != ROK)
7473       {
7474          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Subscription list with cause", __func__);
7475          break;
7476       }
7477
7478       /* Prints the Msg formed */
7479       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
7480       memset(encBuf, 0, ENC_BUF_MAX_LEN);
7481       encBufSize = 0;
7482       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
7483       if(encRetVal.encoded == ENCODE_FAIL)
7484       {
7485          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Delete Required Message (at %s)\n",\
7486                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
7487          break;
7488       }
7489       else
7490       {
7491          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Delete Required Message \n");
7492 #ifdef DEBUG_ASN_PRINT
7493          for(int i=0; i< encBufSize; i++)
7494          {
7495             printf("%x",encBuf[i]);
7496          } 
7497 #endif
7498       }
7499
7500       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
7501       {
7502          DU_LOG("\nERROR   -->  E2AP : Failed to send RIC Susbcription Delete Required Message");      
7503
7504       }
7505       ret = ROK;
7506       break;
7507    }
7508
7509    FreeRicSubscriptionDeleteRequired(e2apMsg, &ricSubsToBeDelList);     
7510    return ret;
7511 }
7512
7513 /*******************************************************************
7514  *
7515  * @brief Free RIC Subscription Delete Request Message
7516  *
7517  * @details
7518  *
7519  *    Function : freeAperDecodingOfRicSubsDeleteReq
7520  *
7521  * Functionality:  Free RIC Subscription Delete Request
7522  *
7523  * @param  E2AP Message PDU
7524  * @return void
7525  *
7526  ******************************************************************/
7527 void freeAperDecodingOfRicSubsDeleteReq(E2AP_PDU_t *e2apMsg)
7528 {
7529    uint8_t ieIdx = 0;
7530    RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
7531
7532    if(e2apMsg)
7533    {
7534       if(e2apMsg->choice.initiatingMessage)
7535       {
7536          ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
7537          if(ricSubsDelReq->protocolIEs.list.array)
7538          {
7539             for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++)
7540             {
7541                if(ricSubsDelReq->protocolIEs.list.array[ieIdx])
7542                {
7543                   free(ricSubsDelReq->protocolIEs.list.array[ieIdx]);
7544                }
7545             }
7546             free(ricSubsDelReq->protocolIEs.list.array);
7547          }
7548       }
7549    }
7550 }
7551
7552 /*******************************************************************
7553  *
7554  * @brief Process RIC Subscription delete request
7555  *
7556  * @details
7557  *
7558  *    Function : procRicSubscriptionDeleteRequest
7559  *
7560  * Functionality: Process RIC subscription delete request.
7561  *    Fetch RAN Function and RIC subscription to be deleted. 
7562  *    Send statistics delete request to MAC for all action sequence
7563  *    within this RIC subscription.
7564  *
7565  * @params[in] E2AP PDU
7566  * @return void
7567  *
7568  ******************************************************************/
7569 void procRicSubscriptionDeleteRequest(E2AP_PDU_t *e2apMsg)
7570 {
7571    uint8_t ieIdx = 0;
7572    uint16_t ranFuncId = 0;
7573    bool procFailure = false;
7574    RicRequestId ricReqId;
7575    RanFunction *ranFuncDb = NULLP;
7576    CmLList *ricSubsNode = NULLP;
7577    RicSubscription *ricSubsDb = NULLP;
7578    RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
7579    RICsubscriptionDeleteRequest_IEs_t *ricSubsDelReqIe = NULLP;
7580
7581    DU_LOG("\nINFO   -->  E2AP : %s: Received RIC Subscription Delete Request", __func__);
7582
7583    do{
7584       if(!e2apMsg)
7585       {
7586          DU_LOG("\nERROR  -->  E2AP : %s: E2AP Message is NULL", __func__);
7587          break;
7588       }
7589
7590       if(!e2apMsg->choice.initiatingMessage)
7591       {
7592          DU_LOG("\nERROR  -->  E2AP : %s: Initiating Message in E2AP PDU is NULL", __func__);
7593          break;
7594       }
7595
7596       ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
7597       if(!ricSubsDelReq->protocolIEs.list.array)
7598       {
7599          DU_LOG("\nERROR  -->  E2AP : %s: Array conatining E2AP message IEs is null", __func__);
7600          break;
7601       }
7602
7603       for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++)
7604       {
7605          if(!ricSubsDelReq->protocolIEs.list.array[ieIdx])
7606          {
7607             DU_LOG("\nERROR  -->  E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx);
7608             break;
7609          }
7610
7611          ricSubsDelReqIe = ricSubsDelReq->protocolIEs.list.array[ieIdx];
7612          switch(ricSubsDelReqIe->id)
7613          {
7614             case ProtocolIE_IDE2_id_RICrequestID:
7615                {
7616                   memset(&ricReqId, 0, sizeof(RicRequestId));
7617                   ricReqId.requestorId = ricSubsDelReqIe->value.choice.RICrequestID.ricRequestorID;
7618                   ricReqId.instanceId = ricSubsDelReqIe->value.choice.RICrequestID.ricInstanceID;
7619                   break;
7620                }
7621
7622             case ProtocolIE_IDE2_id_RANfunctionID:
7623                {
7624                   ranFuncId = ricSubsDelReqIe->value.choice.RANfunctionID;
7625                   ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
7626                   if(!ranFuncDb)
7627                   {
7628                      DU_LOG("\nERROR  -->  E2AP : %s: RAN Function ID [%d] not found", __func__, ranFuncId);
7629                      procFailure = true;
7630                      break;
7631                   }
7632
7633                   ricSubsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode); 
7634                   if(!ricSubsDb)
7635                   {
7636                      DU_LOG("\nERROR  -->  E2AP : %s: RIC Subscription not found for Requestor_ID [%d] Instance_ID [%d]",\
7637                            __func__, ricReqId.requestorId, ricReqId.instanceId);
7638                      procFailure = true;
7639                      break;
7640                   }
7641
7642                   //TODO : Send statistics delete request to MAC 
7643                   break;
7644                }
7645
7646             default:
7647                break;
7648          } /* End of switch for Protocol IE Id */
7649          
7650          if(procFailure)
7651             break;
7652       } /* End of for loop for Protocol IE list */
7653
7654       break;
7655    }while(true);
7656
7657    freeAperDecodingOfRicSubsDeleteReq(e2apMsg);
7658    return;
7659 }
7660
7661 /*******************************************************************
7662  *
7663  * @brief Deallocate the memory allocated for E2 node configuration
7664  * update ack msg by aper decoder
7665  *
7666  * @details
7667  *
7668  *    Function : freeAperDecodingOfE2NodeConfigUpdateAck 
7669  *
7670  *    Functionality:
7671  *       - Deallocate the memory allocated for E2 node configuration
7672  * update ack msg by aper decoder
7673  *
7674  * @params[in] E2AP_PDU_t *e2apMsg
7675  * @return ROK     - success
7676  *         RFAILED - failure
7677  *
7678  * ****************************************************************/
7679
7680 void freeAperDecodingOfE2NodeConfigUpdateAck(E2nodeConfigurationUpdateAcknowledge_t *updateAckMsg)
7681 {
7682    uint8_t arrIdx =0, e2NodeConfigIdx=0;
7683    E2nodeComponentConfigUpdateAck_ItemIEs_t *updateAckItemIe=NULL;
7684    E2nodeComponentConfigUpdateAck_List_t *updateAckList=NULL;
7685    E2nodeComponentConfigRemovalAck_ItemIEs_t *removalAckItemIe=NULL;
7686    E2nodeComponentConfigRemovalAck_List_t *removalAckList=NULL;
7687    E2nodeComponentConfigAdditionAck_ItemIEs_t *additionAckItemIte=NULL;
7688    E2nodeComponentConfigAdditionAck_List_t *additionAckList=NULL;
7689
7690    E2nodeComponentInterfaceF1_t *f1InterfaceInfo=NULLP;
7691    if(updateAckMsg->protocolIEs.list.array != NULLP)
7692    {
7693       for(arrIdx = 0; arrIdx < updateAckMsg->protocolIEs.list.count; arrIdx++)
7694       {
7695          if(updateAckMsg->protocolIEs.list.array[arrIdx])
7696          {
7697             switch(updateAckMsg->protocolIEs.list.array[arrIdx]->id)
7698             {
7699                case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
7700                   {
7701                      additionAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
7702                      if(additionAckList->list.array)
7703                      {
7704                         for(e2NodeConfigIdx=0; e2NodeConfigIdx<additionAckList->list.count; e2NodeConfigIdx++)
7705                         {
7706                            additionAckItemIte = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) additionAckList->list.array[e2NodeConfigIdx];
7707                            if(additionAckItemIte)
7708                            {
7709                               switch(additionAckItemIte->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present)
7710                               {
7711                                  case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
7712                                     {
7713                                        f1InterfaceInfo = additionAckItemIte->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
7714                                        free(f1InterfaceInfo->gNB_DU_ID.buf);
7715                                        free(f1InterfaceInfo);
7716                                        break;
7717                                     }
7718                                  default:
7719                                     break;
7720                               }
7721                               free(additionAckItemIte);
7722                            }
7723                            free(additionAckList->list.array);
7724                         }
7725                         break;
7726                      }
7727                   }
7728                case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
7729                   {
7730                      updateAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List;
7731                      if(updateAckList->list.array)
7732                      {
7733                         for(e2NodeConfigIdx=0; e2NodeConfigIdx<updateAckList->list.count; e2NodeConfigIdx++)
7734                         {
7735                            updateAckItemIe = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) updateAckList->list.array[e2NodeConfigIdx];
7736                            if(updateAckItemIe)
7737                            {
7738                               switch(updateAckItemIe->value.choice.E2nodeComponentConfigUpdateAck_Item.e2nodeComponentID.present)
7739                               {
7740                                  case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
7741                                     {
7742                                        f1InterfaceInfo = updateAckItemIe->value.choice.E2nodeComponentConfigUpdateAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
7743                                        free(f1InterfaceInfo->gNB_DU_ID.buf);
7744                                        free(f1InterfaceInfo);
7745                                        break;
7746                                     }
7747                                  default:
7748                                     break;
7749                               }
7750                               free(updateAckItemIe);
7751                            }
7752                         }
7753                         free(updateAckList->list.array);
7754                      }
7755                      break;
7756                   }
7757                case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
7758                   {
7759                      removalAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List;
7760                      if(removalAckList->list.array)
7761                      {
7762                         for(e2NodeConfigIdx=0; e2NodeConfigIdx<removalAckList->list.count; e2NodeConfigIdx++)
7763                         {
7764                            removalAckItemIe = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) removalAckList->list.array[e2NodeConfigIdx];
7765                            if(removalAckItemIe)
7766                            {
7767                               switch(removalAckItemIe->value.choice.E2nodeComponentConfigRemovalAck_Item.e2nodeComponentID.present)
7768                               {
7769                                  case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
7770                                     {
7771                                        f1InterfaceInfo = removalAckItemIe->value.choice.E2nodeComponentConfigRemovalAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
7772                                        free(f1InterfaceInfo->gNB_DU_ID.buf);
7773                                        free(f1InterfaceInfo);
7774                                        break;
7775                                     }
7776                                  default:
7777                                     break;
7778                               }
7779                               free(removalAckItemIe);
7780                            }
7781                         }
7782                         free(removalAckList->list.array);
7783                      }
7784                      break;
7785                   }
7786             }
7787             free(updateAckMsg->protocolIEs.list.array[arrIdx]);
7788          }
7789       }
7790       free(updateAckMsg->protocolIEs.list.array);
7791    }
7792 }
7793
7794 /******************************************************************
7795  *
7796  * @brief Processes the E2 node config update ack msg
7797  *
7798  * @details
7799  *
7800  *    Function :procE2NodeConfigUpdateAck 
7801  *
7802  *    Functionality: Processes the E2 node config update ack msg
7803  *
7804  * @params[in] E2AP_PDU_t ASN decoded E2AP message
7805  * @return ROK     - success
7806  *         RFAILED - failure
7807  *
7808  * ****************************************************************/
7809
7810 void procE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg)
7811 {
7812    uint8_t arrIdx =0;
7813    uint16_t e2CfgIdx =0;
7814    E2nodeConfigurationUpdateAcknowledge_t *e2NodeConfigUpdateAck =NULLP;
7815    E2nodeComponentConfigUpdateAck_List_t *e2NodeConfigUpdateAckList=NULLP;
7816    E2nodeComponentConfigUpdateAck_ItemIEs_t *e2NodeUpdateAckItem=NULLP;
7817    E2nodeComponentConfigRemovalAck_List_t *e2NodeConfigRemovalAckList=NULLP;
7818    E2nodeComponentConfigRemovalAck_ItemIEs_t *e2NodeRemovalAckItem=NULLP;
7819    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList=NULLP;
7820    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAdditionAckItem=NULLP;
7821
7822    e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
7823
7824    if(e2NodeConfigUpdateAck->protocolIEs.list.array)
7825    {
7826        for(arrIdx =0; arrIdx<e2NodeConfigUpdateAck->protocolIEs.list.count; arrIdx++)
7827        {
7828             switch(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id)
7829             {
7830                case ProtocolIE_IDE2_id_TransactionID:
7831                {
7832                   break;
7833                }
7834                case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
7835                {
7836                   e2NodeConfigAdditionAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
7837                   if(e2NodeConfigAdditionAckList->list.array)
7838                   {
7839                      for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigAdditionAckList->list.count; e2CfgIdx++) 
7840                      {
7841                         e2NodeAdditionAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[e2CfgIdx];    
7842                         handleE2NodeConfigUpdateAckIes((PTR)&e2NodeAdditionAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item,\
7843                         ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck);
7844                      }
7845                   }
7846                   break;
7847                }
7848                case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
7849                {
7850                   e2NodeConfigUpdateAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List;
7851                   if(e2NodeConfigUpdateAckList->list.array)
7852                   {
7853                      for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigUpdateAckList->list.count; e2CfgIdx++) 
7854                      {
7855                         e2NodeUpdateAckItem = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) e2NodeConfigUpdateAckList->list.array[e2CfgIdx];    
7856                         handleE2NodeConfigUpdateAckIes((PTR)&e2NodeUpdateAckItem->value.choice.E2nodeComponentConfigUpdateAck_Item,\
7857                         ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck);
7858                      }
7859                   }
7860                   break;
7861                }
7862                case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
7863                {
7864                   e2NodeConfigRemovalAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List;
7865                   if(e2NodeConfigRemovalAckList->list.array)
7866                   {
7867                      for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigRemovalAckList->list.count; e2CfgIdx++) 
7868                      {
7869                         e2NodeRemovalAckItem = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) e2NodeConfigRemovalAckList->list.array[e2CfgIdx];    
7870                         handleE2NodeConfigUpdateAckIes((PTR)&e2NodeRemovalAckItem->value.choice.E2nodeComponentConfigRemovalAck_Item,\
7871                         ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck);
7872                      }
7873                   }
7874                   break;
7875                }
7876             }
7877        }
7878    }
7879
7880    freeAperDecodingOfE2NodeConfigUpdateAck(e2NodeConfigUpdateAck);
7881 }
7882
7883 /*******************************************************************
7884  *
7885  * @brief Handles received E2AP message and sends back response  
7886  *
7887  * @details
7888  *
7889  *    Function : E2APMsgHdlr
7890  *
7891  *    Functionality:
7892  *         - Decodes received E2AP control message
7893  *         - Prepares response message, encodes and sends to SCTP
7894  *
7895  * @params[in] 
7896  * @return ROK     - success
7897  *         RFAILED - failure
7898  *
7899  * ****************************************************************/
7900 void E2APMsgHdlr(Buffer *mBuf)
7901 {
7902    int i =0;
7903    char *recvBuf = NULLP;
7904    MsgLen copyCnt =0;
7905    MsgLen recvBufLen =0;
7906    E2AP_PDU_t *e2apMsg = NULLP;
7907    asn_dec_rval_t rval ={0}; /* Decoder return value */
7908    E2AP_PDU_t e2apasnmsg={0} ;
7909
7910    DU_LOG("\nDEBUG   -->  E2AP : Received E2AP message buffer");
7911    ODU_PRINT_MSG(mBuf, 0,0);
7912
7913    /* Copy mBuf into char array to decode it */
7914    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
7915    DU_ALLOC(recvBuf, (Size)recvBufLen);
7916
7917    if(recvBuf == NULLP)
7918    {
7919       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
7920       return;
7921    }
7922    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
7923    {
7924       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
7925       return;
7926    }
7927
7928 #ifdef DEBUG_ASN_PRINT
7929    printf("\nDEBUG   -->  E2AP : Received flat buffer to be decoded : ");
7930    for(i=0; i< recvBufLen; i++)
7931    {
7932       printf("%x",recvBuf[i]);
7933    }
7934 #endif
7935
7936    /* Decoding flat buffer into E2AP messsage */
7937    e2apMsg = &e2apasnmsg;
7938    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
7939
7940    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
7941    DU_FREE(recvBuf, (Size)recvBufLen);
7942
7943    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
7944    {
7945       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
7946       return;
7947    }
7948    printf("\n");
7949    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
7950
7951    switch(e2apMsg->present)
7952    {
7953       case E2AP_PDU_PR_unsuccessfulOutcome:
7954          {
7955             switch(e2apMsg->choice.unsuccessfulOutcome->value.present)
7956             {
7957                case UnsuccessfulOutcomeE2__value_PR_E2setupFailure:
7958                   {
7959                      procE2SetupFailure(e2apMsg);
7960                      break;
7961                   }
7962                case UnsuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateFailure:
7963                   {
7964                      procE2NodeConfigUpdateFailure(e2apMsg);
7965                      break;
7966                   }
7967                case UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure:
7968                   {
7969                      procRicServiceUpdateFailure(e2apMsg);
7970                      break;
7971                   }
7972                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionModificationRefuse:
7973                   {
7974                      procRicSubscriptionModificationRefuse(e2apMsg);
7975                      break;
7976                   }
7977                default:
7978                   {
7979                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome  [%d]",\
7980                            e2apMsg->choice.unsuccessfulOutcome->value.present);
7981                      return;
7982                   }
7983             }
7984             free(e2apMsg->choice.unsuccessfulOutcome);
7985             break;
7986          }
7987       case E2AP_PDU_PR_successfulOutcome:
7988          {
7989             switch(e2apMsg->choice.successfulOutcome->value.present)
7990             {
7991                case SuccessfulOutcomeE2__value_PR_E2setupResponse:
7992                   {
7993                      if(!duCb.e2Status)
7994                      {
7995                         procE2SetupRsp(e2apMsg);
7996                      }
7997                      break;
7998                   }
7999                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
8000                   {
8001                      procResetResponse(e2apMsg);
8002                      break;
8003                   }
8004                case SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge:
8005                   {
8006                      procRicServiceUpdateAck(e2apMsg);
8007                      break;
8008                   }
8009                case SuccessfulOutcomeE2__value_PR_RICsubscriptionModificationConfirm:
8010                   {
8011                      procRicSubscriptionModificationConfirm(e2apMsg);
8012                      break;
8013                   }
8014                case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge:
8015                   {
8016                      procE2NodeConfigUpdateAck(e2apMsg);
8017                      break;
8018                   }
8019                default:
8020                   {
8021                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome  [%d]",\
8022                            e2apMsg->choice.successfulOutcome->value.present);
8023                      return;
8024                   }
8025             }/* End of switch(successfulOutcome) */
8026             free(e2apMsg->choice.successfulOutcome);
8027             break;
8028          }
8029
8030       case E2AP_PDU_PR_initiatingMessage:
8031          {
8032             switch(e2apMsg->choice.initiatingMessage->value.present)
8033             {
8034                case InitiatingMessageE2__value_PR_RICsubscriptionRequest: 
8035                   {
8036                      procRicSubscriptionRequest(e2apMsg);
8037                      break;
8038                   }
8039                case InitiatingMessageE2__value_PR_RICserviceQuery:
8040                   {
8041                      procRicServiceQuery(e2apMsg);
8042                      break;
8043                   }
8044                case InitiatingMessageE2__value_PR_ErrorIndicationE2:
8045                   {
8046                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
8047                      break;
8048                   }
8049                case InitiatingMessageE2__value_PR_ResetRequestE2:
8050                   {
8051                      DU_LOG("\nINFO  -->  E2AP : Reset request received");
8052                      procE2ResetRequest(e2apMsg);
8053                      break;
8054                   }
8055                case InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequest:
8056                   {
8057                      DU_LOG("\nINFO  -->  E2AP : RIC Subscription Delete Request received");
8058                      procRicSubscriptionDeleteRequest(e2apMsg);
8059                      break;
8060                   }
8061                case InitiatingMessageE2__value_PR_E2RemovalRequest:
8062                   {
8063                      DU_LOG("\nINFO  -->  E2AP : E2 Removal request received");
8064                      procE2RemovalRequest(e2apMsg);
8065                      break;
8066                   }
8067                default:
8068                   {
8069                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\
8070                            e2apMsg->choice.initiatingMessage->value.present);
8071                      return;
8072                   }
8073             }/* End of switch(initiatingMessage) */
8074             free(e2apMsg->choice.initiatingMessage);
8075             break;
8076          }
8077       default:
8078          {
8079             DU_LOG("\nERROR  -->  E2AP : Invalid type of e2apMsg->present [%d]",e2apMsg->present);
8080             return;
8081          }
8082          free(e2apMsg);
8083
8084    }/* End of switch(e2apMsg->present) */
8085
8086 } /* End of E2APMsgHdlr */
8087
8088 /**********************************************************************
8089   End of file
8090  **********************************************************************/