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