f13282f3be965b6b163b7a9e2d844471f6fa63a7
[o-du/l2.git] / src / du_app / du_e2ap_msg_hdl.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
5 #   Licensed under the Apache License, Version 2.0 (the "License");            #
6 #   you may not use this file except in compliance with the License.           #
7 #   You may obtain a copy of the License at                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
11 #   Unless required by applicable law or agreed to in writing, software        #
12 #   distributed under the License is distributed on an "AS IS" BASIS,          #
13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
14 #   See the License for the specific language governing permissions and        #
15 #   limitations under the License.                                             #
16 ################################################################################
17 *******************************************************************************/
18 #include "common_def.h"
19 #include "du_tmr.h"
20 #include "lrg.h"
21 #include "lkw.x"
22 #include "lrg.x"
23 #include "legtp.h"
24 #include "du_app_mac_inf.h"
25 #include "du_app_rlc_inf.h"
26 #include "du_e2ap_mgr.h"
27 #include "du_e2ap_msg_hdl.h"
28 #include "du_cfg.h"
29 #include "du_mgr.h"
30 #include "du_mgr_main.h"
31 #include "du_utils.h"
32 #include "GlobalE2node-gNB-ID.h"
33 #include "ProtocolIE-FieldE2.h"
34 #include "E2setupRequest.h"
35 #include "InitiatingMessageE2.h"
36 #include "SuccessfulOutcomeE2.h"
37 #include "UnsuccessfulOutcomeE2.h"
38 #include "E2AP-PDU.h"
39 #include "odu_common_codec.h"
40 #include "E2nodeComponentInterfaceF1.h"
41 #include "E2setupRequest.h"
42 #include "du_e2_conversions.h"
43 #include "E2SM-KPM-RANfunction-Description.h"
44 #include "RANfunction-Name.h"
45 #include "RIC-EventTriggerStyle-Item.h"
46 #include "RIC-ReportStyle-Item.h"
47 #include "MeasurementInfo-Action-Item.h"
48 #include "E2SM-KPM-EventTriggerDefinition.h"
49 #include "E2SM-KPM-EventTriggerDefinition-Format1.h"
50 #include "E2SM-KPM-ActionDefinition.h"
51 #include "E2SM-KPM-ActionDefinition-Format1.h"
52 #include "MeasurementInfoItem.h"
53
54 /*******************************************************************
55  *
56  * @brief Builds Global gNodeB Params
57  *
58  * @details
59  *
60  *    Function : BuildGlobalgNBId
61  *
62  *    Functionality: Building the Plmn and gNB id
63  *
64  * @params[in] GlobalE2node_gNB_ID_t *gNbId
65  * @return ROK     - success
66  *         RFAILED - failure
67  *
68  ******************************************************************/
69
70 uint8_t BuildGlobalgNBId(GlobalE2node_gNB_ID_t *gNbId)
71 {
72    uint8_t unused = 0;
73    uint8_t byteSize = 4;
74    uint8_t gnbId = duCb.gnbId;
75    uint8_t ret = ROK;
76
77    /* fill Global gNB ID Id */
78    gNbId->global_gNB_ID.plmn_id.size = 3 * sizeof(uint8_t);
79    gNbId->global_gNB_ID.plmn_id.buf = NULLP;
80    DU_ALLOC(gNbId->global_gNB_ID.plmn_id.buf , gNbId->global_gNB_ID.plmn_id.size);
81    if(gNbId->global_gNB_ID.plmn_id.buf == NULLP)
82    {
83       DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for Plmn buffer");
84       ret = RFAILED;
85    }
86    else
87    {
88       buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
89             gNbId->global_gNB_ID.plmn_id.buf);
90       gNbId->global_gNB_ID.gnb_id.present = GNB_ID_Choice_PR_gnb_ID;
91       /* Allocate Buffer size */
92       gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size = byteSize * sizeof(uint8_t);
93       gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf = NULLP;
94       DU_ALLOC(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf, \
95             gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size);
96       if(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf == NULLP)
97       {
98          DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for gnb buffer");
99          ret = RFAILED;
100       }
101       else
102       {
103          fillBitString(&gNbId->global_gNB_ID.gnb_id.choice.gnb_ID, unused, byteSize, gnbId);
104       }
105    }
106
107    /* fill gNB-DU ID */ 
108    DU_ALLOC( gNbId->gNB_DU_ID, sizeof(GNB_DU_ID_t));
109    if(gNbId->gNB_DU_ID == NULLP)
110    {
111       DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for gNB_DU_ID ");
112       ret = RFAILED;
113    }
114    else
115    {
116       gNbId->gNB_DU_ID->size = sizeof(uint8_t);
117       DU_ALLOC( gNbId->gNB_DU_ID->buf, sizeof(uint8_t));
118       if(gNbId->gNB_DU_ID->buf)
119       {
120          gNbId->gNB_DU_ID->buf[0] =duCb.e2apDb.e2NodeId;
121       }
122       else
123       {
124          DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for gNB_DU_ID buffer");
125          ret = RFAILED;
126       }
127    }
128
129    return ret;
130 }
131
132 /******************************************************************
133  *
134  * @brief Search E2 node component with the help of action type
135  *
136  * @details
137  *
138  *    Function : searchE2NodeComponentInfo 
139  *
140  *    Functionality: Search E2 node component with the help of action type 
141  *
142  * @params[in] uint8_t componentActionType
143  * @return CmLList
144  *
145  * ****************************************************************/
146
147 CmLList *searchE2NodeComponentInfo(InterfaceType interfaceType, uint8_t componentActionType)
148 {
149    E2NodeComponent *e2NodeComponentInfo;
150    CmLList         *node;
151
152    if(duCb.e2apDb.e2NodeComponentList.count)
153    {
154       CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node);
155       while(node)
156       {
157          e2NodeComponentInfo = (E2NodeComponent*)node->node;
158          if((e2NodeComponentInfo->interfaceType == interfaceType) && (e2NodeComponentInfo->componentActionType == componentActionType))
159             break;
160          else
161             node = node->next;
162       }
163    }
164    return node; 
165 }
166
167 /*******************************************************************
168  *
169  * @brief Builds E2 node config addition list 
170  *
171  * @details
172  *
173  *    Function : BuildE2NodeConfigAddList
174  *
175  *    Functionality: Building E2 node config addition list
176  *
177  * @params[in] E2nodeComponentConfigAddition_List_t *e2NodeAddList 
178  * @return ROK     - success
179  *         RFAILED - failure
180  *
181  ******************************************************************/
182
183 uint8_t BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAddList)
184 {
185    uint8_t arrIdx = 0;
186    CmLList         *node;
187    E2NodeComponent *e2NodeComponentInfo;
188    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItemIe;
189    E2nodeComponentConfigAddition_Item_t *e2NodeAddItem;
190
191    e2NodeAddList->list.count = 1;
192    e2NodeAddList->list.size = e2NodeAddList->list.count * sizeof(E2nodeComponentConfigAddition_ItemIEs_t *);
193    DU_ALLOC(e2NodeAddList->list.array, e2NodeAddList->list.size);
194    if(e2NodeAddList->list.array == NULLP)
195    {
196        DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
197        return RFAILED;
198    }
199
200    for(arrIdx = 0; arrIdx< e2NodeAddList->list.count; arrIdx++)
201    {
202       DU_ALLOC(e2NodeAddList->list.array[arrIdx], sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
203       if(e2NodeAddList->list.array[arrIdx] == NULLP)
204       {
205          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
206          return RFAILED;
207       }
208    }
209    
210    node = searchE2NodeComponentInfo(F1, E2_NODE_COMPONENT_ADD);
211    if(!node)
212    {
213       DU_LOG("\nERROR  --> E2AP : Received e2NodeComponentInfo is null");
214       return RFAILED;
215    }
216    e2NodeComponentInfo = (E2NodeComponent*)node->node;
217    
218    arrIdx = 0;
219    e2NodeAddItemIe = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[arrIdx];
220    e2NodeAddItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition_Item;
221    e2NodeAddItemIe->criticality = CriticalityE2_reject;
222    e2NodeAddItemIe->value.present = E2nodeComponentConfigAddition_ItemIEs__value_PR_E2nodeComponentConfigAddition_Item;
223    e2NodeAddItem = &e2NodeAddItemIe->value.choice.E2nodeComponentConfigAddition_Item;
224    
225    /* E2nodeComponentInterfaceType */
226    e2NodeAddItem->e2nodeComponentInterfaceType = E2nodeComponentInterfaceType_f1;
227
228    /* E2 Node Component Request Part */
229    if(e2NodeComponentInfo->componentRequestPart)
230    {
231       e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.size = e2NodeComponentInfo->reqBufSize ;
232       DU_ALLOC(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\
233             e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.size);
234       if(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf == NULLP)
235       {
236          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
237          return RFAILED;
238       }
239
240       memcpy(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\
241             e2NodeComponentInfo->componentRequestPart, e2NodeAddItem->e2nodeComponentConfiguration.\
242             e2nodeComponentRequestPart.size);
243    }
244    else
245    {
246       DU_LOG("\nERROR  --> E2AP: componentRequestPart is null ");
247       return RFAILED;
248    }
249
250
251    /* E2 Node Component Response Part */
252    if(e2NodeComponentInfo->componentResponsePart)
253    {
254       e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.size = e2NodeComponentInfo->rspBufSize; 
255       DU_ALLOC(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.buf, \
256             e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.size);
257       if(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.buf == NULLP)
258       {
259          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
260          return RFAILED;
261       }
262       memcpy(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.buf, \
263             e2NodeComponentInfo->componentResponsePart, e2NodeAddItem->e2nodeComponentConfiguration.\
264             e2nodeComponentResponsePart.size);
265    }
266    else
267    {
268       DU_LOG("\nERROR  --> E2AP: componentResponsePart is null");
269       return RFAILED;
270    }
271    
272    /* E2 Node Component ID */
273    e2NodeAddItem->e2nodeComponentID.present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1;
274    DU_ALLOC(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\
275    sizeof(E2nodeComponentInterfaceF1_t));
276    if(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1 == NULLP)
277    {
278        DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
279        return RFAILED;
280    }
281    e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t);
282    DU_ALLOC(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
283    e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
284
285    if(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP)
286    {
287       DU_LOG("\nERROR  -->list.  E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
288       return RFAILED;
289    }
290    e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[arrIdx]  = e2NodeComponentInfo->componentId;
291    return ROK;
292
293 }
294
295 /*******************************************************************
296  *
297  * @brief deallocation of E2SM_KPM_RANfunction_Description_t
298  *
299  * @details
300  *
301  *    Function : freeE2smKpmRanFunctionDefinition
302  *
303  *    Functionality: deallocation of E2SM_KPM_RANfunction_Description_t
304  *
305  * @params[in]  E2SM_KPM_RANfunction_Description_t *ranFunctionDefinition
306  * @return void
307  *
308  ******************************************************************/
309
310 void freeE2smKpmRanFunctionDefinition(E2SM_KPM_RANfunction_Description_t *ranFunctionDefinition)
311 {
312    MeasurementInfo_Action_Item_t *measInfoList;
313    uint8_t eventTriggerIdx, reportStyleIdx, measInfoIdx;
314    RANfunction_Name_t *ranFuncName;
315    struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle;
316    struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List *eventTriggerStyle;
317    if(ranFunctionDefinition)
318    {
319       ranFuncName = &ranFunctionDefinition->ranFunction_Name;
320       /* Free RAN function Name */     
321       DU_FREE(ranFuncName->ranFunction_ShortName.buf,  ranFuncName->ranFunction_ShortName.size);
322       DU_FREE(ranFuncName->ranFunction_E2SM_OID.buf, ranFuncName->ranFunction_E2SM_OID.size);
323       DU_FREE(ranFuncName->ranFunction_Description.buf, ranFuncName->ranFunction_Description.size);
324
325       /* Sequence of Event Trigger styles */
326       eventTriggerStyle = ranFunctionDefinition->ric_EventTriggerStyle_List;
327       if(eventTriggerStyle)
328       {
329          if(eventTriggerStyle->list.array)
330          {
331             for(eventTriggerIdx =0;eventTriggerIdx<eventTriggerStyle->list.count; eventTriggerIdx++)
332             {
333                if(eventTriggerStyle->list.array[eventTriggerIdx])
334                {
335                   DU_FREE(eventTriggerStyle->list.array[eventTriggerIdx]->ric_EventTriggerStyle_Name.buf,\
336                         eventTriggerStyle->list.array[eventTriggerIdx]->ric_EventTriggerStyle_Name.size);
337                   DU_FREE(eventTriggerStyle->list.array[eventTriggerIdx], sizeof(RIC_EventTriggerStyle_Item_t ));
338                }
339             }
340             DU_FREE(eventTriggerStyle->list.array, eventTriggerStyle->list.size)
341          }
342          DU_FREE(eventTriggerStyle, sizeof(struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List));
343       }
344       
345       /* Sequence of Report styles */
346       ricReportStyle = ranFunctionDefinition->ric_ReportStyle_List;
347       if(ricReportStyle)
348       {
349          if(ricReportStyle->list.array)
350          {
351             for(reportStyleIdx =0;reportStyleIdx<ricReportStyle->list.count; reportStyleIdx++)
352             {
353                if(ricReportStyle->list.array[reportStyleIdx])
354                {
355                   if(ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.buf)
356                   {
357                      DU_FREE(ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.buf,\
358                            ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.size);
359                   }
360                   if(ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.array)
361                   {
362                      for(measInfoIdx=0; measInfoIdx<ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.count; \
363                            measInfoIdx++)
364                      {
365                         measInfoList = ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.array[measInfoIdx];
366                         if(measInfoList)
367                         {
368                            DU_FREE(measInfoList->measID, sizeof(long));
369                            DU_FREE(measInfoList->measName.buf, measInfoList->measName.size);
370                            DU_FREE(measInfoList,sizeof(MeasurementInfo_Action_Item_t)); 
371                         }
372                      }
373                      DU_FREE(measInfoList,ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.size);
374                   }
375                   DU_FREE(ricReportStyle->list.array[reportStyleIdx], sizeof(RIC_ReportStyle_Item_t));
376                }
377             }
378             DU_FREE(ricReportStyle->list.array, ricReportStyle->list.size);
379          }
380          DU_FREE(ricReportStyle, sizeof(struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List));
381       }
382       DU_FREE(ranFunctionDefinition, sizeof(E2SM_KPM_RANfunction_Description_t)); 
383    }
384 }
385
386 /*******************************************************************
387  *
388  * @brief fill the e2sm ric report style
389  *
390  * @details
391  *
392  *    Function : fillRicReportStyle
393  *
394  *    Functionality: fill the report style
395  *
396  * @params[in]   RanFunction *ranFuncDb, struct
397  * E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle
398  * @return ROK     - success
399  *         RFAILED - failure
400  *
401  ******************************************************************/
402 uint8_t fillRicReportStyle(RanFunction *ranFuncDb, struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle)
403 {
404    uint8_t styleIdx, measInfoIdx;
405    MeasurementInfo_Action_List_t *measInfo;
406    CmLList  *node;
407    
408    ricReportStyle->list.count = ranFuncDb->numOfReportStyleSupported;
409    ricReportStyle->list.size = ricReportStyle->list.count * sizeof(RIC_ReportStyle_Item_t*);
410    DU_ALLOC(ricReportStyle->list.array, ricReportStyle->list.size);
411    if(!ricReportStyle->list.array)
412    {
413       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for ranFuncDefinition %d",__LINE__);
414       return RFAILED;
415    }
416
417    for(styleIdx =0;styleIdx<ricReportStyle->list.count; styleIdx++)
418    {
419       DU_ALLOC(ricReportStyle->list.array[styleIdx], sizeof(RIC_ReportStyle_Item_t));
420       if(!ricReportStyle->list.array[styleIdx])
421       {
422          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
423          return RFAILED;
424       }
425       
426       /* RIC Report Style Type */
427       ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Type = ranFuncDb->reportStyleList[styleIdx].reportStyle.styleType;
428       
429       /* RIC Report Style Format Type */
430       ricReportStyle->list.array[styleIdx]->ric_ActionFormat_Type = ranFuncDb->reportStyleList[styleIdx].reportStyle.formatType;
431       
432       /* RIC Report Style Name */
433       ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size = strlen(ranFuncDb->reportStyleList[styleIdx].reportStyle.name);
434       DU_ALLOC(ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf,\
435             ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size);
436       if(!ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf)
437       {
438          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
439          return RFAILED;
440       }
441       memcpy(ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf, ranFuncDb->reportStyleList[styleIdx].reportStyle.name,\
442             ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size);
443
444       /* RIC Indication Header Format Type*/
445       ricReportStyle->list.array[styleIdx]->ric_IndicationHeaderFormat_Type = ranFuncDb->ricIndicationHeaderFormat;
446
447       /* RIC Indication Message Format Type*/
448       ricReportStyle->list.array[styleIdx]->ric_IndicationMessageFormat_Type = ranFuncDb->ricIndicationMessageFormat;
449       
450       /* Measurement Info Action List */
451       CmLListCp measInfoList =ranFuncDb->reportStyleList[styleIdx].measurementInfoList;
452       if(!measInfoList.count)
453       {
454          continue;      
455       }
456
457       CM_LLIST_FIRST_NODE(&ranFuncDb->reportStyleList[styleIdx].measurementInfoList, node);
458       measInfo = &ricReportStyle->list.array[styleIdx]->measInfo_Action_List;
459
460       measInfo->list.count = measInfoList.count; 
461       measInfo->list.size =  measInfoList.count*sizeof(MeasurementInfo_Action_Item_t*);
462       DU_ALLOC(measInfo->list.array, measInfo->list.size);
463       if(!measInfo->list.array)
464       {
465          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
466          return RFAILED;
467       }
468
469       for(measInfoIdx=0; measInfoIdx<measInfo->list.count; measInfoIdx++)
470       {
471          if(!node)
472          {
473             DU_LOG("\nERROR  --> E2AP: Measurement info node is null");
474             return RFAILED;
475          }
476
477          DU_ALLOC(measInfo->list.array[measInfoIdx],sizeof(MeasurementInfo_Action_Item_t));  
478          if(!measInfo->list.array[measInfoIdx])
479          {
480             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
481             return RFAILED;
482          }
483          MeasurementInfoForAction *measInfoForAction= (MeasurementInfoForAction*)node->node;
484          DU_ALLOC(measInfo->list.array[measInfoIdx]->measID, sizeof(long));
485          if(!measInfo->list.array[measInfoIdx]->measID)
486          {
487             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
488             return RFAILED;
489          }
490          
491          memcpy(measInfo->list.array[measInfoIdx]->measID, &measInfoForAction->measurementTypeId,sizeof(long));
492          measInfo->list.array[measInfoIdx]->measName.size= strlen(measInfoForAction->measurementTypeName);
493          DU_ALLOC(measInfo->list.array[measInfoIdx]->measName.buf, measInfo->list.array[measInfoIdx]->measName.size);
494          if(!measInfo->list.array[measInfoIdx]->measName.size)
495          {
496             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
497             return RFAILED;
498          }
499
500          memcpy(measInfo->list.array[measInfoIdx]->measName.buf, \
501                measInfoForAction->measurementTypeName,\
502                measInfo->list.array[measInfoIdx]->measName.size);
503          node = node->next;
504       }
505
506    }
507    return ROK;
508 }
509 /*******************************************************************
510  *
511  * @brief fill the ric event trigger style
512  *
513  * @details
514  *
515  *    Function : fillRicEventTriggerStyle
516  *
517  *    Functionality: fill the ric event trigger style
518  *
519  * @params[in]   
520  * @return ROK     - success
521  *         RFAILED - failure
522  *
523  ******************************************************************/
524 uint8_t fillRicEventTriggerStyle(RanFunction *ranFuncDb, struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List *ricEventTriggerStyle)
525 {
526    uint8_t styleIdx;
527
528    ricEventTriggerStyle->list.count = ranFuncDb->numOfEventTriggerStyleSupported;
529    ricEventTriggerStyle->list.size = ricEventTriggerStyle->list.count*  sizeof(RIC_EventTriggerStyle_Item_t *);
530    DU_ALLOC(ricEventTriggerStyle->list.array, ricEventTriggerStyle->list.size);
531    if(!ricEventTriggerStyle->list.array)
532    {
533       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for ric_EventTriggerStyle_List %d",__LINE__);
534       return RFAILED;
535    }
536
537    for(styleIdx =0;styleIdx<ricEventTriggerStyle->list.count; styleIdx++)
538    {
539       DU_ALLOC(ricEventTriggerStyle->list.array[styleIdx], sizeof(RIC_EventTriggerStyle_Item_t ));
540       if(!ricEventTriggerStyle->list.array[styleIdx])
541       {
542          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
543          return RFAILED;
544       }
545       ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Type = ranFuncDb->eventTriggerStyleList[styleIdx].styleType;
546
547       ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerFormat_Type = ranFuncDb->eventTriggerStyleList[styleIdx].formatType;
548
549       ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.size = strlen(ranFuncDb->eventTriggerStyleList[styleIdx].name);
550       DU_ALLOC(ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.buf,\
551             ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.size);
552       if(!ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.buf)
553       {
554          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
555          return RFAILED;
556       }
557       memcpy(ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.buf,ranFuncDb->eventTriggerStyleList[styleIdx].name,\
558             ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.size);
559    
560    }
561    return ROK;
562 }
563
564 /*******************************************************************
565  *
566  * @brief Builds Ran function item
567  *
568  * @details
569  *
570  *    Function : BuildRanFunctionItem  
571  *
572  *    Functionality: Building RAN function item
573  *
574  * @params[in] 
575  *             RAN function item that has to be filled 
576  *             Stored RAN Function information
577  * @return ROK     - success
578  *         RFAILED - failure
579  *
580  ******************************************************************/
581
582 uint8_t BuildRanFunctionItem(RANfunction_Item_t *ranFuncItem, RanFunction *ranFuncDb)
583 {
584    uint8_t ret =RFAILED;
585    RANfunctionDefinition_t  *ranFunctionDefinition;
586    RANfunction_Name_t *ranFuncName;
587    asn_enc_rval_t encRetVal;
588    E2SM_KPM_RANfunction_Description_t *ranFuncDefinition;
589    
590    while(true)
591    {
592       /* RAN function Id*/
593       ranFuncItem->ranFunctionID = ranFuncDb->id;
594
595       /* RAN Function Revision*/
596       ranFuncItem->ranFunctionRevision = ranFuncDb->revisionCounter;
597
598       /* RAN function OID*/
599       ranFuncItem->ranFunctionOID.size = strlen(ranFuncDb->name.serviceModelOID);
600       DU_ALLOC(ranFuncItem->ranFunctionOID.buf, ranFuncItem->ranFunctionOID.size);
601       if(!ranFuncItem->ranFunctionOID.buf)
602       {
603          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
604          break;
605       }
606       memcpy(ranFuncItem->ranFunctionOID.buf, ranFuncDb->name.serviceModelOID, ranFuncItem->ranFunctionOID.size);
607
608       /* RAN function Definition */
609       DU_ALLOC(ranFuncDefinition, sizeof(E2SM_KPM_RANfunction_Description_t));
610       if(!ranFuncDefinition)
611       {
612          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
613          break;
614       }
615
616       /* RAN function Name */
617       ranFuncName = &ranFuncDefinition->ranFunction_Name;
618
619       /* RAN function ShortName */
620       ranFuncName->ranFunction_ShortName.size = strlen(ranFuncDb->name.shortName); 
621       DU_ALLOC(ranFuncName->ranFunction_ShortName.buf,  ranFuncName->ranFunction_ShortName.size);
622       if(!ranFuncName->ranFunction_ShortName.buf)
623       {
624          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
625          break;
626       }
627       memcpy(ranFuncName->ranFunction_ShortName.buf, ranFuncDb->name.shortName, strlen(ranFuncDb->name.shortName));
628
629       /* RAN function E2SM_OID */
630       ranFuncName->ranFunction_E2SM_OID.size = strlen(ranFuncDb->name.serviceModelOID);
631       DU_ALLOC(ranFuncName->ranFunction_E2SM_OID.buf, ranFuncName->ranFunction_E2SM_OID.size);
632       if(!ranFuncName->ranFunction_E2SM_OID.buf)
633       {
634          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
635          break;
636       }
637       memcpy(ranFuncName->ranFunction_E2SM_OID.buf, ranFuncDb->name.serviceModelOID, ranFuncName->ranFunction_E2SM_OID.size);
638
639       /* RAN Function Name Description */
640       ranFuncName->ranFunction_Description.size = strlen(ranFuncDb->name.description);
641       DU_ALLOC(ranFuncName->ranFunction_Description.buf, ranFuncName->ranFunction_Description.size);
642       if(!ranFuncName->ranFunction_Description.buf)
643       {
644          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
645          break;
646       }
647       memcpy(ranFuncName->ranFunction_Description.buf, ranFuncDb->name.description, ranFuncName->ranFunction_Description.size);
648
649       /* RIC Event Trigger Style List */
650       DU_ALLOC(ranFuncDefinition->ric_EventTriggerStyle_List, sizeof(struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List));
651       if(!ranFuncDefinition->ric_EventTriggerStyle_List)
652       {
653          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
654          break;
655       }
656
657       if(fillRicEventTriggerStyle(ranFuncDb, ranFuncDefinition->ric_EventTriggerStyle_List)!=ROK)
658       {
659          DU_LOG("\nERROR  --> E2AP: failed to fill ric event trigger style");
660          break;
661       }
662
663       /* RIC Report Style List */
664       DU_ALLOC(ranFuncDefinition->ric_ReportStyle_List, sizeof(struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List));
665       if(!ranFuncDefinition->ric_ReportStyle_List)
666       {
667          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
668          break;
669       }
670       if(fillRicReportStyle(ranFuncDb, ranFuncDefinition->ric_ReportStyle_List) != ROK)
671       {
672          DU_LOG("\nERROR  --> E2AP: failed to fill ric report style");
673          break;
674       }
675
676       /* Encode the F1SetupRequest type as APER */
677       xer_fprint(stdout, &asn_DEF_E2SM_KPM_RANfunction_Description, ranFuncDefinition);
678
679       memset(encBuf, 0, ENC_BUF_MAX_LEN);
680       encBufSize = 0;
681       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_RANfunction_Description, 0, ranFuncDefinition, PrepFinalEncBuf, encBuf);
682
683       /* Encode results */
684       if(encRetVal.encoded == ENCODE_FAIL)
685       {
686          DU_LOG("\nERROR  -->  F1AP : Could not encode RAN function definition  (at %s)\n",\
687                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
688          break;
689       }
690       else
691       {
692          DU_LOG("\nDEBUG   -->  F1AP : Created APER encoded buffer for RAN function definition \n");
693          for(uint8_t measIeIdx=0; measIeIdx< encBufSize; measIeIdx++)
694          {
695             printf("%x",encBuf[measIeIdx]);
696          }
697          ranFunctionDefinition = &ranFuncItem->ranFunctionDefinition; 
698          ranFunctionDefinition->size = encBufSize;
699          DU_ALLOC(ranFunctionDefinition->buf, encBufSize);
700          if(ranFunctionDefinition->buf == NULLP)
701          {
702             DU_LOG("\nERROR  -->  F1AP : Memory allocation failed for RAN function definition buffer");
703             break;
704          }
705          memcpy(ranFunctionDefinition->buf, &encBuf, encBufSize);
706          ret = ROK;
707          break;
708       }
709    }
710    freeE2smKpmRanFunctionDefinition(ranFuncDefinition);
711    return ret;
712 }
713
714 /*******************************************************************
715  *
716  * @brief Builds Ran function add list based on the procedure code
717  *
718  * @details
719  *
720  *    Function : BuildRanFunctionAddList 
721  *
722  *    Functionality: Building RAN addition addition list
723  *       In case of ProcedureCodeE2_id_E2setup we add all the RAN Function list
724  *       which is present in E2 database.
725  *       In the case of other procedures, we just fill the RAN functions whose ID 
726  *       is contained in recvList
727  *
728  * @params[in] 
729  *       RAN Function list
730  *       Procedure code
731  *       Count of ran functions to be added in the list
732  *       Received list of RAN functions
733  *
734  * @return ROK     - success
735  *         RFAILED - failure
736  *
737  ******************************************************************/
738
739 uint8_t BuildRanFunctionAddList(RANfunctions_List_t *ranFunctionsList, uint8_t procedureCode, uint8_t count, RanFuncInfo *recvList)
740 {
741    uint16_t id;
742    RanFunction *ranFuncDb;
743    uint8_t ranFuncIdx;
744    RANfunction_ItemIEs_t *ranFuncItemIe;
745    
746    /* For ProcedureCodeE2_id_E2setup, the number of RAN function list items is
747     * equal to the number of ran function entries stored in the database.
748     * For any other procedure, the RAN function list count is equal
749     * to the count of ran functions obtained from the function's caller */
750
751    if(procedureCode == ProcedureCodeE2_id_E2setup)
752       ranFunctionsList->list.count = duCb.e2apDb.numOfRanFunction;
753    else
754       ranFunctionsList->list.count = count;
755
756    ranFunctionsList->list.size = ranFunctionsList->list.count * sizeof(RANfunction_ItemIEs_t*);
757    DU_ALLOC(ranFunctionsList->list.array, ranFunctionsList->list.size);
758    if(ranFunctionsList->list.array == NULLP)
759    {
760       DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
761       return RFAILED;
762    }
763
764    for(ranFuncIdx = 0; ranFuncIdx< ranFunctionsList->list.count; ranFuncIdx++)
765    {
766       DU_ALLOC(ranFunctionsList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
767       if(ranFunctionsList->list.array[ranFuncIdx] == NULLP)
768       {
769          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
770          return RFAILED;
771       }
772       if(procedureCode == ProcedureCodeE2_id_E2setup) 
773       {
774          /* Getting all of the RAN function's information from DuCb one by one*/
775          ranFuncDb = &duCb.e2apDb.ranFunction[ranFuncIdx];
776       }
777       else
778       {
779          /* Getting only the RAN function information from DuCb whose Id is
780           * present in the received array */
781          id =recvList[ranFuncIdx].id;
782          ranFuncDb = &duCb.e2apDb.ranFunction[id-1];
783       }
784       ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncIdx];
785       ranFuncItemIe->id = ProtocolIE_IDE2_id_RANfunction_Item;
786       ranFuncItemIe->criticality = CriticalityE2_ignore;
787       ranFuncItemIe->value.present = RANfunction_ItemIEs__value_PR_RANfunction_Item;
788       BuildRanFunctionItem(&ranFuncItemIe->value.choice.RANfunction_Item, ranFuncDb);
789    }
790    return ROK;
791 }   
792
793 /*******************************************************************
794  *
795  * @brief De Allocate E2 Setup Request Message
796  *
797  * @details
798  *
799  *    Function : FreeE2SetupReq
800  *
801  *    Functionality: De-Allocating E2 Setup request Message
802  *
803  * @params[in] E2AP_PDU_t *e2apMsg
804  
805  * @return void
806  *
807  * ****************************************************************/
808
809 void FreeE2SetupReq(E2AP_PDU_t *e2apMsg)
810 {
811    uint8_t arrIdx = 0;
812    uint8_t e2NodeAddListIdx =0, ranFuncAddListIdx;
813    E2setupRequest_t *e2SetupReq;
814    E2nodeComponentConfigAddition_List_t *e2NodeAddList;
815    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
816    RANfunctions_List_t *ranFunctionsList;
817    RANfunction_ItemIEs_t *ranFuncItemIe;
818    RANfunction_Item_t  *ranFunItem;
819
820    /* De-allocating Memory */
821    if(e2apMsg != NULLP)
822    {
823       if(e2apMsg->choice.initiatingMessage != NULLP)
824       {
825          e2SetupReq = &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest; 
826          if(e2SetupReq->protocolIEs.list.array != NULLP)
827          {
828             for(arrIdx = 0; arrIdx < e2SetupReq->protocolIEs.list.count; arrIdx++)
829             {
830                if(e2SetupReq->protocolIEs.list.array[arrIdx] != NULLP)
831                {
832                   switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
833                   {
834                      case ProtocolIE_IDE2_id_TransactionID:
835                           break;
836                      case ProtocolIE_IDE2_id_GlobalE2node_ID:
837                         {
838                            if(e2SetupReq->protocolIEs.list.array[arrIdx]->\
839                                  value.choice.GlobalE2node_ID.choice.gNB != NULLP)
840                            {
841                               GlobalE2node_gNB_ID_t *gNbId = NULLP;
842                               gNbId = e2SetupReq->protocolIEs.list.array[arrIdx]->\
843                                       value.choice.GlobalE2node_ID.choice.gNB;
844                               if(gNbId->global_gNB_ID.plmn_id.buf != NULLP)
845                               {
846                                  DU_FREE(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf,\
847                                        gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size);
848                                  DU_FREE(gNbId->global_gNB_ID.plmn_id.buf,\
849                                        gNbId->global_gNB_ID.plmn_id.size);
850                               }
851
852                               if(gNbId->gNB_DU_ID != NULLP)
853                               {
854                                  DU_FREE( gNbId->gNB_DU_ID->buf, gNbId->gNB_DU_ID->size);
855                                  DU_FREE(gNbId->gNB_DU_ID, sizeof(GNB_DU_ID_t));
856                               }
857                               DU_FREE(e2SetupReq->protocolIEs.list.array[arrIdx]->value.\
858                                     choice.GlobalE2node_ID.choice.gNB, sizeof(GlobalE2node_gNB_ID_t));
859                            }
860                            break;
861                         }
862                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
863                      {
864                          e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;
865                          if(e2NodeAddList->list.array)
866                          {
867                              for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
868                              {
869                                 e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
870                                 
871                                 /* Free E2 Node Component Request Part */
872                                 DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\
873                                       e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentRequestPart.size);
874                                 
875                                 /* Free E2 Node Component Response Part */
876                                 DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.\
877                                       e2nodeComponentResponsePart.buf, \
878                                       e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentResponsePart.size);
879                                  
880                                  /* Free E2 Node Component ID */
881                                 if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1)
882                                 {
883                                     DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
884                                     e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
885                                     e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
886                                     e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
887                                     DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\
888                                     sizeof(E2nodeComponentInterfaceF1_t));
889                                 }
890                                 DU_FREE(e2NodeAddList->list.array[e2NodeAddListIdx], sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
891                              }
892                              DU_FREE(e2NodeAddList->list.array, e2NodeAddList->list.size);
893                          }
894                          break;
895                      }
896                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
897                      {
898                         ranFunctionsList = &(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List);  
899                         if(ranFunctionsList->list.array)
900                         {  
901                            for(ranFuncAddListIdx= 0; ranFuncAddListIdx< ranFunctionsList->list.count; ranFuncAddListIdx++)
902                            {
903                               if(ranFunctionsList->list.array[ranFuncAddListIdx])
904                               {
905                                  ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncAddListIdx];
906                                  ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
907                                  DU_FREE(ranFunItem->ranFunctionOID.buf, ranFunItem->ranFunctionOID.size);
908                                  DU_FREE(ranFunItem->ranFunctionDefinition.buf, ranFunItem->ranFunctionDefinition.size);
909                                  DU_FREE(ranFunctionsList->list.array[ranFuncAddListIdx], sizeof(RANfunction_ItemIEs_t));
910                               }
911                            }
912                            DU_FREE(ranFunctionsList->list.array, ranFunctionsList->list.size);
913                         }
914                         break;
915                      }
916
917                      default:
918                         DU_LOG("\nERROR  --> E2AP: Invalid event at e2SetupRequet %ld ",\
919                               (e2SetupReq->protocolIEs.list.array[arrIdx]->id));
920                         break;
921                   }
922                   DU_FREE(e2SetupReq->protocolIEs.list.array[arrIdx], sizeof(E2setupRequestIEs_t));
923                }
924             }
925             DU_FREE(e2SetupReq->protocolIEs.list.array, e2SetupReq->protocolIEs.list.size);
926          }
927          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
928       }
929       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
930    }
931 }
932
933 /*******************************************************************
934  *
935  * @brief Builds and Send the E2SetupRequest
936  *
937  * @details
938  *
939  *    Function : BuildAndSendE2SetupReq
940  *
941  * Functionality:Fills the E2SetupRequest
942  *
943  * @return ROK     - success
944  *         RFAILED - failure
945  *
946  ******************************************************************/
947
948 uint8_t BuildAndSendE2SetupReq()
949 {
950    uint8_t arrIdx = 0, elementCnt=0;
951    uint8_t transId = 0, ret = ROK;
952    bool memAllocFailed;
953    E2AP_PDU_t        *e2apMsg = NULLP;
954    E2setupRequest_t  *e2SetupReq = NULLP;
955    asn_enc_rval_t     encRetVal;       /* Encoder return value */
956
957    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup Request\n");
958    do
959    {
960       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
961       if(e2apMsg == NULLP)
962       {
963          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
964          break;
965       }
966       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
967       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
968       if(e2apMsg->choice.initiatingMessage == NULLP)
969       {
970          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
971          break;
972       }
973       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
974       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2setup;
975       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2setupRequest;
976       e2SetupReq = &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest;
977
978       elementCnt = 4;
979       e2SetupReq->protocolIEs.list.count = elementCnt;
980       e2SetupReq->protocolIEs.list.size = elementCnt * sizeof(E2setupRequestIEs_t*);
981
982       /* Initialize the E2Setup members */
983       DU_ALLOC(e2SetupReq->protocolIEs.list.array, \
984             e2SetupReq->protocolIEs.list.size);
985       if(e2SetupReq->protocolIEs.list.array == NULLP)
986       {
987          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
988          break;
989       }
990       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
991       {
992          DU_ALLOC(e2SetupReq->protocolIEs.list.array[arrIdx],\
993                sizeof(E2setupRequestIEs_t));
994          if(e2SetupReq->protocolIEs.list.array[arrIdx] == NULLP)
995          {
996             memAllocFailed = true;
997             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayarrIdx [%d]", arrIdx);
998             break;
999          }
1000       }
1001       if(memAllocFailed == true)
1002          break;
1003
1004       arrIdx = 0;
1005
1006       /* TransactionID */
1007       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
1008       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1009       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
1010       transId = assignTransactionId();
1011       e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
1012
1013       arrIdx++;
1014       /* GlobalE2node_gNB_ID */
1015       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_GlobalE2node_ID;
1016       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1017       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_GlobalE2node_ID;
1018       e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.present = GlobalE2node_ID_PR_gNB;
1019
1020       DU_ALLOC(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.\
1021             GlobalE2node_ID.choice.gNB, sizeof(GlobalE2node_gNB_ID_t));
1022       if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.\
1023             GlobalE2node_ID.choice.gNB == NULLP)
1024       {
1025          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for gNbId");
1026          break;
1027       }
1028       else
1029       {
1030          ret = BuildGlobalgNBId(e2SetupReq->protocolIEs.list.array[arrIdx]->value.\
1031                choice.GlobalE2node_ID.choice.gNB);
1032          if(ret != ROK)
1033          {
1034              DU_LOG("\nERROR  -->  E2AP : Failed to build Global Gnb Id");
1035              break;
1036          }
1037       }
1038       
1039       /* RAN Functions Added List */
1040       arrIdx++;
1041       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAdded;
1042       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1043       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_RANfunctions_List;
1044       if(BuildRanFunctionAddList(&(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List), ProcedureCodeE2_id_E2setup, 0, NULL)!=ROK)      
1045       {
1046          DU_LOG("\nERROR  -->  E2AP : Failed to create RAN Function");
1047          break;
1048       }
1049
1050       /* E2 Node Component Configuration Addition List */
1051       arrIdx++;
1052       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition;
1053       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1054       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_E2nodeComponentConfigAddition_List;
1055       if(BuildE2NodeConfigAddList(&(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List))!=ROK)
1056       {
1057          DU_LOG("\nERROR  -->  E2AP : Failed to create E2 Node config list");
1058          break;
1059       }
1060
1061
1062
1063       /* Prints the Msg formed */
1064       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1065
1066       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1067       encBufSize = 0;
1068       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
1069             encBuf);
1070       if(encRetVal.encoded == ENCODE_FAIL)
1071       {
1072          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupRequest structure (at %s)\n",\
1073                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1074          break;
1075       }
1076       else
1077       {
1078          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2SetupRequest\n");
1079 #ifdef DEBUG_ASN_PRINT
1080          for(int i=0; i< encBufSize; i++)
1081          {
1082             printf("%x",encBuf[i]);
1083          }
1084 #endif
1085       }
1086       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
1087       {
1088          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
1089       }
1090       break;
1091    }while(true);
1092
1093    duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
1094    duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
1095    
1096    FreeE2SetupReq(e2apMsg);
1097    return ret;
1098 }/* End of BuildAndSendE2SetupReq */
1099
1100 /*******************************************************************
1101  *
1102  * @brief Builds Ric Request Id
1103  *
1104  * @details
1105  *
1106  *    Function : BuildRicRequestId
1107  *
1108  *    Functionality: Building the Ric Request Id
1109  *
1110  * @params[in] RICrequestID_t *ricReqId
1111  * @return ROK     - success
1112  *         RFAILED - failure
1113  *
1114  * ****************************************************************/
1115
1116 uint8_t BuildRicRequestId(RICrequestID_t *ricReqId)
1117 {
1118    if(ricReqId == NULLP)
1119    {
1120       return RFAILED;
1121    }
1122
1123    ricReqId->ricRequestorID = 1;
1124    ricReqId->ricInstanceID  = 1;
1125    return ROK;
1126 }
1127
1128 /*******************************************************************
1129  *
1130  * @brief Fills the mandatory RicAdmitted List Items
1131  *
1132  * @details
1133  *
1134  *    Function : fillRicAdmitList
1135  *
1136  *    Functionality: Fills the mandatory Ric Admitted List Items
1137  *
1138  * @params[in] RICaction_Admitted_ItemIEs_t *ricAdmitItems
1139  * @return ROK     - success
1140  *         RFAILED - failure
1141  *
1142  * ****************************************************************/
1143
1144 uint8_t fillRicAdmitList(RICaction_Admitted_ItemIEs_t *ricAdmitItems)
1145 {
1146
1147    if(ricAdmitItems != NULLP)
1148    {
1149       ricAdmitItems->id = ProtocolIE_IDE2_id_RICaction_Admitted_Item;
1150       ricAdmitItems->criticality = CriticalityE2_reject;
1151       ricAdmitItems->value.present = RICaction_Admitted_ItemIEs__value_PR_RICaction_Admitted_Item;
1152       ricAdmitItems->value.choice.RICaction_Admitted_Item.ricActionID = 1; 
1153    }
1154    else
1155    {
1156       return RFAILED;
1157    }
1158    return ROK;
1159 }
1160 /*******************************************************************
1161  *
1162  * @brief Builds the mandatory RicAdmitted List Params
1163  *
1164  * @details
1165  *
1166  *    Function : BuildRicAdmitList
1167  *
1168  *    Functionality: Builds the mandatory Ric Admitted List Params
1169  *
1170  * @params[in] RICaction_Admitted_List_t *admitListPtr
1171  * @return ROK     - success
1172  *         RFAILED - failure
1173  *
1174  * ****************************************************************/
1175
1176 uint8_t BuildRicAdmitList(RICaction_Admitted_List_t *admitListPtr)
1177 {
1178    uint8_t idx ;
1179    uint8_t elementCnt;  
1180    uint8_t ret= ROK;
1181    elementCnt = 1;
1182
1183    if(admitListPtr == NULLP)
1184    {
1185       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC Admit List failed");
1186       ret = RFAILED;
1187    }
1188    else
1189    {
1190       admitListPtr->list.count = elementCnt;
1191       admitListPtr->list.size  = elementCnt * sizeof(RICaction_Admitted_ItemIEs_t);
1192       DU_ALLOC(admitListPtr->list.array, admitListPtr->list.size);
1193       if(admitListPtr->list.array == NULLP)
1194       {
1195          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC Admit List failed");
1196          ret = RFAILED;
1197       }
1198       else
1199       {
1200          for(idx=0 ; idx<elementCnt ; idx++ )
1201          {
1202             DU_ALLOC(admitListPtr->list.array[idx], sizeof(RICaction_Admitted_ItemIEs_t));
1203             if(admitListPtr->list.array[idx] == NULLP)
1204             {
1205                ret = RFAILED;
1206             }
1207          }
1208          if(ret != RFAILED)
1209          {
1210             idx=0;
1211             fillRicAdmitList((RICaction_Admitted_ItemIEs_t *)admitListPtr->list.array[idx]);
1212          }
1213       }
1214    }    
1215    return ret;
1216 }
1217 /*******************************************************************
1218  *
1219  * @breif Deallocation of BuildAndSendRicSubscriptionRsp memory
1220  *
1221  * @details
1222  *
1223  *    Function : FreeRicSubscriptionRsp
1224  *
1225  * Functionality:Free the RicSubscriptionRsp
1226  *
1227  * @param[in] E2AP_PDU_t *e2apRicMsg
1228  *
1229  * @return void
1230  *      
1231  *
1232  ******************************************************************/
1233 void FreeRicSubscriptionRsp(E2AP_PDU_t  *e2apRicMsg)
1234 {
1235    RICsubscriptionResponse_t  *ricSubscriptionRsp= NULLP;
1236    uint8_t idx=0;
1237    uint8_t idx1=0;
1238    RICaction_Admitted_List_t *admitListPtr;
1239
1240    if(e2apRicMsg != NULLP)
1241    {
1242       if(e2apRicMsg->choice.successfulOutcome != NULLP)
1243       {
1244          ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
1245          if(ricSubscriptionRsp)
1246          {
1247             if(ricSubscriptionRsp->protocolIEs.list.array != NULLP)
1248             {
1249                for(idx=0; idx<ricSubscriptionRsp->protocolIEs.list.count; idx++)
1250                {
1251                   if(ricSubscriptionRsp->protocolIEs.list.array[idx] != NULLP)
1252                   {
1253                      switch(ricSubscriptionRsp->protocolIEs.list.array[idx]->id)
1254                      {
1255                         case ProtocolIE_IDE2_id_RICrequestID:
1256                            break;
1257
1258                         case ProtocolIE_IDE2_id_RANfunctionID:
1259                            break;
1260
1261                         case ProtocolIE_IDE2_id_RICactions_Admitted:
1262                            {
1263                               admitListPtr = &ricSubscriptionRsp->protocolIEs.list.\
1264                                              array[idx]->value.choice.RICaction_Admitted_List;
1265                               if(admitListPtr->list.array != NULLP)
1266                               {
1267                                  for(idx1=0 ; idx1<admitListPtr->list.count; idx1++ )
1268                                  {
1269                                     if(admitListPtr->list.array[idx1] != NULLP)
1270                                     {
1271                                        DU_FREE(admitListPtr->list.array[idx1],
1272                                              sizeof(RICaction_Admitted_ItemIEs_t));
1273                                     }
1274                                  }
1275                                  DU_FREE(admitListPtr->list.array, admitListPtr->list.size);     
1276                               }
1277                               break;
1278                            }
1279                         default:
1280                            break;
1281                      }
1282                      DU_FREE(ricSubscriptionRsp->protocolIEs.list.array[idx], \
1283                            sizeof(RICsubscriptionResponse_IEs_t));
1284                   }
1285                }
1286                DU_FREE(ricSubscriptionRsp->protocolIEs.list.array, \
1287                      ricSubscriptionRsp->protocolIEs.list.size);
1288             }
1289          }   
1290          DU_FREE(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1291       }         
1292       DU_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));        
1293    }
1294 }
1295 /*******************************************************************
1296  *
1297  * @brief Builds and Send the RicSubscriptionRsp
1298  *
1299  * @details
1300  *
1301  *    Function : BuildAndSendRicSubscriptionRsp
1302  *
1303  * functionality:Fills the RicSubscriptionRsp
1304  *
1305  * @return ROK     - success
1306  *         RFAILED - failure
1307  *
1308  ******************************************************************/
1309 uint8_t  FillRicSubscriptionRsp(RICsubscriptionResponse_t  *ricSubscriptionRsp )
1310 {
1311    uint8_t idx=0;
1312    uint8_t ret = ROK;
1313    uint8_t elementCnt = 0;
1314    uint8_t BuildRicRequestIdret=ROK;
1315    uint8_t BuildRicAdmitListret=ROK;
1316
1317    elementCnt=3;
1318    ricSubscriptionRsp->protocolIEs.list.count = elementCnt;
1319    ricSubscriptionRsp->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionResponse_IEs_t);
1320    DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array, \
1321          ricSubscriptionRsp->protocolIEs.list.size);
1322    if(ricSubscriptionRsp->protocolIEs.list.array == NULLP)
1323    {
1324       DU_LOG("\nERROR  -->  E2AP : Memory allocation for FillRicSubscriptionRsp  failed");
1325       ret = RFAILED;
1326    }
1327    else
1328    {
1329       for(idx=0; idx<ricSubscriptionRsp->protocolIEs.list.count; idx++)
1330       {
1331          DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array[idx], \
1332                sizeof(RICsubscriptionResponse_IEs_t));
1333          if(ricSubscriptionRsp->protocolIEs.list.array[idx] == NULLP)
1334          {
1335             ret = RFAILED;
1336          }
1337       }
1338       if(ret != RFAILED)
1339       {
1340
1341          idx=0;
1342          ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
1343          ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1344          ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
1345                                                                          RICsubscriptionRequest_IEs__value_PR_RICrequestID;
1346          BuildRicRequestIdret =
1347             BuildRicRequestId(&ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RICrequestID);
1348          if(BuildRicRequestIdret != ROK)
1349          {
1350             ret = RFAILED;
1351          }
1352          else
1353          {
1354             idx++;
1355             ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
1356             ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1357             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
1358                                                                             RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
1359             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1;
1360
1361             idx++;
1362             ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactions_Admitted;
1363             ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1364             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
1365                                                                             RICsubscriptionResponse_IEs__value_PR_RICaction_Admitted_List;
1366             BuildRicAdmitListret =
1367                BuildRicAdmitList(&ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RICaction_Admitted_List);
1368             if(BuildRicAdmitListret != ROK)
1369             {
1370                ret = RFAILED;
1371             }
1372          }
1373       }
1374    }    
1375    return ret;
1376 }
1377 /*******************************************************************
1378  *
1379  * @brief Builds and Send the RicSubscriptionRsp
1380  *
1381  * @details
1382  *
1383  *    Function : BuildAndSendRicSubscriptionRsp
1384  *
1385  * Functionality:Fills the RicSubscriptionRsp
1386  *
1387  * @return ROK     - success
1388  *         RFAILED - failure
1389  *
1390  ******************************************************************/
1391
1392 uint8_t BuildAndSendRicSubscriptionRsp()
1393 {
1394
1395    E2AP_PDU_t         *e2apRicMsg = NULLP;
1396    RICsubscriptionResponse_t  *ricSubscriptionRsp=NULLP;
1397    asn_enc_rval_t     encRetVal; 
1398    uint8_t ret = RFAILED;
1399    uint8_t FillRicricSubscriptionRspret;
1400
1401    while(true)
1402    {
1403       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Response\n");
1404
1405       DU_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t)); 
1406       if(e2apRicMsg == NULLP)
1407       {
1408          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1409          break;
1410       }
1411       e2apRicMsg->present =  E2AP_PDU_PR_successfulOutcome;
1412       DU_ALLOC(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1413       if(e2apRicMsg->choice.successfulOutcome == NULLP)
1414       {
1415          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC subscription Response failed");
1416          break;
1417       }
1418
1419       e2apRicMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
1420       e2apRicMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
1421       e2apRicMsg->choice.successfulOutcome->value.present = \
1422                                                             SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse;
1423       ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
1424
1425       FillRicricSubscriptionRspret = FillRicSubscriptionRsp(ricSubscriptionRsp);
1426       if(FillRicricSubscriptionRspret != ROK)
1427       {
1428          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICsubscriptionResponseIE failed");
1429          break;
1430       }
1431
1432       /* Prints the Msg formed */
1433       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
1434
1435       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1436       encBufSize = 0;
1437       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\
1438             encBuf);
1439       if(encRetVal.encoded == ENCODE_FAIL)
1440       {
1441          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Response structure (at %s)\n",\
1442                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1443          break;
1444       }
1445       else
1446       {
1447          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RIC subscription response \n");
1448 #ifdef DEBUG_ASN_PRINT
1449          for(int i=0; i< encBufSize; i++)
1450          {
1451             printf("%x",encBuf[i]);
1452          } 
1453 #endif
1454       } 
1455
1456       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
1457       {
1458          DU_LOG("\nERROR  -->  E2AP : Sending RIC Subscription Response failed");      
1459          break;
1460       }
1461
1462       ret = ROK;
1463       break;
1464
1465    }
1466    FreeRicSubscriptionRsp(e2apRicMsg);
1467
1468    return ret;
1469 }
1470
1471 /******************************************************************
1472  *
1473  * @brief Deallocation of memory allocated bu aper decoder for e2 setup response
1474  *
1475  * @details
1476  *
1477  *    Function : freeAperDecodingOfE2SetupRsp
1478  *
1479  *    Functionality: Deallocation of memory allocated bu aper decoder for e2
1480  *    setup response
1481  *
1482  * @params[in] E2setupResponse_t *e2SetRspMsg;
1483  * @return void
1484  *
1485  * ****************************************************************/
1486 void freeAperDecodingOfE2SetupRsp(E2setupResponse_t *e2SetRspMsg)
1487 {
1488    uint8_t arrIdx, e2NodeConfigAddAckListIdx;
1489    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem;
1490    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAddAckList;
1491
1492    if(e2SetRspMsg)
1493    {
1494       if(e2SetRspMsg->protocolIEs.list.array)
1495       {
1496          for(arrIdx=0; arrIdx<e2SetRspMsg->protocolIEs.list.count; arrIdx++)
1497          {
1498             if(e2SetRspMsg->protocolIEs.list.array[arrIdx])
1499             {
1500                switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
1501                {
1502                   case ProtocolIE_IDE2_id_TransactionID:
1503                      break;
1504
1505                   case ProtocolIE_IDE2_id_GlobalRIC_ID:
1506                      {
1507                         free(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.pLMN_Identity.buf);
1508                         free(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID.buf);
1509                         break;
1510                      }
1511
1512                   case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
1513                      {
1514                         e2NodeConfigAddAckList = &e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
1515                         if(e2NodeConfigAddAckList->list.array )
1516                         {
1517                            for(e2NodeConfigAddAckListIdx = 0; e2NodeConfigAddAckListIdx< e2NodeConfigAddAckList->list.count; e2NodeConfigAddAckListIdx++)
1518                            {
1519                               if(e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx])
1520                               {
1521                                  e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx];
1522                                  free(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.\
1523                                        e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf);
1524                                  free(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.\
1525                                        e2nodeComponentInterfaceTypeF1);
1526                                  free(e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx]);
1527                               }
1528                            }
1529                            free(e2NodeConfigAddAckList->list.array);
1530                         }
1531                         break;
1532                      }
1533                }
1534                free(e2SetRspMsg->protocolIEs.list.array[arrIdx]);  
1535             }
1536          }
1537          free(e2SetRspMsg->protocolIEs.list.array);
1538       }
1539    }
1540 }
1541 /******************************************************************
1542  *
1543  * @brief Processes E2 Setup Response sent by RIC
1544  *
1545  * @details
1546  *
1547  *    Function : procE2SetupRsp
1548  *
1549  *    Functionality: Processes E2 Setup Response sent by RIC
1550  *
1551  * @params[in] E2AP_PDU_t ASN decoded E2AP message
1552  * @return ROK     - success
1553  *         RFAILED - failure
1554  *
1555  * ****************************************************************/
1556 uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg)
1557 {
1558    uint8_t arrIdx =0, transId=0; 
1559    uint32_t recvBufLen;             
1560    E2setupResponse_t *e2SetRspMsg;
1561    CmLList         *node;
1562    E2NodeComponent *e2NodeComponentInfo;
1563
1564    DU_LOG("\nINFO   -->  E2AP : E2 Setup Response received"); 
1565    duCb.e2Status = TRUE; //Set E2 status as true
1566    e2SetRspMsg = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
1567
1568    for(arrIdx=0; arrIdx<e2SetRspMsg->protocolIEs.list.count; arrIdx++)
1569    {
1570       switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
1571       {
1572          case ProtocolIE_IDE2_id_TransactionID:
1573             {
1574                transId = e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
1575                if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
1576                      (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
1577                {
1578                   memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
1579                }
1580                else
1581                {
1582                   DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
1583                   return RFAILED;
1584                }
1585                break;
1586             }
1587
1588          case ProtocolIE_IDE2_id_GlobalRIC_ID:
1589             {
1590                /* To store the Ric Id Params */
1591                recvBufLen = sizeof(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value\
1592                      .choice.GlobalRIC_ID.pLMN_Identity.size);
1593                   memcpy(&duCb.e2apDb.ricId.plmnId, e2SetRspMsg->protocolIEs.list.array[arrIdx]\
1594                         ->value.choice.GlobalRIC_ID.pLMN_Identity.buf, recvBufLen);
1595                bitStringToInt(&e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID, &duCb.e2apDb.ricId);
1596                /*TODO : duCb.e2apDb.ricId.plmnId memory to be deallocated after the usage */
1597                break;
1598             }
1599
1600          case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
1601             break;
1602
1603          default:
1604             DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2SetupRsp:%ld",
1605                   e2SetRspMsg->protocolIEs.list.array[arrIdx]->id);
1606             break;
1607       }
1608    }
1609    freeAperDecodingOfE2SetupRsp(e2SetRspMsg);
1610    
1611    node = searchE2NodeComponentInfo(F1, E2_NODE_COMPONENT_ADD);
1612    if(!node)
1613    {
1614       DU_LOG("\nERROR  --> E2AP : Received e2NodeComponentInfo is null");
1615       return RFAILED;
1616    }
1617    else
1618    {
1619       e2NodeComponentInfo = (E2NodeComponent*)node->node;
1620       cmLListDelFrm(&duCb.e2apDb.e2NodeComponentList, node);
1621       DU_FREE(e2NodeComponentInfo->componentRequestPart, e2NodeComponentInfo->reqBufSize);
1622       DU_FREE(e2NodeComponentInfo->componentResponsePart, e2NodeComponentInfo->rspBufSize);
1623       DU_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent));
1624       DU_FREE(node, sizeof(CmLList));
1625    }
1626
1627    BuildAndSendE2NodeConfigUpdate();
1628    return ROK;
1629 }
1630
1631 /*******************************************************************
1632  *
1633  * @brief Free RIC Subscription Request
1634  *
1635  * @details
1636  *
1637  *    Function : freeAperDecodingOfRicSubsReq
1638  *
1639  * Functionality : Free RIC Subscription Request
1640  *
1641  * @return void
1642  *
1643  ******************************************************************/
1644 void freeAperDecodingOfRicSubsReq(RICsubscriptionRequest_t *ricSubscriptionReq)
1645 {
1646    uint8_t idx = 0;
1647    uint8_t elementIdx = 0;
1648    RICsubscriptionDetails_t *subsDetails = NULLP;
1649    RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
1650
1651    if(ricSubscriptionReq->protocolIEs.list.array)
1652    {
1653       for(idx=0; idx < ricSubscriptionReq->protocolIEs.list.count; idx++)
1654       {
1655          switch(ricSubscriptionReq->protocolIEs.list.array[idx]->id)
1656          {
1657             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
1658                {
1659                   subsDetails = &(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails);
1660                   free(subsDetails->ricEventTriggerDefinition.buf);
1661
1662                   if(subsDetails->ricAction_ToBeSetup_List.list.array)
1663                   {
1664                      for(elementIdx = 0; elementIdx < subsDetails->ricAction_ToBeSetup_List.list.count; elementIdx++)
1665                      {
1666                         if(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
1667                         {
1668                            actionItem = (RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.\
1669                               list.array[elementIdx];
1670                            if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
1671                            {
1672                               free(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf);
1673                               free(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition);
1674                            }
1675                            free(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx]);
1676                         }
1677                      }
1678                      free(subsDetails->ricAction_ToBeSetup_List.list.array);
1679                   }
1680                   break;
1681                }
1682          }
1683          free(ricSubscriptionReq->protocolIEs.list.array[idx]);
1684       }
1685       free(ricSubscriptionReq->protocolIEs.list.array);
1686    }
1687 }
1688
1689 /*******************************************************************
1690  *
1691  * @brief Free Event Trigger Definition
1692  *
1693  * @details
1694  *
1695  *    Function : freeAperDecodingOfEventTriggerDef
1696  *
1697  *    Functionality: Free Event Trigger Definition
1698  *
1699  * @params[in] E2SM-KPM Event Trigger Definition
1700  * @return void
1701  *
1702  * ****************************************************************/
1703 void  freeAperDecodingOfEventTriggerDef(E2SM_KPM_EventTriggerDefinition_t *eventTiggerDef)
1704 {
1705    if(eventTiggerDef)
1706    {
1707       switch(eventTiggerDef->eventDefinition_formats.present)
1708       {
1709          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING:
1710             break;
1711
1712          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1:
1713             free(eventTiggerDef->eventDefinition_formats.choice.eventDefinition_Format1);
1714             break;
1715       }
1716    }
1717 }
1718
1719 /*******************************************************************
1720  *
1721  * @brief Extract E2SM-KPM Event trigger definition
1722  *
1723  * @details
1724  *
1725  *    Function : extractEventTriggerDef
1726  *
1727  * Functionality : This function :
1728  *     - Decodes E2SM-KPM Event Trigger Definition
1729  *     - Validates that even trigger style is supported by E2 node
1730  *     - Stores event trigger details in local DB
1731  *
1732  * @params[in] RAN Function Database structure
1733  *             RIC Subscription Info to be added to RAN function
1734  *             RIC Event Trigger Definition buffer received from RIC
1735  * @return ROK     - success
1736  *         RFAILED - failure
1737  *
1738  ******************************************************************/
1739 uint8_t extractEventTriggerDef(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, RICeventTriggerDefinition_t *ricEventTriggerDef)
1740 {
1741    uint8_t ret = RFAILED;
1742    uint8_t eventIdx = 0;
1743    asn_dec_rval_t rval ={0};
1744    E2SM_KPM_EventTriggerDefinition_t eventTiggerDef, *eventTiggerDefPtr = NULLP;
1745
1746    /* Decoding E2SM-KPM Even Trigger Definition */
1747    eventTiggerDefPtr = &eventTiggerDef;
1748    memset(eventTiggerDefPtr, 0, sizeof(E2SM_KPM_EventTriggerDefinition_t));
1749
1750    rval = aper_decode(0, &asn_DEF_E2SM_KPM_EventTriggerDefinition, (void **)&eventTiggerDefPtr, ricEventTriggerDef->buf,\
1751          ricEventTriggerDef->size, 0, 0);
1752    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
1753    {
1754       DU_LOG("\nERROR  -->  E2AP : ASN decode failed for E2SM-KPM Event Trigger Definition");
1755       return RFAILED;
1756    }
1757    printf("\n");
1758    xer_fprint(stdout, &asn_DEF_E2SM_KPM_EventTriggerDefinition, eventTiggerDefPtr);
1759
1760    /* Validating the received event trigger definition format */
1761    for(eventIdx = 0; eventIdx < ranFuncDb->numOfEventTriggerStyleSupported; eventIdx++)
1762    {
1763       if((eventTiggerDefPtr->eventDefinition_formats.present != \
1764          E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING) && \
1765          (eventTiggerDefPtr->eventDefinition_formats.present == ranFuncDb->eventTriggerStyleList[eventIdx].formatType))
1766       {
1767          ricSubscriptionInfo->eventTriggerDefinition.formatType = ranFuncDb->eventTriggerStyleList[eventIdx].formatType;
1768          ricSubscriptionInfo->eventTriggerDefinition.choice.format1.reportingPeriod = \
1769             eventTiggerDefPtr->eventDefinition_formats.choice.eventDefinition_Format1->reportingPeriod;
1770
1771          ret = ROK;
1772          break;
1773       }
1774    }
1775
1776    /* Free E2SM_KPM_EventTriggerDefinition_t */
1777    freeAperDecodingOfEventTriggerDef(eventTiggerDefPtr);
1778    return ret;
1779 }
1780
1781 /*******************************************************************
1782  *
1783  * @brief Free RIC Action Definition
1784  *
1785  * @details
1786  *
1787  *    Function :  freeAperDecodingOfRicActionDefinition
1788  *
1789  *    Functionality: Free RIC Action Definition
1790  *
1791  * @params[in] E2SM-KPM Action definition
1792  * @return void
1793  *
1794  * ****************************************************************/
1795 void  freeAperDecodingOfRicActionDefinition(E2SM_KPM_ActionDefinition_t *actionDef)
1796 {
1797    uint8_t  elementIdx = 0;
1798    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
1799    MeasurementInfoItem_t *measItem = NULLP;
1800
1801    switch(actionDef->actionDefinition_formats.present)
1802    {
1803       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
1804          {
1805             if(actionDef->actionDefinition_formats.choice.actionDefinition_Format1)
1806             {
1807                actionFormat1 = actionDef->actionDefinition_formats.choice.actionDefinition_Format1;
1808                if(actionFormat1->measInfoList.list.array)
1809                {
1810                   for(elementIdx = 0; elementIdx < actionFormat1->measInfoList.list.count; elementIdx++)
1811                   {
1812                      if(actionFormat1->measInfoList.list.array[elementIdx])
1813                      {
1814                         measItem = actionFormat1->measInfoList.list.array[elementIdx];
1815                         switch(measItem->measType.present)
1816                         {
1817                            case MeasurementType_PR_NOTHING:
1818                               break;
1819
1820                            case MeasurementType_PR_measName:
1821                            {
1822                               free(measItem->measType.choice.measName.buf);
1823                               break;
1824                            }
1825
1826                            case MeasurementType_PR_measID:
1827                               break;
1828                         }
1829                         free(measItem);
1830                      }
1831                   }
1832                   free(actionFormat1->measInfoList.list.array);
1833                }
1834                free(actionFormat1);
1835             }
1836             break;
1837          }
1838       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format2:
1839       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format3:
1840       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format4:
1841       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format5:
1842       default:
1843          break;   
1844    }
1845 }
1846
1847 /*******************************************************************
1848  *
1849  * @brief Extract Measurement Info list from action definition
1850  *
1851  * @details
1852  *
1853  *    Function : extractMeasInfoList
1854  *
1855  * Functionality : This function :
1856  *     - Traverses Measurement-to-be-subscribed list
1857  *     - Validates that each measurement in Measurement-to-be-subscribed
1858  *       list is supported in RAN-Function->Measurement-supported list.
1859  *     - If all measurements in an action is supported by RAN function,
1860  *       it is added to measurement-subscribed list in local DB
1861  *
1862  * @params[in] Measurement Info supported list by RAN function
1863  *             Measurement Info to be subscribed as requested by RIC
1864  *             Measurement Info finally subscribed
1865  *             Memory failure indicator
1866  * @return ROK     - success
1867  *         RFAILED - failure
1868  *
1869  ******************************************************************/
1870 uint8_t extractMeasInfoList(CmLListCp *measInfoSupportedList, MeasurementInfoList_t *measInfoToBeSubscribedList, \
1871    CmLListCp *measInfoSubscribedList, bool *memFailure)
1872 {
1873    uint8_t elementIdx = 0;
1874    MeasurementInfoForAction *measInfoSupportedDb = NULLP;
1875    MeasurementInfo *measInfoSubscribedDb = NULLP, *measInfoToDel = NULLP;
1876    CmLList *supportedMeasNode = NULLP, *measToAddNode = NULLP, *measToDelNode = NULLP;;
1877    MeasurementInfoItem_t *measItem = NULLP;
1878
1879    /* Validate Measurement list is supported by E2 node. 
1880     *
1881     * Traverse and compare the Measurement-Supported List in E2
1882     * node with Measurement-to-be-subscribed list received from RIC.
1883     * If a match is found, add it to measurement-subscription list.
1884     */
1885    for(elementIdx = 0; elementIdx < measInfoToBeSubscribedList->list.count; elementIdx++)
1886    {
1887       measInfoSubscribedDb = NULLP;
1888       measToAddNode = NULLP;
1889       measItem = measInfoToBeSubscribedList->list.array[elementIdx];
1890
1891       CM_LLIST_FIRST_NODE(measInfoSupportedList, supportedMeasNode);
1892       while(supportedMeasNode)
1893       {
1894          measInfoSupportedDb = (MeasurementInfoForAction*)supportedMeasNode->node;
1895          switch(measItem->measType.present)
1896          {
1897             case MeasurementType_PR_measName:
1898                {
1899                   if(!strcmp(measInfoSupportedDb->measurementTypeName, (char *)measItem->measType.choice.measName.buf))
1900                   {
1901                      DU_ALLOC(measInfoSubscribedDb, sizeof(MeasurementInfo));
1902                   }
1903                   break;
1904                }
1905
1906             case MeasurementType_PR_measID:
1907                {
1908                   if(measInfoSupportedDb->measurementTypeId == measItem->measType.choice.measID)
1909                   {
1910                      DU_ALLOC(measInfoSubscribedDb, sizeof(MeasurementInfo));
1911                   }
1912                   break;
1913                }
1914
1915             default:
1916                {
1917                   DU_LOG("\nERROR  ->  DUAPP: Invalid Measurement-type identifier in \
1918                         E2SM-KPM Action Definition Format");
1919                   break;
1920                }
1921          } /* End of switch, for measurement type identifier */
1922
1923          /* If measurement type is supported, add to measurement-subscription list */
1924          if(measInfoSubscribedDb)
1925          {
1926             measInfoSubscribedDb->measurementTypeId = measInfoSupportedDb->measurementTypeId;
1927             memcpy(measInfoSubscribedDb->measurementTypeName, measInfoSupportedDb->measurementTypeName, \
1928                   strlen(measInfoSupportedDb->measurementTypeName));
1929
1930             DU_ALLOC(measToAddNode, sizeof(CmLList));
1931             if(measToAddNode)
1932             {
1933                measToAddNode->node = (PTR) measInfoSubscribedDb;
1934                cmLListAdd2Tail(measInfoSubscribedList, measToAddNode);
1935
1936                /* Break out of while loop if measurement info is found in measurement-supported list  */
1937                break;
1938             }
1939             else
1940             {
1941                DU_FREE(measInfoSubscribedDb, sizeof(MeasurementInfo));
1942                measInfoSubscribedDb = NULLP;
1943                *memFailure = true;
1944                break;
1945             }
1946          }
1947
1948          supportedMeasNode = supportedMeasNode->next;  
1949
1950       } /* End of while for traversing measurement-supported list in a report style */
1951
1952       /* If a measurement-to-be-subscribed is not found in measurement-supported list in this report style
1953        * Then :
1954        * Delete all entries from measurement-subscription list and
1955        * Break out of for loop to search in next report style */
1956       if(!measInfoSubscribedDb)
1957       {
1958          while(measInfoSubscribedList->count)
1959          {
1960             measToDelNode = cmLListDelFrm(measInfoSubscribedList, measInfoSubscribedList->first);
1961             measInfoToDel = (MeasurementInfo*)measToDelNode->node;
1962             DU_FREE(measInfoToDel, sizeof(MeasurementInfo));
1963             DU_FREE(measToDelNode, sizeof(CmLList));
1964          }
1965          break;
1966       }
1967
1968    } /* End of for loop , traversing measurement-to-be-subscribed list */
1969
1970    /* If all measurement-to-be-subscribed was found in measurement-supported list and 
1971     * was added to measurement-subscription list successfully, return from here */
1972    if(measInfoToBeSubscribedList->list.count == measInfoSubscribedList->count)
1973       return ROK;
1974
1975    return RFAILED;
1976 }
1977
1978 /*******************************************************************
1979  *
1980  * @brief Extract E2SM-KPM Action definition
1981  *
1982  * @details
1983  *
1984  *    Function : extractRicActionDef
1985  *
1986  * Functionality : This function :
1987  *     - Decodes E2SM-KPM Action Definition
1988  *     - Validates that action is supported by E2 node
1989  *     - Stores action details in local DB
1990  *
1991  * @params[in] RAN Function Database structure
1992  *             RIC subscription's Action definition to be added to 
1993  *                RAN function
1994  *             RIC Action Definition buffer received from RIC
1995  * @return ROK     - success
1996  *         RFAILED - failure
1997  *
1998  ******************************************************************/
1999 uint8_t extractRicActionDef(RanFunction *ranFuncDb, ActionDefinition *actionDefDb, RICactionDefinition_t *ricActionDef)
2000 {
2001    bool memFailure = false;
2002    uint8_t styleIdx = 0;
2003    asn_dec_rval_t rval ={0};
2004
2005    E2SM_KPM_ActionDefinition_t actionDef, *actionDefPtr = NULLP;
2006    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
2007    CmLListCp *measInfoSupportedList = NULLP;
2008    CmLListCp *measInfoSubscribedList = NULLP;
2009
2010    /* Decoding E2SM-KPM Action Definition */
2011    actionDefPtr = &actionDef;
2012    memset(actionDefPtr, 0, sizeof(E2SM_KPM_EventTriggerDefinition_t));
2013
2014    rval = aper_decode(0, &asn_DEF_E2SM_KPM_ActionDefinition, (void **)&actionDefPtr, ricActionDef->buf,\
2015          ricActionDef->size, 0, 0);
2016    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
2017    {
2018       DU_LOG("\nERROR  -->  E2AP : ASN decode failed for E2SM-KPM Action Definition");
2019       return RFAILED;
2020    }
2021    printf("\n");
2022    xer_fprint(stdout, &asn_DEF_E2SM_KPM_ActionDefinition, actionDefPtr);
2023
2024
2025    /* Validate if Report style to subscribe is supported by E2 Node */
2026    for(styleIdx= 0; styleIdx < ranFuncDb->numOfReportStyleSupported; styleIdx++)
2027    {
2028       /* Validate Report style type and report style format type is supported by E2 Node */
2029       if((ranFuncDb->reportStyleList[styleIdx].reportStyle.styleType == actionDefPtr->ric_Style_Type) &&
2030             (ranFuncDb->reportStyleList[styleIdx].reportStyle.formatType == actionDefPtr->actionDefinition_formats.present))
2031       {
2032          /* Fetch Report stype type and format type */
2033          actionDefDb->styleType = actionDefPtr->ric_Style_Type;
2034          actionDefDb->formatType = actionDefPtr->actionDefinition_formats.present;
2035
2036          switch(actionDefPtr->actionDefinition_formats.present)
2037          {
2038             case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
2039                {
2040                   actionFormat1 = actionDefPtr->actionDefinition_formats.choice.actionDefinition_Format1; 
2041
2042                   /* Fetch granularity period */
2043                   actionDefDb->choice.format1.granularityPeriod = actionFormat1->granulPeriod;
2044
2045                   /* Validate and add the Measurement to subscription list */
2046                   measInfoSupportedList = &ranFuncDb->reportStyleList[styleIdx].measurementInfoList;
2047                   measInfoSubscribedList = &actionDefDb->choice.format1.measurementInfoList;
2048                   if(extractMeasInfoList(measInfoSupportedList, &actionFormat1->measInfoList, \
2049                      measInfoSubscribedList, &memFailure) == ROK)
2050                   {
2051                      if(!memFailure)
2052                      {
2053                         /* Free E2SM_KPM_ActionDefinition_t */
2054                         freeAperDecodingOfRicActionDefinition(actionDefPtr);
2055                         return ROK;
2056                      }
2057                   }
2058
2059                   break;  /* End of E2SM-KPM Action definition format 1 case */
2060                }
2061
2062             default :
2063                {
2064                   DU_LOG("\nERROR  ->  DUAPP: Only E2SM-KPM Action Definition Format 1 is supported");
2065                   break;
2066                }
2067          } /* End of switch for E2SM-KPM Action definition formats */
2068       }
2069
2070       if(memFailure)
2071          break;
2072    } /* End of for loop, traversing Report-styles-supported list in E2 node */
2073
2074    /* Memset action Db and Free E2SM_KPM_ActionDefinition_t */
2075    memset(actionDefDb, 0, sizeof(ActionDefinition));
2076    freeAperDecodingOfRicActionDefinition(actionDefPtr);
2077    return RFAILED;
2078 }
2079
2080 /*******************************************************************
2081  *
2082  * @brief Extract RIC Action to be setup
2083  *
2084  * @details
2085  *
2086  *    Function : extractRicActionToBeSetup
2087  *
2088  * Functionality : This function :
2089  *     - Validates that each action-to-be-setup is supported by E2 node
2090  *     - Stores event trigger details in local DB
2091  *
2092  * @params[in] RAN Function Database structure
2093  *             RIC Subscription Info to be added to RAN function
2094  *             RIC Action To Be Setup List received from RIC
2095  * @return ROK     - success
2096  *         RFAILED - failure
2097  *
2098  ******************************************************************/
2099 uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, RICactions_ToBeSetup_List_t *actionList)
2100 {
2101    uint8_t actionIdx = 0;
2102    uint8_t ricActionId = 0;
2103    RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
2104
2105    if(actionList->list.array)
2106    {
2107       for(actionIdx = 0; actionIdx < actionList->list.count; actionIdx++)
2108       {
2109          actionItem =(RICaction_ToBeSetup_ItemIEs_t *)actionList->list.array[actionIdx];
2110          switch(actionItem->id)
2111          {
2112             case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item:
2113                {
2114                   /* If Action type is REPORT and 
2115                    * If RIC action definition's extraction and validation passes, 
2116                    * Then : 
2117                    * This action is added to action sequence list of subscription info */
2118                   if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType == RICactionType_report)
2119                   {
2120                      ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
2121                      ricSubscriptionInfo->actionSequence[ricActionId-1].id = ricActionId;
2122                      ricSubscriptionInfo->actionSequence[ricActionId-1].type = REPORT;
2123
2124                      if(extractRicActionDef(ranFuncDb, &ricSubscriptionInfo->actionSequence[ricActionId-1].definition, \
2125                         actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition) == ROK)
2126                      {
2127                         ricSubscriptionInfo->actionSequence[ricActionId-1].action = CONFIG_ADD;
2128                         ricSubscriptionInfo->numOfActions++;
2129                      }
2130                      else
2131                      {
2132                         memset(&ricSubscriptionInfo->actionSequence[ricActionId-1], 0, sizeof(ActionInfo));
2133                         /* TODO : Since this action addition failed, add to
2134                          * reject-action-list in subscription response */
2135                      }
2136                   }
2137                   break;
2138                }
2139             default:
2140                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id);
2141                break;
2142          }
2143       }
2144    }
2145
2146    /* If there is even 1 action that can be added, return ROK */
2147    if(ricSubscriptionInfo->numOfActions)
2148       return ROK;
2149
2150    return RFAILED;
2151 }
2152
2153 /******************************************************************
2154  *
2155  * @brief Processes RIC Subscription Req sent by RIC
2156  *
2157  * @details
2158  *
2159  *    Function : procRicSubsReq
2160  *
2161  *    Functionality: Processes E2 Setup Response sent by CU
2162  *
2163  * @params[in] E2AP_PDU_t ASN decoded E2AP message
2164  * @return ROK     - success
2165  *         RFAILED - failure
2166  *
2167  * ****************************************************************/
2168
2169 uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg)
2170 {
2171    uint8_t idx = 0; 
2172    uint8_t ret = ROK;
2173    uint16_t ranFuncId = 0;
2174    CmLList  *ricSubscriptionNode = NULLP;
2175    RanFunction *ranFuncDb = NULLP;
2176    RICsubscriptionRequest_t *ricSubsReq = NULLP;
2177    RICsubscriptionDetails_t *subsDetails = NULLP;
2178    RicSubscription *ricSubscriptionInfo = NULLP;
2179
2180    DU_LOG("\nINFO   -->  E2AP : RIC Subscription request received"); 
2181    ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
2182
2183    for(idx=0; idx<ricSubsReq->protocolIEs.list.count; idx++)
2184    {
2185       if(ricSubsReq->protocolIEs.list.array[idx])
2186       {
2187          switch(ricSubsReq->protocolIEs.list.array[idx]->id)
2188          {
2189             case ProtocolIE_IDE2_id_RICrequestID:
2190                {
2191                   DU_ALLOC(ricSubscriptionInfo, sizeof(RicSubscription));
2192                   if(!ricSubscriptionInfo)
2193                   {
2194                      DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for ricSubscriptionInfo");
2195                      ret = RFAILED;
2196                      break;
2197                   }
2198                   ricSubscriptionInfo->requestId.requestorId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID;
2199                   ricSubscriptionInfo->requestId.instanceId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID;
2200
2201                   break;
2202                }
2203
2204             case ProtocolIE_IDE2_id_RANfunctionID:
2205                {
2206                   ranFuncId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID; 
2207
2208                   /* Validating RAN Function id */
2209                   if(duCb.e2apDb.ranFunction[ranFuncId-1].id == ranFuncId)
2210                   {
2211                      ranFuncDb = &duCb.e2apDb.ranFunction[ranFuncId-1];
2212                   }
2213                   else
2214                   {
2215                      /* TODO : Send RAN Subcription Failure */
2216                      ret = RFAILED;
2217                   }
2218                   break;
2219                }
2220
2221             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
2222                {
2223                   subsDetails = &ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails;
2224
2225                   /* Decode, Validate and record Event Trigger Definition */
2226                   if(extractEventTriggerDef(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricEventTriggerDefinition) != ROK)
2227                   {
2228                      /* TODO : Send RAN Subcription Failure */
2229                      ret = RFAILED;
2230                      break;
2231                   }
2232
2233                   /* Decode, Validate and record RIC actions */
2234                   if(extractRicActionToBeSetup(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricAction_ToBeSetup_List) != ROK)
2235                   {
2236                      /* TODO : Send RAN Subcription Failure */
2237                      ret = RFAILED;
2238                      break;
2239                   }
2240                }
2241                break;
2242
2243             default:
2244                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RIC SubsReq:%ld",
2245                      ricSubsReq->protocolIEs.list.array[idx]->id);
2246                break;
2247          }
2248
2249          if(ret == RFAILED)
2250             break;
2251       }
2252    }
2253
2254    freeAperDecodingOfRicSubsReq(ricSubsReq);
2255
2256    if(ret == ROK)
2257    {
2258       /* Add RAN subcription detail to RAN function */
2259       DU_ALLOC(ricSubscriptionNode, sizeof(CmLList));
2260       if(ricSubscriptionNode)
2261       {
2262          ricSubscriptionNode->node = (PTR) ricSubscriptionInfo;
2263          cmLListAdd2Tail(&ranFuncDb->subscriptionList, ricSubscriptionNode);
2264       }
2265
2266 #ifdef KPI_CALCULATION
2267       /* Send statistics request to other DU entities */
2268       BuildAndSendStatsReq(ranFuncId, ricSubscriptionInfo);
2269 #endif      
2270
2271       /* TODO : Trigger RIC subscription response once statistics response is
2272        * received from MAC . 
2273        * TBD in next gerrit */
2274       ret = BuildAndSendRicSubscriptionRsp();
2275       {
2276          BuildAndSendRicIndication(ricSubscriptionInfo);
2277       }
2278    }
2279
2280    return ret;
2281 }
2282
2283 /*******************************************************************
2284  *
2285  * @brief Free the RicIndication Message
2286  *
2287  * @details
2288  *
2289  *    Function : FreeRicIndication
2290  *
2291  * Functionality: Free the RicIndication Message
2292  *
2293  * @return void
2294  *         
2295  *
2296  ******************************************************************/
2297 void FreeRicIndication(E2AP_PDU_t  *e2apMsg) 
2298 {
2299    uint8_t idx = 0;
2300    RICindication_t *ricIndicationMsg= NULLP;
2301
2302    if(e2apMsg != NULLP)
2303    {
2304       if(e2apMsg->choice.initiatingMessage != NULLP)
2305       {
2306          ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
2307          if(ricIndicationMsg!= NULLP)
2308          {
2309             if(ricIndicationMsg->protocolIEs.list.array != NULLP)
2310             {
2311                for(idx=0; idx<ricIndicationMsg->protocolIEs.list.count; idx++)
2312                {
2313                   if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP)
2314                   {
2315                      switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
2316                      {
2317                         case ProtocolIE_IDE2_id_RICrequestID:
2318                            break;
2319
2320                         case ProtocolIE_IDE2_id_RANfunctionID:
2321                            break;
2322
2323                         case ProtocolIE_IDE2_id_RICactionID:
2324                            break;
2325
2326                         case ProtocolIE_IDE2_id_RICindicationType:
2327                            break;
2328
2329                         case ProtocolIE_IDE2_id_RICindicationHeader:
2330                            {
2331                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\
2332                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
2333                               break;
2334                            }
2335                         case ProtocolIE_IDE2_id_RICindicationMessage:
2336                            {
2337                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\
2338                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
2339                               break;
2340                            }
2341                         default:
2342                            break;
2343                      }
2344                      DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t));
2345                   }
2346                }
2347                DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size);
2348             }
2349          }
2350          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2351       }
2352       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2353    }
2354 }
2355
2356 /*******************************************************************
2357  *
2358  * brief Fill the RicIndication Message
2359  *
2360  * @details
2361  *
2362  *    Function : FillRicIndication
2363  *
2364  * Functionality:Fills the RicIndication Message
2365  *
2366  * @return ROK     - success
2367  *         RFAILED - failure
2368  *
2369  ******************************************************************/
2370 uint8_t FillRicIndication(RICindication_t *ricIndicationMsg, RicSubscription *ricSubscriptionInfo)
2371 {
2372    uint8_t elementCnt=0;
2373    uint8_t idx=0;
2374    uint8_t ret = ROK;
2375    elementCnt = 6;
2376
2377    ricIndicationMsg->protocolIEs.list.count = elementCnt;
2378    ricIndicationMsg->protocolIEs.list.size  = elementCnt * sizeof(RICindication_t);
2379    /* Initialize the Ric Indication members */
2380    DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, \
2381          ricIndicationMsg->protocolIEs.list.size);
2382    if(ricIndicationMsg->protocolIEs.list.array == NULLP)
2383    {
2384       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
2385       ret = RFAILED;
2386    }
2387    else
2388    {
2389       for(idx=0; idx<elementCnt; idx++)
2390       {
2391          DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx],\
2392                sizeof(RICindication_IEs_t));
2393          if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
2394          {
2395             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
2396             ret = RFAILED;
2397          }
2398       }
2399       if(ret != RFAILED)
2400       {
2401          idx = 0;
2402
2403          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
2404          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2405          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
2406                                                                         RICindication_IEs__value_PR_RICrequestID;
2407          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID =ricSubscriptionInfo->requestId.requestorId;
2408          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID = ricSubscriptionInfo->requestId.instanceId;
2409
2410          idx++;
2411          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
2412          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2413          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
2414                                                                         RICindication_IEs__value_PR_RANfunctionID;
2415          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = duCb.e2apDb.ranFunction[0].id;
2416
2417          idx++;
2418          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
2419          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2420          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
2421                                                                         RICindication_IEs__value_PR_RICactionID;
2422          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = ricSubscriptionInfo->actionSequence[0].id;
2423
2424          idx++;
2425          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
2426          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2427          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
2428                                                                         RICindication_IEs__value_PR_RICindicationType;
2429          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = ricSubscriptionInfo->actionSequence[0].type;
2430
2431          idx++;
2432          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
2433          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2434          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
2435                                                                         RICindication_IEs__value_PR_RICindicationHeader;
2436          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size = 3 *
2437             sizeof(uint8_t);
2438          DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf ,\
2439                ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
2440          if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf == NULLP)
2441          {
2442             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
2443             ret = RFAILED;
2444          }
2445          else
2446          {
2447             buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
2448                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf);
2449             idx++;
2450             /* TO BE CHANGED: RIC INDICATION DATA */
2451             /* For now filling a dummy octect data, need to tested with PRBs*/
2452             ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
2453             ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2454             ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
2455                                                                            RICindication_IEs__value_PR_RICindicationMessage;
2456             ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size = 3 *
2457                sizeof(uint8_t);
2458             DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf ,\
2459                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
2460             if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf == NULLP)
2461             {
2462                DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
2463                ret = RFAILED;
2464             }
2465             else
2466             {
2467                buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
2468                      ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf);
2469             }
2470          }
2471       }
2472    }
2473    return ret;
2474 }
2475
2476 /*******************************************************************
2477  *
2478  * @brief Builds and Send the RicIndication Message
2479  *
2480  * @details
2481  *
2482  *    Function : BuildAndSendRicIndication
2483  *
2484  * Functionality:Fills the RicIndication Message
2485  *
2486  * @return ROK     - success
2487  *         RFAILED - failure
2488  *
2489  ******************************************************************/
2490
2491 uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo)
2492 {
2493    E2AP_PDU_t                 *e2apMsg = NULLP;
2494    RICindication_t            *ricIndicationMsg=NULLP;
2495    asn_enc_rval_t             encRetVal;        /* Encoder return value */
2496    uint8_t ret = RFAILED; 
2497    uint8_t FillRicIndicationret = ROK;
2498
2499    while(true)
2500    {
2501       DU_LOG("\nINFO   -->  E2AP : Building RIC Indication Message\n");
2502
2503       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2504       if(e2apMsg == NULLP)
2505       {
2506          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2507          break;
2508       }
2509
2510       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
2511       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2512       if(e2apMsg->choice.initiatingMessage == NULLP)
2513       {
2514          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2515          break;
2516       }
2517       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
2518       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2519       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication;
2520
2521       ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
2522
2523       FillRicIndicationret = FillRicIndication(ricIndicationMsg, ricSubscriptionInfo);
2524       if(FillRicIndicationret != ROK)
2525       {
2526          break;
2527       }
2528       /* Prints the Msg formed */
2529       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2530       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2531       encBufSize = 0;
2532       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
2533             encBuf);
2534       if(encRetVal.encoded == ENCODE_FAIL)
2535       {
2536          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Indication Message (at %s)\n",\
2537                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2538          break;
2539       }
2540       else
2541       {
2542          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Indication Message \n");
2543 #ifdef DEBUG_ASN_PRINT
2544          for(int i=0; i< encBufSize; i++)
2545          {
2546             printf("%x",encBuf[i]);
2547          } 
2548 #endif
2549       }
2550
2551       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
2552       {
2553          DU_LOG("\nINFO   -->  E2AP : Sending RIC Indication Message");      
2554
2555       }
2556       ret = ROK;
2557       break;
2558    }
2559    FreeRicIndication(e2apMsg);  
2560    return ret;
2561 }
2562
2563 /*******************************************************************
2564  *
2565  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
2566  *
2567  * @details
2568  *
2569  *    Function : FreeE2NodeConfigUpdate 
2570  *
2571  *    Functionality:
2572  *       - freeing the memory allocated for E2nodeConfigurationUpdate
2573  *
2574  * @params[in] E2AP_PDU_t *e2apMsg 
2575  * @return ROK     - success
2576  *         RFAILED - failure
2577  *
2578  * ****************************************************************/
2579 void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg)
2580 {
2581    uint8_t arrIdx =0;
2582    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate;
2583
2584    if(e2apMsg != NULLP)
2585    {
2586       if(e2apMsg->choice.initiatingMessage != NULLP)
2587       {
2588          e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
2589          if(e2NodeConfigUpdate->protocolIEs.list.array != NULLP)
2590          {
2591             for(arrIdx = 0; arrIdx < e2NodeConfigUpdate->protocolIEs.list.count; arrIdx++)
2592             {
2593                DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
2594             }
2595             DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
2596          }
2597          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2598       }
2599       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2600    }
2601 }
2602
2603 /*******************************************************************
2604  *
2605  * @brief Buld and send the E2 node config update msg 
2606  *
2607  * @details
2608  *
2609  *    Function : BuildAndSendE2NodeConfigUpdate
2610  *
2611  *    Functionality:
2612  *         - Buld and send the E2 node config update msg
2613  *
2614  * @params[in] 
2615  * @return ROK     - success
2616  *         RFAILED - failure
2617  *
2618  * ****************************************************************/
2619
2620 uint8_t BuildAndSendE2NodeConfigUpdate()
2621 {
2622    uint8_t arrIdx = 0,elementCnt = 1;
2623    uint8_t ret = ROK;
2624    E2AP_PDU_t        *e2apMsg = NULLP;
2625    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate = NULLP;
2626    asn_enc_rval_t     encRetVal;       /* Encoder return value */
2627
2628    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update\n");
2629    do
2630    {
2631       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2632       if(e2apMsg == NULLP)
2633       {
2634          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2635          break;
2636       }
2637       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
2638       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2639       if(e2apMsg->choice.initiatingMessage == NULLP)
2640       {
2641          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2642          DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2643          return RFAILED;
2644       }
2645       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2646       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
2647       e2apMsg->choice.initiatingMessage->value.present = \
2648       InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate;
2649       e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
2650
2651       e2NodeConfigUpdate->protocolIEs.list.count = elementCnt;
2652       e2NodeConfigUpdate->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdate_IEs_t*);
2653       /* Initialize the Ric Indication members */
2654       DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array, \
2655             e2NodeConfigUpdate->protocolIEs.list.size);
2656       if(e2NodeConfigUpdate->protocolIEs.list.array == NULLP)
2657       {
2658          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
2659          break;
2660       }
2661       
2662       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
2663       {
2664          DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
2665          if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx] == NULLP)
2666          {
2667             
2668             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
2669             break;
2670          }
2671       }
2672
2673       arrIdx = 0;
2674       /* TransactionID */
2675       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2676       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2677       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_TransactionID;
2678       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = TRANS_ID;
2679
2680
2681       /* Prints the Msg formed */
2682       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2683
2684       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2685       encBufSize = 0;
2686       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
2687             encBuf);
2688       if(encRetVal.encoded == ENCODE_FAIL)
2689       {
2690          DU_LOG("\nERROR  -->  E2AP : Could not encode E2nodeConfigurationUpdate structure (at %s)\n",\
2691                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2692          break;
2693       }
2694       else
2695       {
2696          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2nodeConfigurationUpdate\n");
2697 #ifdef DEBUG_ASN_PRINT
2698          for(int i=0; i< encBufSize; i++)
2699          {
2700             printf("%x",encBuf[i]);
2701          }
2702 #endif
2703       }
2704       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize))
2705       {
2706          DU_LOG("\nERROR  -->  E2AP : Sending E2 node config update failed");
2707          return RFAILED;
2708       }
2709
2710       break;
2711    }while(true);
2712    
2713    FreeE2NodeConfigUpdate(e2apMsg);
2714    return ret;
2715 }
2716
2717 /*******************************************************************
2718  *
2719  * @brief Deallocate the memory allocated for E2ResetRequest msg
2720  *
2721  * @details
2722  *
2723  *    Function : FreeE2ResetRequest
2724  *
2725  *    Functionality:
2726  *       - freeing the memory allocated for E2ResetRequest
2727  *
2728  * @params[in] E2AP_PDU_t *e2apMsg
2729  * @return ROK     - success
2730  *         RFAILED - failure
2731  *
2732  * ****************************************************************/
2733 void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg)
2734 {
2735    uint8_t ieIdx =0;
2736    ResetRequestE2_t  *resetReq = NULLP;
2737
2738    if(e2apMsg != NULLP)
2739    {
2740       if(e2apMsg->choice.initiatingMessage != NULLP)
2741       {
2742          resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
2743          if(resetReq->protocolIEs.list.array)
2744          {
2745             for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
2746             {
2747                DU_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
2748             }
2749             DU_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
2750          }
2751          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2752       }
2753       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2754    }
2755 }
2756
2757 /*******************************************************************
2758  *
2759  * @brief Build and send the E2 reset request msg
2760  *
2761  * @details
2762  *
2763  *    Function : BuildAndSendE2ResetRequest
2764  *
2765  *    Functionality:
2766  *         - Buld and send the E2 reset request msg to RIC
2767  *
2768  * @params[in]
2769  * @return ROK     - success
2770  *         RFAILED - failure
2771  *
2772  * ****************************************************************/
2773 uint8_t BuildAndSendE2ResetRequest(E2CauseType failureType, E2Cause failureCause)
2774 {
2775    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
2776    uint8_t ret = RFAILED;
2777    E2AP_PDU_t        *e2apMsg = NULLP;
2778    ResetRequestE2_t  *resetReq = NULLP;
2779    asn_enc_rval_t     encRetVal;       /* Encoder return value */
2780
2781    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Request\n");
2782
2783    do
2784    {
2785       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2786       if(e2apMsg == NULLP)
2787       {
2788          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for E2AP-PDU failed");
2789          break;
2790       }
2791
2792       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
2793       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2794       if(e2apMsg->choice.initiatingMessage == NULLP)
2795       {
2796          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for initiatingMessage");
2797          break;
2798       }
2799
2800       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
2801       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2802       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
2803       resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
2804
2805       elementCnt = 2;
2806       resetReq->protocolIEs.list.count = elementCnt;
2807       resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
2808
2809       DU_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
2810       if(!resetReq->protocolIEs.list.array)
2811       {
2812          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
2813             Reset Request IE array");
2814          break;
2815       }
2816
2817       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
2818       {
2819          DU_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
2820          if(!resetReq->protocolIEs.list.array[ieIdx])
2821          {
2822             DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
2823             Reset Request IE array element");
2824             break;
2825          }
2826       }
2827
2828       /* In case of failure */
2829       if(ieIdx < elementCnt)
2830          break;
2831
2832       ieIdx = 0;
2833       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2834       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
2835       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
2836       transId = assignTransactionId();
2837       resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
2838
2839       ieIdx++;
2840       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
2841       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
2842       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
2843       resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present = failureType;
2844       switch(resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present)
2845       {
2846          case CauseE2_PR_NOTHING:
2847             break;
2848          case CauseE2_PR_ricRequest:
2849             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricRequest = failureCause;
2850             break;
2851          case CauseE2_PR_ricService:
2852             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricService = failureCause;
2853             break;
2854          case CauseE2_PR_e2Node:
2855             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.e2Node = failureCause;
2856             break;
2857          case CauseE2_PR_transport:
2858             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.transport = failureCause;
2859             break;
2860          case CauseE2_PR_protocol:
2861             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.protocol = failureCause;
2862             break;
2863          case CauseE2_PR_misc:
2864             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.misc = failureCause;
2865             break;
2866       }
2867
2868       /* Prints the Msg formed */
2869       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2870
2871       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2872       encBufSize = 0;
2873       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
2874             encBuf);
2875       if(encRetVal.encoded == ENCODE_FAIL)
2876       {
2877          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupRequest structure (at %s)\n",\
2878                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2879          break;
2880       }
2881       else
2882       {
2883          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2SetupRequest\n");
2884 #ifdef DEBUG_ASN_PRINT
2885          for(int i=0; i< encBufSize; i++)
2886          {
2887             printf("%x",encBuf[i]);
2888          }
2889 #endif
2890       }
2891       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
2892       {
2893          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
2894          break;
2895       }
2896
2897       /* In case the message is sent successfully, store the transaction info to
2898        * be used when response is received */
2899       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
2900       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
2901
2902       ret = ROK;
2903       break;
2904    }while(true);
2905
2906    /* Free all memory */
2907    FreeE2ResetRequest(e2apMsg);
2908    return ret;
2909 }
2910
2911 /*******************************************************************
2912  *
2913  * @brief Deallocate the memory allocated for Reset Response msg
2914  *
2915  * @details
2916  *
2917  *    Function : freeAperDecodingOfE2ResetRsp
2918  *
2919  *    Functionality:
2920  *       - freeing the memory allocated for Reset response
2921  *
2922  * @params[in] ResetResponseE2_t *resetResponse
2923  * @return void
2924  *
2925  * ****************************************************************/
2926 void freeAperDecodingOfE2ResetRsp(ResetResponseE2_t *resetResponse)
2927 {
2928    uint8_t ieIdx;
2929
2930    if(resetResponse)
2931    {
2932       if(resetResponse->protocolIEs.list.array)
2933       {
2934          for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
2935          {
2936             if(resetResponse->protocolIEs.list.array[ieIdx])
2937             {
2938                switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
2939                {
2940                   case ProtocolIE_IDE2_id_TransactionID:
2941                      break;
2942
2943                   case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
2944                      break;
2945                }
2946                free(resetResponse->protocolIEs.list.array[ieIdx]);
2947             }
2948          }
2949          free(resetResponse->protocolIEs.list.array);
2950       }
2951    }
2952 }
2953
2954 /******************************************************************
2955  *
2956  * @brief Processes E2 Reset Response sent by RIC
2957  *
2958  * @details
2959  *
2960  *    Function : procResetResponse
2961  *
2962  *    Functionality: Processes E2 Reset Response sent by RIC
2963  *
2964  * @params[in] E2AP_PDU_t ASN decoded E2AP message
2965  * @return ROK     - success
2966  *         RFAILED - failure
2967  *
2968  * ****************************************************************/
2969 uint8_t procResetResponse(E2AP_PDU_t *e2apMsg)
2970 {
2971    uint8_t ieIdx =0, transId;
2972    ResetResponseE2_t *resetResponse;
2973
2974    DU_LOG("\nINFO   -->  E2AP : E2 Reset Response received");
2975    resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;;
2976
2977    for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
2978    {
2979       switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
2980       {
2981          case ProtocolIE_IDE2_id_TransactionID:
2982             transId = resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
2983             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) && \
2984                   (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
2985             {
2986                memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
2987             }
2988             else
2989             {
2990                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
2991                return RFAILED;
2992             }
2993             break;
2994          case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
2995             /* As per ORAN WG3 E2AP spec v3.0, section 9.2.2
2996                Criticality Diagnostics IE is sent by Near-RT RIC when parts of a received message i.e. 
2997                Reset Request in this case, have not been comprehended or were missing, or if the message 
2998                contained logical errors.
2999
3000                Processing of this ID should be implemented when negative call flows are to be supported.
3001              */
3002             break;
3003          default:
3004             DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2 Reset Response : %ld",
3005                   resetResponse->protocolIEs.list.array[ieIdx]->id);
3006             break;
3007       }
3008    }
3009
3010    freeAperDecodingOfE2ResetRsp(resetResponse);
3011    return ROK;
3012 }
3013
3014 /******************************************************************
3015  *
3016  * @brief Deallocation of memory allocated bu aper decoder for e2 setup Failure
3017  *
3018  * @details
3019  *
3020  *    Function : freeAperDecodingOfE2SetupFailure
3021  *
3022  *    Functionality: Deallocation of memory allocated bu aper decoder for e2
3023  *    setup Failure
3024  *
3025  * @params[in] E2setupFailure_t *e2SetupFailure;
3026  * @return void
3027  *
3028  * ****************************************************************/
3029 void freeAperDecodingOfE2SetupFailure(E2setupFailure_t *e2SetupFailure)
3030 {
3031    uint8_t arrIdx;
3032
3033    if(e2SetupFailure)
3034    {
3035       if(e2SetupFailure->protocolIEs.list.array)
3036       {
3037          for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
3038          {
3039             if(e2SetupFailure->protocolIEs.list.array[arrIdx])
3040             {
3041                free(e2SetupFailure->protocolIEs.list.array[arrIdx]);  
3042             }
3043          }
3044          free(e2SetupFailure->protocolIEs.list.array);
3045       }
3046    }
3047 }
3048 /******************************************************************
3049  *
3050  * @brief Processes E2 Setup Failure sent by RIC
3051  *
3052  * @details
3053  *
3054  *    Function : procE2SetupFailure
3055  *
3056  *    Functionality: Processes E2 Setup failure sent by RIC
3057  *
3058  * @params[in] E2AP_PDU_t ASN decoded E2AP message
3059  * @return ROK     - success
3060  *         RFAILED - failure
3061  *
3062  * ****************************************************************/
3063 void procE2SetupFailure(E2AP_PDU_t *e2apMsg)
3064 {
3065    uint8_t arrIdx =0, transId =0, timerValue=0; 
3066    E2setupFailure_t *e2SetupFailure;
3067
3068    DU_LOG("\nINFO   -->  E2AP : E2 Setup failure received"); 
3069    e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
3070
3071    for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
3072    {
3073       switch(e2SetupFailure->protocolIEs.list.array[arrIdx]->id)
3074       {
3075          case ProtocolIE_IDE2_id_TransactionID:
3076          {
3077             transId = e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
3078             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
3079                   (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
3080             {
3081                memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
3082             }
3083             else
3084             {
3085                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
3086                return ;
3087             }
3088             break;
3089          }
3090          case ProtocolIE_IDE2_id_TimeToWaitE2:
3091             {
3092                timerValue = covertE2WaitTimerEnumToValue(e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
3093                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR)) == FALSE)
3094                {
3095                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR, timerValue);
3096                }
3097                else
3098                {
3099                   DU_LOG("\nERROR   -->  E2AP : EVENT_E2_SETUP_TMR timer is already running");
3100                   return;
3101                }
3102                break; 
3103             }
3104       }
3105    }
3106
3107    freeAperDecodingOfE2SetupFailure(e2SetupFailure);
3108 }
3109 /******************************************************************
3110  *
3111  * @brief Deallocation of memory allocated bu aper decoder for RIC service Query
3112  *
3113  * @details
3114  *
3115  *    Function : freeAperDecodingOfRicServiceQuery
3116  *
3117  *    Functionality: Deallocation of memory allocated bu aper decoder for RIC
3118  *    service Query
3119  *
3120  * @params[in] RICserviceQuery_t *ricServiceQuery;
3121  * @return void
3122  *
3123  * ****************************************************************/
3124
3125 void freeAperDecodingOfRicServiceQuery(RICserviceQuery_t *ricServiceQuery)
3126 {
3127    uint8_t arrIdx,ranFuncIdx;
3128     RANfunctionsID_List_t *ranFuncAddedList;
3129
3130    if(ricServiceQuery)
3131    {
3132       if(ricServiceQuery->protocolIEs.list.array)
3133       {
3134          for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
3135          {
3136             if(ricServiceQuery->protocolIEs.list.array[arrIdx])
3137             {
3138                switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
3139                {
3140                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
3141                   {
3142                      ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
3143                      if(ranFuncAddedList->list.array)
3144                      {
3145                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
3146                         {
3147                            free(ranFuncAddedList->list.array[ranFuncIdx]);
3148                         }
3149                         free(ranFuncAddedList->list.array);;
3150                      }
3151                      break;
3152                   }
3153                   default:
3154                      break;
3155                }
3156                free(ricServiceQuery->protocolIEs.list.array[arrIdx]);
3157             }
3158          }
3159          free(ricServiceQuery->protocolIEs.list.array);
3160       }
3161    }
3162 }
3163 /*******************************************************************
3164  *
3165  * @brief Build RanFunction Delete List
3166  *
3167  * @details
3168  *
3169  *    Function : BuildRanFunctionDeleteList
3170  *
3171  * Functionality:  Build RanFunction Delete List
3172  *
3173  * @params[in]
3174  *    RANfunctionsID List
3175  *    Count of the RAN function
3176  *    Received RAN function list
3177  *
3178  * @return ROK     - success
3179  *         RFAILED - failure
3180  *
3181  ******************************************************************/
3182
3183 uint8_t BuildRanFunctionDeleteList(RANfunctionsID_List_t *deleteList, uint8_t count, RanFuncInfo *recvdRanFunc)
3184 {
3185    uint8_t ranFuncIdx=0;
3186    RANfunctionID_ItemIEs_t *delRanFuncItem;
3187
3188    if(count)
3189    {
3190       deleteList->list.count = count;
3191       deleteList->list.size = deleteList->list.count * sizeof(RANfunctionID_ItemIEs_t*);
3192       DU_ALLOC(deleteList->list.array, deleteList->list.size);
3193       if(deleteList->list.array == NULLP)
3194       {
3195          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
3196          return RFAILED;
3197       }
3198       for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
3199       {
3200          DU_ALLOC(deleteList->list.array[ranFuncIdx], sizeof(RANfunctionID_ItemIEs_t));
3201          if(deleteList->list.array[ranFuncIdx] == NULLP)
3202          {
3203             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
3204             return RFAILED;
3205          }
3206          delRanFuncItem= (RANfunctionID_ItemIEs_t *) deleteList->list.array[ranFuncIdx];
3207          delRanFuncItem->id = ProtocolIE_IDE2_id_RANfunctionID_Item;
3208          delRanFuncItem->criticality = CriticalityE2_ignore;
3209          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionID = recvdRanFunc[ranFuncIdx].id;
3210          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionRevision = recvdRanFunc[ranFuncIdx].revisionCounter;
3211
3212       }
3213    }
3214    return ROK;
3215 }
3216 /*******************************************************************
3217  *
3218  * @brief De Allocate  Ric Service Update message
3219  *
3220  * @details
3221  *
3222  *    Function : FreeRicServiceUpdate
3223  *
3224  *    Functionality: De-Allocating Ric Service Update message
3225  *
3226  * @params[in] E2AP_PDU_t *e2apMsg
3227
3228  * @return void
3229  *
3230  * ****************************************************************/
3231
3232 void FreeRicServiceUpdate(E2AP_PDU_t *e2apMsg)
3233 {
3234    uint8_t arrIdx = 0;
3235    uint8_t ranFuncAddListIdx=0, ranFuncDelIdx=0;
3236    RICserviceUpdate_t *ricServiceUpdate;
3237    RANfunctions_List_t *ranFunctionsList;
3238    RANfunction_ItemIEs_t *ranFuncItemIe;
3239    RANfunction_Item_t  *ranFunItem;
3240    RANfunctionsID_List_t *deleteList;
3241
3242    /* De-allocating Memory */
3243    if(e2apMsg != NULLP)
3244    {
3245       if(e2apMsg->choice.initiatingMessage != NULLP)
3246       {
3247          ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
3248          if(ricServiceUpdate->protocolIEs.list.array != NULLP)
3249          {
3250             for(arrIdx = 0; arrIdx < ricServiceUpdate->protocolIEs.list.count; arrIdx++)
3251             {
3252                if(ricServiceUpdate->protocolIEs.list.array[arrIdx] != NULLP)
3253                {
3254                   switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
3255                   {
3256                      case ProtocolIE_IDE2_id_TransactionID:
3257                         break;
3258
3259                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
3260                      case ProtocolIE_IDE2_id_RANfunctionsModified:
3261                         {
3262                            ranFunctionsList = &(ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List);
3263                            if(ranFunctionsList->list.array)
3264                            {
3265                               for(ranFuncAddListIdx= 0; ranFuncAddListIdx< ranFunctionsList->list.count; ranFuncAddListIdx++)
3266                               {
3267                                  if(ranFunctionsList->list.array[ranFuncAddListIdx])
3268                                  {
3269                                     ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncAddListIdx];
3270                                     ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
3271                                     DU_FREE(ranFunItem->ranFunctionOID.buf, ranFunItem->ranFunctionOID.size);
3272                                     DU_FREE(ranFunItem->ranFunctionDefinition.buf, ranFunItem->ranFunctionDefinition.size);
3273                                     DU_FREE(ranFunctionsList->list.array[ranFuncAddListIdx], sizeof(RANfunction_ItemIEs_t));
3274                                  }
3275                               }
3276                               DU_FREE(ranFunctionsList->list.array, ranFunctionsList->list.size);
3277                            }
3278                            break;
3279                         }
3280                      case ProtocolIE_IDE2_id_RANfunctionsDeleted:
3281                         {
3282                            deleteList= &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
3283                            if(deleteList->list.array)
3284                            {
3285                               for(ranFuncDelIdx = 0; ranFuncDelIdx< deleteList->list.count; ranFuncDelIdx++)
3286                               {
3287                                  DU_FREE(deleteList->list.array[ranFuncDelIdx], sizeof(RANfunctionID_ItemIEs_t));
3288                               }
3289                               DU_FREE(deleteList->list.array, deleteList->list.size);
3290   
3291                            }
3292                            break;
3293                         }
3294                      default:
3295                         DU_LOG("\nERROR  --> E2AP: Invalid event at ricServiceUpdate %ld ",\
3296                               (ricServiceUpdate->protocolIEs.list.array[arrIdx]->id));
3297                         break;
3298                   }
3299                   DU_FREE(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
3300                }
3301             }
3302             DU_FREE(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
3303          }
3304          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3305       }
3306       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3307    }
3308 }
3309
3310 /*******************************************************************
3311  *
3312  * @brief Builds and Send the RicServiceUpdateuest
3313  *
3314  * @details
3315  *
3316  *    Function : BuildAndSendRicServiceUpdate
3317  *
3318  * Functionality:Fills the RicServiceUpdateuest
3319  *
3320  * @return ROK     - success
3321  *         RFAILED - failure
3322  *
3323  ******************************************************************/
3324
3325 uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate)
3326 {
3327    uint8_t arrIdx = 0, elementCnt=0;
3328    uint8_t transId = 0, ret = RFAILED;
3329    bool memAllocFailed =false;
3330    E2AP_PDU_t        *e2apMsg = NULLP;
3331    RICserviceUpdate_t  *ricServiceUpdate = NULLP;
3332    asn_enc_rval_t     encRetVal;       /* Encoder return value */
3333
3334    DU_LOG("\nINFO   -->  E2AP : Building Ric Service Update\n");
3335    do
3336    {
3337       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3338       if(e2apMsg == NULLP)
3339       {
3340          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
3341          break;
3342       }
3343       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
3344       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3345       if(e2apMsg->choice.initiatingMessage == NULLP)
3346       {
3347          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
3348          break;
3349       }
3350       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
3351       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
3352       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceUpdate;
3353       ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
3354       
3355       /* For TransId IE, set elementCnt to 1.
3356       If there is any item in the RAN function add list, RAN function modification list, or RAN function delete list, increment the elementCnt.*/
3357
3358       elementCnt =1;
3359       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
3360         elementCnt++;
3361       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
3362          elementCnt++;
3363       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
3364          elementCnt++;
3365        
3366       ricServiceUpdate->protocolIEs.list.count = elementCnt;
3367       ricServiceUpdate->protocolIEs.list.size = elementCnt * sizeof(RICserviceUpdate_IEs_t*);
3368
3369       /* Initialize the E2Setup members */
3370       DU_ALLOC(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
3371       if(ricServiceUpdate->protocolIEs.list.array == NULLP)
3372       {
3373          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
3374          break;
3375       }
3376       
3377       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
3378       {
3379          DU_ALLOC(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
3380          if(ricServiceUpdate->protocolIEs.list.array[arrIdx] == NULLP)
3381          {
3382             memAllocFailed = true;
3383             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayIdx [%d]", arrIdx);
3384             break;
3385          }
3386       }
3387       if(memAllocFailed == true)
3388          break;
3389
3390       arrIdx = 0;
3391
3392       /* TransactionID */
3393       ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
3394       ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3395       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
3396       if(serviceUpdate.dir == E2_NODE_INITIATED)
3397          transId = assignTransactionId();
3398       else
3399         transId = serviceUpdate.transId;
3400       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
3401
3402       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
3403       {
3404          arrIdx++;
3405          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAdded;
3406          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3407          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
3408          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,\
3409          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded, serviceUpdate.recvRanFuncList.ranFunToBeAdded) !=ROK)
3410          {
3411             break;
3412          }
3413       }
3414
3415       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
3416       {
3417          arrIdx++;
3418          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsModified;
3419          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3420          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
3421          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,
3422          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeModified, serviceUpdate.recvRanFuncList.ranFunToBeModified) !=ROK)
3423          {
3424             break;
3425          }
3426       }
3427
3428       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
3429       {
3430          arrIdx++;
3431          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsDeleted;
3432          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3433          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctionsID_List;
3434          if(BuildRanFunctionDeleteList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List,\
3435          serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted, serviceUpdate.recvRanFuncList.ranFunToBeDeleted) != ROK)
3436          {
3437             break;
3438          }
3439       }
3440       /* Prints the Msg formed */
3441       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3442
3443       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3444       encBufSize = 0;
3445       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3446       if(encRetVal.encoded == ENCODE_FAIL)
3447       {
3448          DU_LOG("\nERROR  -->  E2AP : Could not encode RicServiceUpdateuest structure (at %s)\n",\
3449                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3450          break;
3451       }
3452       else
3453       {
3454          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RicServiceUpdateuest\n");
3455 #ifdef DEBUG_ASN_PRINT
3456          for(int i=0; i< encBufSize; i++)
3457          {
3458             printf("%x",encBuf[i]);
3459          }
3460 #endif
3461       }
3462       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
3463       {
3464          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
3465          break;
3466       }
3467       ret = ROK;
3468       break;
3469    }while(true);
3470    
3471    if(ret == ROK)
3472    {
3473       if(serviceUpdate.dir == E2_NODE_INITIATED)
3474       {
3475          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
3476          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
3477       }
3478       else
3479       {
3480          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId = transId;
3481          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
3482       }
3483       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.dir = serviceUpdate.dir;
3484       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.transId =transId;
3485    }
3486    FreeRicServiceUpdate(e2apMsg);
3487    return ret;
3488 }
3489 /******************************************************************
3490  *
3491  * @brief Processes RIC service Query sent by RIC
3492  *
3493  * @details
3494  *
3495  *    Function : procRicServiceQuery
3496  *
3497  *    Functionality: Processes RIC service Query sent by RIC
3498  *
3499  * @params[in] E2AP_PDU_t ASN decoded E2AP message
3500  * @return ROK     - success
3501  *         RFAILED - failure
3502  *
3503  * ****************************************************************/
3504
3505 void procRicServiceQuery(E2AP_PDU_t *e2apMsg)
3506 {
3507    ConfigType action;
3508    uint16_t arrIdx =0, ranFuncIdx=0,tmpIdx=0;
3509    uint16_t id,revisionCcounter;
3510    bool tmpArray[MAX_RAN_FUNCTION] = {false};
3511    RICserviceQuery_t *ricServiceQuery=NULL;
3512    RicServiceUpdate ricUpdate;
3513    RANfunctionID_ItemIEs_t *ranFuncAddedItemIe;
3514    RANfunctionsID_List_t *ranFuncAddedList;
3515
3516    DU_LOG("\nINFO   -->  E2AP : RIC Service Query received");
3517    memset(&ricUpdate, 0, sizeof(RicServiceUpdate));
3518    ricUpdate.dir = RIC_INITIATED;
3519    ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
3520
3521    for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
3522    {
3523       switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
3524       {
3525          /* TODO completing in next patch/gerrit */
3526          case ProtocolIE_IDE2_id_TransactionID:
3527          {
3528             ricUpdate.transId = ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
3529             break;
3530          }
3531
3532          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
3533          {
3534             ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
3535             if(ranFuncAddedList->list.array)
3536             {
3537                for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
3538                {
3539                   if(ranFuncAddedList->list.array[ranFuncIdx])
3540                   {
3541                      /* Using the RAN function Id, identify the RAN function to be modified or deleted.  */
3542                      
3543                      ranFuncAddedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAddedList->list.array[ranFuncIdx];
3544                      id = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionID;
3545                      revisionCcounter = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision;
3546                      
3547                      if((id != duCb.e2apDb.ranFunction[id-1].id))
3548                      {
3549                         action = CONFIG_DEL;
3550                      }
3551                      else if((id == duCb.e2apDb.ranFunction[id-1].id)&&(revisionCcounter!=duCb.e2apDb.ranFunction[id-1].revisionCounter))
3552                      {
3553                         action = CONFIG_MOD;
3554                      }
3555
3556                      if(action == CONFIG_DEL)
3557                      {
3558                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].id = id;
3559                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].revisionCounter = revisionCcounter;
3560                         ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted++;
3561                      }
3562                      else if(action == CONFIG_MOD)
3563                      {
3564                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].id = id;
3565                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].revisionCounter = revisionCcounter;
3566                         ricUpdate.recvRanFuncList.numOfRanFunToBeModified++;
3567                      }
3568
3569                      /* If any ID is set to true, it means that the ID has been used in either modification or deletion list. 
3570                       * Else we will add the IDs into the added list */
3571                      tmpArray[id-1] = true;
3572                   }
3573                }
3574             }
3575             break;
3576          }
3577       }
3578    }
3579
3580    /*  Traversing the whole RAN function list in ducb to check if any new Ran function ids have been added. */
3581    for(arrIdx =0; arrIdx<MAX_RAN_FUNCTION; arrIdx++)
3582    {
3583       tmpIdx= ricUpdate.recvRanFuncList.numOfRanFunToBeAdded;
3584       if((duCb.e2apDb.ranFunction[arrIdx].id >0)&&(!tmpArray[arrIdx]))
3585       {
3586          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[arrIdx].id;
3587          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[arrIdx].revisionCounter;
3588          ricUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
3589       }
3590    }
3591
3592    if(BuildAndSendRicServiceUpdate(ricUpdate)!= ROK)
3593    {
3594       DU_LOG("\nERROR  -->  E2AP : Failed to build and send ric service update message");
3595    }
3596
3597    freeAperDecodingOfRicServiceQuery(ricServiceQuery);
3598 }
3599
3600
3601 /*******************************************************************
3602  *
3603  * @brief Handles received E2AP message and sends back response  
3604  *
3605  * @details
3606  *
3607  *    Function : E2APMsgHdlr
3608  *
3609  *    Functionality:
3610  *         - Decodes received E2AP control message
3611  *         - Prepares response message, encodes and sends to SCTP
3612  *
3613  * @params[in] 
3614  * @return ROK     - success
3615  *         RFAILED - failure
3616  *
3617  * ****************************************************************/
3618 void E2APMsgHdlr(Buffer *mBuf)
3619 {
3620    int i =0;
3621    char *recvBuf = NULLP;
3622    MsgLen copyCnt =0;
3623    MsgLen recvBufLen =0;
3624    E2AP_PDU_t *e2apMsg = NULLP;
3625    asn_dec_rval_t rval ={0}; /* Decoder return value */
3626    E2AP_PDU_t e2apasnmsg={0} ;
3627
3628    DU_LOG("\nDEBUG   -->  E2AP : Received E2AP message buffer");
3629    ODU_PRINT_MSG(mBuf, 0,0);
3630
3631    /* Copy mBuf into char array to decode it */
3632    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
3633    DU_ALLOC(recvBuf, (Size)recvBufLen);
3634
3635    if(recvBuf == NULLP)
3636    {
3637       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
3638       return;
3639    }
3640    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
3641    {
3642       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
3643       return;
3644    }
3645
3646 #ifdef DEBUG_ASN_PRINT
3647    printf("\nDEBUG   -->  E2AP : Received flat buffer to be decoded : ");
3648    for(i=0; i< recvBufLen; i++)
3649    {
3650       printf("%x",recvBuf[i]);
3651    }
3652 #endif
3653
3654    /* Decoding flat buffer into E2AP messsage */
3655    e2apMsg = &e2apasnmsg;
3656    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
3657
3658    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
3659    DU_FREE(recvBuf, (Size)recvBufLen);
3660
3661    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
3662    {
3663       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
3664       return;
3665    }
3666    printf("\n");
3667    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3668
3669    switch(e2apMsg->present)
3670    {
3671       case E2AP_PDU_PR_unsuccessfulOutcome:
3672          {
3673             switch(e2apMsg->choice.unsuccessfulOutcome->value.present)
3674             {
3675                case UnsuccessfulOutcomeE2__value_PR_E2setupFailure:
3676                   {
3677                      procE2SetupFailure(e2apMsg);
3678                      break;
3679                   }
3680                default:
3681                   {
3682                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome  [%d]",\
3683                            e2apMsg->choice.unsuccessfulOutcome->value.present);
3684                      return;
3685                   }
3686             }
3687             break;
3688          }
3689       case E2AP_PDU_PR_successfulOutcome:
3690          {
3691             switch(e2apMsg->choice.successfulOutcome->value.present)
3692             {
3693                case SuccessfulOutcomeE2__value_PR_E2setupResponse:
3694                   {
3695                      if(!duCb.e2Status)
3696                      {
3697                         procE2SetupRsp(e2apMsg);
3698                      }
3699                      break;
3700                   }
3701                case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge:
3702                   {
3703                      DU_LOG("\nDEBUG   -->  E2AP : E2 node Config update ack message recevied");
3704                      break;
3705                   }
3706                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
3707                   {
3708                      procResetResponse(e2apMsg);
3709                      break;
3710                   }
3711                default:
3712                   {
3713                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome  [%d]",\
3714                            e2apMsg->choice.successfulOutcome->value.present);
3715                      return;
3716                   }
3717             }/* End of switch(successfulOutcome) */
3718             free(e2apMsg->choice.successfulOutcome);
3719             break;
3720          }
3721
3722       case E2AP_PDU_PR_initiatingMessage:
3723          {
3724             switch(e2apMsg->choice.initiatingMessage->value.present)
3725             {
3726                case InitiatingMessageE2__value_PR_RICsubscriptionRequest: 
3727                   {
3728                      procRicSubsReq(e2apMsg);
3729                      break;
3730                   }
3731                case InitiatingMessageE2__value_PR_RICserviceQuery:
3732                   {
3733                      procRicServiceQuery(e2apMsg);
3734                      break;
3735                   }
3736                default:
3737                   {
3738                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\
3739                            e2apMsg->choice.initiatingMessage->value.present);
3740                      return;
3741                   }
3742             }/* End of switch(initiatingMessage) */
3743             free(e2apMsg->choice.initiatingMessage);
3744             break;
3745          }
3746       default:
3747          {
3748             DU_LOG("\nERROR  -->  E2AP : Invalid type of e2apMsg->present [%d]",e2apMsg->present);
3749             return;
3750          }
3751          free(e2apMsg);
3752
3753    }/* End of switch(e2apMsg->present) */
3754
3755 } /* End of E2APMsgHdlr */
3756
3757 /**********************************************************************
3758   End of file
3759  **********************************************************************/