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