eb726346954a1a2cdd270dbaee4784af098d8afd
[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
49 /*******************************************************************
50  *
51  * @brief Builds Global gNodeB Params
52  *
53  * @details
54  *
55  *    Function : BuildGlobalgNBId
56  *
57  *    Functionality: Building the Plmn and gNB id
58  *
59  * @params[in] GlobalE2node_gNB_ID_t *gNbId
60  * @return ROK     - success
61  *         RFAILED - failure
62  *
63  ******************************************************************/
64
65 uint8_t BuildGlobalgNBId(GlobalE2node_gNB_ID_t *gNbId)
66 {
67    uint8_t unused = 0;
68    uint8_t byteSize = 4;
69    uint8_t gnbId = duCb.gnbId;
70    uint8_t ret = ROK;
71
72    /* fill Global gNB ID Id */
73    gNbId->global_gNB_ID.plmn_id.size = 3 * sizeof(uint8_t);
74    gNbId->global_gNB_ID.plmn_id.buf = NULLP;
75    DU_ALLOC(gNbId->global_gNB_ID.plmn_id.buf , gNbId->global_gNB_ID.plmn_id.size);
76    if(gNbId->global_gNB_ID.plmn_id.buf == NULLP)
77    {
78       DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for Plmn buffer");
79       ret = RFAILED;
80    }
81    else
82    {
83       buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
84             gNbId->global_gNB_ID.plmn_id.buf);
85       gNbId->global_gNB_ID.gnb_id.present = GNB_ID_Choice_PR_gnb_ID;
86       /* Allocate Buffer size */
87       gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size = byteSize * sizeof(uint8_t);
88       gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf = NULLP;
89       DU_ALLOC(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf, \
90             gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size);
91       if(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf == NULLP)
92       {
93          DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for gnb buffer");
94          ret = RFAILED;
95       }
96       else
97       {
98          fillBitString(&gNbId->global_gNB_ID.gnb_id.choice.gnb_ID, unused, byteSize, gnbId);
99       }
100    }
101
102    /* fill gNB-DU ID */ 
103    DU_ALLOC( gNbId->gNB_DU_ID, sizeof(GNB_DU_ID_t));
104    if(gNbId->gNB_DU_ID == NULLP)
105    {
106       DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for gNB_DU_ID ");
107       ret = RFAILED;
108    }
109    else
110    {
111       gNbId->gNB_DU_ID->size = sizeof(uint8_t);
112       DU_ALLOC( gNbId->gNB_DU_ID->buf, sizeof(uint8_t));
113       if(gNbId->gNB_DU_ID->buf)
114       {
115          gNbId->gNB_DU_ID->buf[0] =duCb.e2apDb.e2NodeId;
116       }
117       else
118       {
119          DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for gNB_DU_ID buffer");
120          ret = RFAILED;
121       }
122    }
123
124    return ret;
125 }
126
127 /******************************************************************
128  *
129  * @brief Search E2 node component with the help of action type
130  *
131  * @details
132  *
133  *    Function : searchE2NodeComponentInfo 
134  *
135  *    Functionality: Search E2 node component with the help of action type 
136  *
137  * @params[in] uint8_t componentActionType
138  * @return CmLList
139  *
140  * ****************************************************************/
141
142 CmLList *searchE2NodeComponentInfo(InterfaceType interfaceType, uint8_t componentActionType)
143 {
144    E2NodeComponent *e2NodeComponentInfo;
145    CmLList         *node;
146
147    if(duCb.e2apDb.e2NodeComponentList.count)
148    {
149       CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node);
150       while(node)
151       {
152          e2NodeComponentInfo = (E2NodeComponent*)node->node;
153          if((e2NodeComponentInfo->interfaceType == interfaceType) && (e2NodeComponentInfo->componentActionType == componentActionType))
154             break;
155          else
156             node = node->next;
157       }
158    }
159    return node; 
160 }
161
162 /*******************************************************************
163  *
164  * @brief Builds E2 node config addition list 
165  *
166  * @details
167  *
168  *    Function : BuildE2NodeConfigAddList
169  *
170  *    Functionality: Building E2 node config addition list
171  *
172  * @params[in] E2nodeComponentConfigAddition_List_t *e2NodeAddList 
173  * @return ROK     - success
174  *         RFAILED - failure
175  *
176  ******************************************************************/
177
178 uint8_t BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAddList)
179 {
180    uint8_t arrIdx = 0;
181    CmLList         *node;
182    E2NodeComponent *e2NodeComponentInfo;
183    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItemIe;
184    E2nodeComponentConfigAddition_Item_t *e2NodeAddItem;
185
186    e2NodeAddList->list.count = 1;
187    e2NodeAddList->list.size = e2NodeAddList->list.count * sizeof(E2nodeComponentConfigAddition_ItemIEs_t *);
188    DU_ALLOC(e2NodeAddList->list.array, e2NodeAddList->list.size);
189    if(e2NodeAddList->list.array == NULLP)
190    {
191        DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
192        return RFAILED;
193    }
194
195    for(arrIdx = 0; arrIdx< e2NodeAddList->list.count; arrIdx++)
196    {
197       DU_ALLOC(e2NodeAddList->list.array[arrIdx], sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
198       if(e2NodeAddList->list.array[arrIdx] == NULLP)
199       {
200          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
201          return RFAILED;
202       }
203    }
204    
205    node = searchE2NodeComponentInfo(F1, E2_NODE_COMPONENT_ADD);
206    if(!node)
207    {
208       DU_LOG("\nERROR  --> E2AP : Received e2NodeComponentInfo is null");
209       return RFAILED;
210    }
211    e2NodeComponentInfo = (E2NodeComponent*)node->node;
212    
213    arrIdx = 0;
214    e2NodeAddItemIe = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[arrIdx];
215    e2NodeAddItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition_Item;
216    e2NodeAddItemIe->criticality = CriticalityE2_reject;
217    e2NodeAddItemIe->value.present = E2nodeComponentConfigAddition_ItemIEs__value_PR_E2nodeComponentConfigAddition_Item;
218    e2NodeAddItem = &e2NodeAddItemIe->value.choice.E2nodeComponentConfigAddition_Item;
219    
220    /* E2nodeComponentInterfaceType */
221    e2NodeAddItem->e2nodeComponentInterfaceType = E2nodeComponentInterfaceType_f1;
222
223    /* E2 Node Component Request Part */
224    if(e2NodeComponentInfo->componentRequestPart)
225    {
226       e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.size = e2NodeComponentInfo->reqBufSize ;
227       DU_ALLOC(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\
228             e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.size);
229       if(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf == NULLP)
230       {
231          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
232          return RFAILED;
233       }
234
235       memcpy(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\
236             e2NodeComponentInfo->componentRequestPart, e2NodeAddItem->e2nodeComponentConfiguration.\
237             e2nodeComponentRequestPart.size);
238    }
239    else
240    {
241       DU_LOG("\nERROR  --> E2AP: componentRequestPart is null ");
242       return RFAILED;
243    }
244
245
246    /* E2 Node Component Response Part */
247    if(e2NodeComponentInfo->componentResponsePart)
248    {
249       e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.size = e2NodeComponentInfo->rspBufSize; 
250       DU_ALLOC(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.buf, \
251             e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.size);
252       if(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.buf == NULLP)
253       {
254          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
255          return RFAILED;
256       }
257       memcpy(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.buf, \
258             e2NodeComponentInfo->componentResponsePart, e2NodeAddItem->e2nodeComponentConfiguration.\
259             e2nodeComponentResponsePart.size);
260    }
261    else
262    {
263       DU_LOG("\nERROR  --> E2AP: componentResponsePart is null");
264       return RFAILED;
265    }
266    
267    /* E2 Node Component ID */
268    e2NodeAddItem->e2nodeComponentID.present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1;
269    DU_ALLOC(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\
270    sizeof(E2nodeComponentInterfaceF1_t));
271    if(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1 == NULLP)
272    {
273        DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
274        return RFAILED;
275    }
276    e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t);
277    DU_ALLOC(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
278    e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
279
280    if(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP)
281    {
282       DU_LOG("\nERROR  -->list.  E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
283       return RFAILED;
284    }
285    e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[arrIdx]  = e2NodeComponentInfo->componentId;
286    return ROK;
287
288 }
289
290 /*******************************************************************
291  *
292  * @brief deallocation of E2SM_KPM_RANfunction_Description_t
293  *
294  * @details
295  *
296  *    Function : freeE2smKpmRanFunctionDefinition
297  *
298  *    Functionality: deallocation of E2SM_KPM_RANfunction_Description_t
299  *
300  * @params[in]  E2SM_KPM_RANfunction_Description_t *ranFunctionDefinition
301  * @return void
302  *
303  ******************************************************************/
304
305 void freeE2smKpmRanFunctionDefinition(E2SM_KPM_RANfunction_Description_t *ranFunctionDefinition)
306 {
307    MeasurementInfo_Action_Item_t *measInfoList;
308    uint8_t eventTriggerIdx, reportStyleIdx, measInfoIdx;
309    RANfunction_Name_t *ranFuncName;
310    struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle;
311    struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List *eventTriggerStyle;
312    if(ranFunctionDefinition)
313    {
314       ranFuncName = &ranFunctionDefinition->ranFunction_Name;
315       /* Free RAN function Name */     
316       DU_FREE(ranFuncName->ranFunction_ShortName.buf,  ranFuncName->ranFunction_ShortName.size);
317       DU_FREE(ranFuncName->ranFunction_E2SM_OID.buf, ranFuncName->ranFunction_E2SM_OID.size);
318       DU_FREE(ranFuncName->ranFunction_Description.buf, ranFuncName->ranFunction_Description.size);
319
320       /* Sequence of Event Trigger styles */
321       eventTriggerStyle = ranFunctionDefinition->ric_EventTriggerStyle_List;
322       if(eventTriggerStyle)
323       {
324          if(eventTriggerStyle->list.array)
325          {
326             for(eventTriggerIdx =0;eventTriggerIdx<eventTriggerStyle->list.count; eventTriggerIdx++)
327             {
328                if(eventTriggerStyle->list.array[eventTriggerIdx])
329                {
330                   DU_FREE(eventTriggerStyle->list.array[eventTriggerIdx]->ric_EventTriggerStyle_Name.buf,\
331                         eventTriggerStyle->list.array[eventTriggerIdx]->ric_EventTriggerStyle_Name.size);
332                   DU_FREE(eventTriggerStyle->list.array[eventTriggerIdx], sizeof(RIC_EventTriggerStyle_Item_t ));
333                }
334             }
335             DU_FREE(eventTriggerStyle->list.array, eventTriggerStyle->list.size)
336          }
337          DU_FREE(eventTriggerStyle, sizeof(struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List));
338       }
339       
340       /* Sequence of Report styles */
341       ricReportStyle = ranFunctionDefinition->ric_ReportStyle_List;
342       if(ricReportStyle)
343       {
344          if(ricReportStyle->list.array)
345          {
346             for(reportStyleIdx =0;reportStyleIdx<ricReportStyle->list.count; reportStyleIdx++)
347             {
348                if(ricReportStyle->list.array[reportStyleIdx])
349                {
350                   if(ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.buf)
351                   {
352                      DU_FREE(ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.buf,\
353                            ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.size);
354                   }
355                   if(ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.array)
356                   {
357                      for(measInfoIdx=0; measInfoIdx<ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.count; \
358                            measInfoIdx++)
359                      {
360                         measInfoList = ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.array[measInfoIdx];
361                         if(measInfoList)
362                         {
363                            DU_FREE(measInfoList->measID, sizeof(long));
364                            DU_FREE(measInfoList->measName.buf, measInfoList->measName.size);
365                            DU_FREE(measInfoList,sizeof(MeasurementInfo_Action_Item_t)); 
366                         }
367                      }
368                      DU_FREE(measInfoList,ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.size);
369                   }
370                   DU_FREE(ricReportStyle->list.array[reportStyleIdx], sizeof(RIC_ReportStyle_Item_t));
371                }
372             }
373             DU_FREE(ricReportStyle->list.array, ricReportStyle->list.size);
374          }
375          DU_FREE(ricReportStyle, sizeof(struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List));
376       }
377       DU_FREE(ranFunctionDefinition, sizeof(E2SM_KPM_RANfunction_Description_t)); 
378    }
379 }
380
381 /*******************************************************************
382  *
383  * @brief fill the e2sm ric report style
384  *
385  * @details
386  *
387  *    Function : fillRicReportStyle
388  *
389  *    Functionality: fill the report style
390  *
391  * @params[in]   RanFunction *ranFuncDb, struct
392  * E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle
393  * @return ROK     - success
394  *         RFAILED - failure
395  *
396  ******************************************************************/
397 uint8_t fillRicReportStyle(RanFunction *ranFuncDb, struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle)
398 {
399    uint8_t styleIdx, measInfoIdx;
400    MeasurementInfo_Action_List_t *measInfo;
401    CmLList  *node;
402    
403    ricReportStyle->list.count = ranFuncDb->numOfReportStyleSupported;
404    ricReportStyle->list.size = ricReportStyle->list.count * sizeof(RIC_ReportStyle_Item_t*);
405    DU_ALLOC(ricReportStyle->list.array, ricReportStyle->list.size);
406    if(!ricReportStyle->list.array)
407    {
408       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for ranFuncDefinition %d",__LINE__);
409       return RFAILED;
410    }
411
412    for(styleIdx =0;styleIdx<ricReportStyle->list.count; styleIdx++)
413    {
414       DU_ALLOC(ricReportStyle->list.array[styleIdx], sizeof(RIC_ReportStyle_Item_t));
415       if(!ricReportStyle->list.array[styleIdx])
416       {
417          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
418          return RFAILED;
419       }
420       
421       /* RIC Report Style Type */
422       ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Type = ranFuncDb->reportStyleList[styleIdx].reportStyle.styleType;
423       
424       /* RIC Report Style Format Type */
425       ricReportStyle->list.array[styleIdx]->ric_ActionFormat_Type = ranFuncDb->reportStyleList[styleIdx].reportStyle.formatType;
426       
427       /* RIC Report Style Name */
428       ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size = strlen(ranFuncDb->reportStyleList[styleIdx].reportStyle.name);
429       DU_ALLOC(ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf,\
430             ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size);
431       if(!ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf)
432       {
433          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
434          return RFAILED;
435       }
436       memcpy(ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf, ranFuncDb->reportStyleList[styleIdx].reportStyle.name,\
437             ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size);
438
439       /* RIC Indication Header Format Type*/
440       ricReportStyle->list.array[styleIdx]->ric_IndicationHeaderFormat_Type = ranFuncDb->ricIndicationHeaderFormat;
441
442       /* RIC Indication Message Format Type*/
443       ricReportStyle->list.array[styleIdx]->ric_IndicationMessageFormat_Type = ranFuncDb->ricIndicationMessageFormat;
444       
445       /* Measurement Info Action List */
446       CmLListCp measInfoList =ranFuncDb->reportStyleList[styleIdx].measurementInfoList;
447       if(!measInfoList.count)
448       {
449          continue;      
450       }
451
452       CM_LLIST_FIRST_NODE(&ranFuncDb->reportStyleList[styleIdx].measurementInfoList, node);
453       measInfo = &ricReportStyle->list.array[styleIdx]->measInfo_Action_List;
454
455       measInfo->list.count = measInfoList.count; 
456       measInfo->list.size =  measInfoList.count*sizeof(MeasurementInfo_Action_Item_t*);
457       DU_ALLOC(measInfo->list.array, measInfo->list.size);
458       if(!measInfo->list.array)
459       {
460          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
461          return RFAILED;
462       }
463
464       for(measInfoIdx=0; measInfoIdx<measInfo->list.count; measInfoIdx++)
465       {
466          if(!node)
467          {
468             DU_LOG("\nERROR  --> E2AP: Measurement info node is null");
469             return RFAILED;
470          }
471
472          DU_ALLOC(measInfo->list.array[measInfoIdx],sizeof(MeasurementInfo_Action_Item_t));  
473          if(!measInfo->list.array[measInfoIdx])
474          {
475             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
476             return RFAILED;
477          }
478          MeasurementInfoForAction *measInfoForAction= (MeasurementInfoForAction*)node->node;
479          DU_ALLOC(measInfo->list.array[measInfoIdx]->measID, sizeof(long));
480          if(!measInfo->list.array[measInfoIdx]->measID)
481          {
482             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
483             return RFAILED;
484          }
485          
486          memcpy(measInfo->list.array[measInfoIdx]->measID, &measInfoForAction->measurementTypeId,sizeof(long));
487          measInfo->list.array[measInfoIdx]->measName.size= strlen(measInfoForAction->measurementTypeName);
488          DU_ALLOC(measInfo->list.array[measInfoIdx]->measName.buf, measInfo->list.array[measInfoIdx]->measName.size);
489          if(!measInfo->list.array[measInfoIdx]->measName.size)
490          {
491             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
492             return RFAILED;
493          }
494
495          memcpy(measInfo->list.array[measInfoIdx]->measName.buf, \
496                measInfoForAction->measurementTypeName,\
497                measInfo->list.array[measInfoIdx]->measName.size);
498          node = node->next;
499       }
500
501    }
502    return ROK;
503 }
504 /*******************************************************************
505  *
506  * @brief fill the ric event trigger style
507  *
508  * @details
509  *
510  *    Function : fillRicEventTriggerStyle
511  *
512  *    Functionality: fill the ric event trigger style
513  *
514  * @params[in]   
515  * @return ROK     - success
516  *         RFAILED - failure
517  *
518  ******************************************************************/
519 uint8_t fillRicEventTriggerStyle(RanFunction *ranFuncDb, struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List *ricEventTriggerStyle)
520 {
521    uint8_t styleIdx;
522
523    ricEventTriggerStyle->list.count = ranFuncDb->numOfEventTriggerStyleSupported;
524    ricEventTriggerStyle->list.size = ricEventTriggerStyle->list.count*  sizeof(RIC_EventTriggerStyle_Item_t *);
525    DU_ALLOC(ricEventTriggerStyle->list.array, ricEventTriggerStyle->list.size);
526    if(!ricEventTriggerStyle->list.array)
527    {
528       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for ric_EventTriggerStyle_List %d",__LINE__);
529       return RFAILED;
530    }
531
532    for(styleIdx =0;styleIdx<ricEventTriggerStyle->list.count; styleIdx++)
533    {
534       DU_ALLOC(ricEventTriggerStyle->list.array[styleIdx], sizeof(RIC_EventTriggerStyle_Item_t ));
535       if(!ricEventTriggerStyle->list.array[styleIdx])
536       {
537          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
538          return RFAILED;
539       }
540       ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Type = ranFuncDb->eventTriggerStyleList[styleIdx].styleType;
541
542       ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerFormat_Type = ranFuncDb->eventTriggerStyleList[styleIdx].formatType;
543
544       ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.size = strlen(ranFuncDb->eventTriggerStyleList[styleIdx].name);
545       DU_ALLOC(ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.buf,\
546             ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.size);
547       if(!ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.buf)
548       {
549          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
550          return RFAILED;
551       }
552       memcpy(ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.buf,ranFuncDb->eventTriggerStyleList[styleIdx].name,\
553             ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.size);
554    
555    }
556    return ROK;
557 }
558
559 /*******************************************************************
560  *
561  * @brief Builds Ran function item
562  *
563  * @details
564  *
565  *    Function : BuildRanFunctionItem  
566  *
567  *    Functionality: Building RAN function item
568  *
569  * @params[in] 
570  *             RAN function item that has to be filled 
571  *             Stored RAN Function information
572  * @return ROK     - success
573  *         RFAILED - failure
574  *
575  ******************************************************************/
576
577 uint8_t BuildRanFunctionItem(RANfunction_Item_t *ranFuncItem, RanFunction *ranFuncDb)
578 {
579    uint8_t ret =RFAILED;
580    RANfunctionDefinition_t  *ranFunctionDefinition;
581    RANfunction_Name_t *ranFuncName;
582    asn_enc_rval_t encRetVal;
583    E2SM_KPM_RANfunction_Description_t *ranFuncDefinition;
584    
585    while(true)
586    {
587       /* RAN function Id*/
588       ranFuncItem->ranFunctionID = ranFuncDb->id;
589
590       /* RAN Function Revision*/
591       ranFuncItem->ranFunctionRevision = ranFuncDb->revisionCounter;
592
593       /* RAN function OID*/
594       ranFuncItem->ranFunctionOID.size = strlen(ranFuncDb->name.serviceModelOID);
595       DU_ALLOC(ranFuncItem->ranFunctionOID.buf, ranFuncItem->ranFunctionOID.size);
596       if(!ranFuncItem->ranFunctionOID.buf)
597       {
598          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
599          break;
600       }
601       memcpy(ranFuncItem->ranFunctionOID.buf, ranFuncDb->name.serviceModelOID, ranFuncItem->ranFunctionOID.size);
602
603       /* RAN function Definition */
604       DU_ALLOC(ranFuncDefinition, sizeof(E2SM_KPM_RANfunction_Description_t));
605       if(!ranFuncDefinition)
606       {
607          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
608          break;
609       }
610
611       /* RAN function Name */
612       ranFuncName = &ranFuncDefinition->ranFunction_Name;
613
614       /* RAN function ShortName */
615       ranFuncName->ranFunction_ShortName.size = strlen(ranFuncDb->name.shortName); 
616       DU_ALLOC(ranFuncName->ranFunction_ShortName.buf,  ranFuncName->ranFunction_ShortName.size);
617       if(!ranFuncName->ranFunction_ShortName.buf)
618       {
619          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
620          break;
621       }
622       memcpy(ranFuncName->ranFunction_ShortName.buf, ranFuncDb->name.shortName, strlen(ranFuncDb->name.shortName));
623
624       /* RAN function E2SM_OID */
625       ranFuncName->ranFunction_E2SM_OID.size = strlen(ranFuncDb->name.serviceModelOID);
626       DU_ALLOC(ranFuncName->ranFunction_E2SM_OID.buf, ranFuncName->ranFunction_E2SM_OID.size);
627       if(!ranFuncName->ranFunction_E2SM_OID.buf)
628       {
629          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
630          break;
631       }
632       memcpy(ranFuncName->ranFunction_E2SM_OID.buf, ranFuncDb->name.serviceModelOID, ranFuncName->ranFunction_E2SM_OID.size);
633
634       /* RAN Function Name Description */
635       ranFuncName->ranFunction_Description.size = strlen(ranFuncDb->name.description);
636       DU_ALLOC(ranFuncName->ranFunction_Description.buf, ranFuncName->ranFunction_Description.size);
637       if(!ranFuncName->ranFunction_Description.buf)
638       {
639          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
640          break;
641       }
642       memcpy(ranFuncName->ranFunction_Description.buf, ranFuncDb->name.description, ranFuncName->ranFunction_Description.size);
643
644       /* RIC Event Trigger Style List */
645       DU_ALLOC(ranFuncDefinition->ric_EventTriggerStyle_List, sizeof(struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List));
646       if(!ranFuncDefinition->ric_EventTriggerStyle_List)
647       {
648          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
649          break;
650       }
651
652       if(fillRicEventTriggerStyle(ranFuncDb, ranFuncDefinition->ric_EventTriggerStyle_List)!=ROK)
653       {
654          DU_LOG("\nERROR  --> E2AP: failed to fill ric event trigger style");
655          break;
656       }
657
658       /* RIC Report Style List */
659       DU_ALLOC(ranFuncDefinition->ric_ReportStyle_List, sizeof(struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List));
660       if(!ranFuncDefinition->ric_ReportStyle_List)
661       {
662          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
663          break;
664       }
665       if(fillRicReportStyle(ranFuncDb, ranFuncDefinition->ric_ReportStyle_List) != ROK)
666       {
667          DU_LOG("\nERROR  --> E2AP: failed to fill ric report style");
668          break;
669       }
670
671       /* Encode the F1SetupRequest type as APER */
672       xer_fprint(stdout, &asn_DEF_E2SM_KPM_RANfunction_Description, ranFuncDefinition);
673
674       memset(encBuf, 0, ENC_BUF_MAX_LEN);
675       encBufSize = 0;
676       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_RANfunction_Description, 0, ranFuncDefinition, PrepFinalEncBuf, encBuf);
677
678       /* Encode results */
679       if(encRetVal.encoded == ENCODE_FAIL)
680       {
681          DU_LOG("\nERROR  -->  F1AP : Could not encode RAN function definition  (at %s)\n",\
682                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
683          break;
684       }
685       else
686       {
687          DU_LOG("\nDEBUG   -->  F1AP : Created APER encoded buffer for RAN function definition \n");
688          for(uint8_t measIeIdx=0; measIeIdx< encBufSize; measIeIdx++)
689          {
690             printf("%x",encBuf[measIeIdx]);
691          }
692          ranFunctionDefinition = &ranFuncItem->ranFunctionDefinition; 
693          ranFunctionDefinition->size = encBufSize;
694          DU_ALLOC(ranFunctionDefinition->buf, encBufSize);
695          if(ranFunctionDefinition->buf == NULLP)
696          {
697             DU_LOG("\nERROR  -->  F1AP : Memory allocation failed for RAN function definition buffer");
698             break;
699          }
700          memcpy(ranFunctionDefinition->buf, &encBuf, encBufSize);
701          ret = ROK;
702          break;
703       }
704    }
705    freeE2smKpmRanFunctionDefinition(ranFuncDefinition);
706    return ret;
707 }
708
709 /*******************************************************************
710  *
711  * @brief Builds Ran function add list based on the procedure code
712  *
713  * @details
714  *
715  *    Function : BuildRanFunctionAddList 
716  *
717  *    Functionality: Building RAN addition addition list
718  *       In case of ProcedureCodeE2_id_E2setup we add all the RAN Function list
719  *       which is present in E2 database.
720  *       In the case of other procedures, we just fill the RAN functions whose ID 
721  *       is contained in recvList
722  *
723  * @params[in] 
724  *       RAN Function list
725  *       Procedure code
726  *       Count of ran functions to be added in the list
727  *       Received list of RAN functions
728  *
729  * @return ROK     - success
730  *         RFAILED - failure
731  *
732  ******************************************************************/
733
734 uint8_t BuildRanFunctionAddList(RANfunctions_List_t *ranFunctionsList, uint8_t procedureCode, uint8_t count, uint8_t *recvList)
735 {
736    uint16_t id;
737    RanFunction *ranFuncDb;
738    uint8_t ranFuncIdx;
739    RANfunction_ItemIEs_t *ranFuncItemIe;
740    
741    /* For ProcedureCodeE2_id_E2setup, the number of RAN function list items is
742     * equal to the number of ran function entries stored in the database.
743     * For any other procedure, the RAN function list count is equal
744     * to the count of ran functions obtained from the function's caller */
745
746    if(procedureCode == ProcedureCodeE2_id_E2setup)
747       ranFunctionsList->list.count = duCb.e2apDb.numOfRanFunction;
748    else
749       ranFunctionsList->list.count = count;
750
751    ranFunctionsList->list.size = ranFunctionsList->list.count * sizeof(RANfunction_ItemIEs_t*);
752    DU_ALLOC(ranFunctionsList->list.array, ranFunctionsList->list.size);
753    if(ranFunctionsList->list.array == NULLP)
754    {
755       DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
756       return RFAILED;
757    }
758
759    for(ranFuncIdx = 0; ranFuncIdx< ranFunctionsList->list.count; ranFuncIdx++)
760    {
761       DU_ALLOC(ranFunctionsList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
762       if(ranFunctionsList->list.array[ranFuncIdx] == NULLP)
763       {
764          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
765          return RFAILED;
766       }
767       if(procedureCode == ProcedureCodeE2_id_E2setup) 
768       {
769          /* Getting all of the RAN function's information from DuCb one by one*/
770          ranFuncDb = &duCb.e2apDb.ranFunction[ranFuncIdx];
771       }
772       else
773       {
774          /* Getting only the RAN function information from DuCb whose Id is
775           * present in the received array */
776          id =recvList[ranFuncIdx];
777          ranFuncDb = &duCb.e2apDb.ranFunction[id-1];
778       }
779       ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncIdx];
780       ranFuncItemIe->id = ProtocolIE_IDE2_id_RANfunction_Item;
781       ranFuncItemIe->criticality = CriticalityE2_ignore;
782       ranFuncItemIe->value.present = RANfunction_ItemIEs__value_PR_RANfunction_Item;
783       BuildRanFunctionItem(&ranFuncItemIe->value.choice.RANfunction_Item, ranFuncDb);
784    }
785    return ROK;
786 }   
787
788 /*******************************************************************
789  *
790  * @brief De Allocate E2 Setup Request Message
791  *
792  * @details
793  *
794  *    Function : FreeE2SetupReq
795  *
796  *    Functionality: De-Allocating E2 Setup request Message
797  *
798  * @params[in] E2AP_PDU_t *e2apMsg
799  
800  * @return void
801  *
802  * ****************************************************************/
803
804 void FreeE2SetupReq(E2AP_PDU_t *e2apMsg)
805 {
806    uint8_t arrIdx = 0;
807    uint8_t e2NodeAddListIdx =0, ranFuncAddListIdx;
808    E2setupRequest_t *e2SetupReq;
809    E2nodeComponentConfigAddition_List_t *e2NodeAddList;
810    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
811    RANfunctions_List_t *ranFunctionsList;
812    RANfunction_ItemIEs_t *ranFuncItemIe;
813    RANfunction_Item_t  *ranFunItem;
814
815    /* De-allocating Memory */
816    if(e2apMsg != NULLP)
817    {
818       if(e2apMsg->choice.initiatingMessage != NULLP)
819       {
820          e2SetupReq = &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest; 
821          if(e2SetupReq->protocolIEs.list.array != NULLP)
822          {
823             for(arrIdx = 0; arrIdx < e2SetupReq->protocolIEs.list.count; arrIdx++)
824             {
825                if(e2SetupReq->protocolIEs.list.array[arrIdx] != NULLP)
826                {
827                   switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
828                   {
829                      case ProtocolIE_IDE2_id_TransactionID:
830                           break;
831                      case ProtocolIE_IDE2_id_GlobalE2node_ID:
832                         {
833                            if(e2SetupReq->protocolIEs.list.array[arrIdx]->\
834                                  value.choice.GlobalE2node_ID.choice.gNB != NULLP)
835                            {
836                               GlobalE2node_gNB_ID_t *gNbId = NULLP;
837                               gNbId = e2SetupReq->protocolIEs.list.array[arrIdx]->\
838                                       value.choice.GlobalE2node_ID.choice.gNB;
839                               if(gNbId->global_gNB_ID.plmn_id.buf != NULLP)
840                               {
841                                  DU_FREE(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf,\
842                                        gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size);
843                                  DU_FREE(gNbId->global_gNB_ID.plmn_id.buf,\
844                                        gNbId->global_gNB_ID.plmn_id.size);
845                               }
846
847                               if(gNbId->gNB_DU_ID != NULLP)
848                               {
849                                  DU_FREE( gNbId->gNB_DU_ID->buf, gNbId->gNB_DU_ID->size);
850                                  DU_FREE(gNbId->gNB_DU_ID, sizeof(GNB_DU_ID_t));
851                               }
852                               DU_FREE(e2SetupReq->protocolIEs.list.array[arrIdx]->value.\
853                                     choice.GlobalE2node_ID.choice.gNB, sizeof(GlobalE2node_gNB_ID_t));
854                            }
855                            break;
856                         }
857                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
858                      {
859                          e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;
860                          if(e2NodeAddList->list.array)
861                          {
862                              for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
863                              {
864                                 e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
865                                 
866                                 /* Free E2 Node Component Request Part */
867                                 DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\
868                                       e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentRequestPart.size);
869                                 
870                                 /* Free E2 Node Component Response Part */
871                                 DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.\
872                                       e2nodeComponentResponsePart.buf, \
873                                       e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentResponsePart.size);
874                                  
875                                  /* Free E2 Node Component ID */
876                                 if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1)
877                                 {
878                                     DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
879                                     e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
880                                     e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
881                                     e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
882                                     DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\
883                                     sizeof(E2nodeComponentInterfaceF1_t));
884                                 }
885                                 DU_FREE(e2NodeAddList->list.array[e2NodeAddListIdx], sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
886                              }
887                              DU_FREE(e2NodeAddList->list.array, e2NodeAddList->list.size);
888                          }
889                          break;
890                      }
891                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
892                      {
893                         ranFunctionsList = &(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List);  
894                         if(ranFunctionsList->list.array)
895                         {  
896                            for(ranFuncAddListIdx= 0; ranFuncAddListIdx< ranFunctionsList->list.count; ranFuncAddListIdx++)
897                            {
898                               if(ranFunctionsList->list.array[ranFuncAddListIdx])
899                               {
900                                  ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncAddListIdx];
901                                  ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
902                                  DU_FREE(ranFunItem->ranFunctionOID.buf, ranFunItem->ranFunctionOID.size);
903                                  DU_FREE(ranFunItem->ranFunctionDefinition.buf, ranFunItem->ranFunctionDefinition.size);
904                                  DU_FREE(ranFunctionsList->list.array[ranFuncAddListIdx], sizeof(RANfunction_ItemIEs_t));
905                               }
906                            }
907                            DU_FREE(ranFunctionsList->list.array, ranFunctionsList->list.size);
908                         }
909                         break;
910                      }
911
912                      default:
913                         DU_LOG("\nERROR  --> E2AP: Invalid event at e2SetupRequet %ld ",\
914                               (e2SetupReq->protocolIEs.list.array[arrIdx]->id));
915                         break;
916                   }
917                   DU_FREE(e2SetupReq->protocolIEs.list.array[arrIdx], sizeof(E2setupRequestIEs_t));
918                }
919             }
920             DU_FREE(e2SetupReq->protocolIEs.list.array, e2SetupReq->protocolIEs.list.size);
921          }
922          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
923       }
924       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
925    }
926 }
927
928 /*******************************************************************
929  *
930  * @brief Builds and Send the E2SetupRequest
931  *
932  * @details
933  *
934  *    Function : BuildAndSendE2SetupReq
935  *
936  * Functionality:Fills the E2SetupRequest
937  *
938  * @return ROK     - success
939  *         RFAILED - failure
940  *
941  ******************************************************************/
942
943 uint8_t BuildAndSendE2SetupReq()
944 {
945    uint8_t arrIdx = 0, elementCnt=0;
946    uint8_t transId = 0, ret = ROK;
947    bool memAllocFailed;
948    E2AP_PDU_t        *e2apMsg = NULLP;
949    E2setupRequest_t  *e2SetupReq = NULLP;
950    asn_enc_rval_t     encRetVal;       /* Encoder return value */
951
952    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup Request\n");
953    do
954    {
955       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
956       if(e2apMsg == NULLP)
957       {
958          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
959          break;
960       }
961       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
962       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
963       if(e2apMsg->choice.initiatingMessage == NULLP)
964       {
965          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
966          break;
967       }
968       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
969       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2setup;
970       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2setupRequest;
971       e2SetupReq = &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest;
972
973       elementCnt = 4;
974       e2SetupReq->protocolIEs.list.count = elementCnt;
975       e2SetupReq->protocolIEs.list.size = elementCnt * sizeof(E2setupRequestIEs_t*);
976
977       /* Initialize the E2Setup members */
978       DU_ALLOC(e2SetupReq->protocolIEs.list.array, \
979             e2SetupReq->protocolIEs.list.size);
980       if(e2SetupReq->protocolIEs.list.array == NULLP)
981       {
982          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
983          break;
984       }
985       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
986       {
987          DU_ALLOC(e2SetupReq->protocolIEs.list.array[arrIdx],\
988                sizeof(E2setupRequestIEs_t));
989          if(e2SetupReq->protocolIEs.list.array[arrIdx] == NULLP)
990          {
991             memAllocFailed = true;
992             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayarrIdx [%d]", arrIdx);
993             break;
994          }
995       }
996       if(memAllocFailed == true)
997          break;
998
999       arrIdx = 0;
1000
1001       /* TransactionID */
1002       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
1003       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1004       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
1005       transId = assignTransactionId();
1006       e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
1007
1008       arrIdx++;
1009       /* GlobalE2node_gNB_ID */
1010       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_GlobalE2node_ID;
1011       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1012       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_GlobalE2node_ID;
1013       e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.present = GlobalE2node_ID_PR_gNB;
1014
1015       DU_ALLOC(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.\
1016             GlobalE2node_ID.choice.gNB, sizeof(GlobalE2node_gNB_ID_t));
1017       if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.\
1018             GlobalE2node_ID.choice.gNB == NULLP)
1019       {
1020          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for gNbId");
1021          break;
1022       }
1023       else
1024       {
1025          ret = BuildGlobalgNBId(e2SetupReq->protocolIEs.list.array[arrIdx]->value.\
1026                choice.GlobalE2node_ID.choice.gNB);
1027          if(ret != ROK)
1028          {
1029              DU_LOG("\nERROR  -->  E2AP : Failed to build Global Gnb Id");
1030              break;
1031          }
1032       }
1033       
1034       /* RAN Functions Added List */
1035       arrIdx++;
1036       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAdded;
1037       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1038       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_RANfunctions_List;
1039       if(BuildRanFunctionAddList(&(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List), ProcedureCodeE2_id_E2setup, 0, NULL)!=ROK)      
1040       {
1041          DU_LOG("\nERROR  -->  E2AP : Failed to create RAN Function");
1042          break;
1043       }
1044
1045       /* E2 Node Component Configuration Addition List */
1046       arrIdx++;
1047       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition;
1048       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1049       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_E2nodeComponentConfigAddition_List;
1050       if(BuildE2NodeConfigAddList(&(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List))!=ROK)
1051       {
1052          DU_LOG("\nERROR  -->  E2AP : Failed to create E2 Node config list");
1053          break;
1054       }
1055
1056
1057
1058       /* Prints the Msg formed */
1059       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1060
1061       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1062       encBufSize = 0;
1063       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
1064             encBuf);
1065       if(encRetVal.encoded == ENCODE_FAIL)
1066       {
1067          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupRequest structure (at %s)\n",\
1068                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1069          break;
1070       }
1071       else
1072       {
1073          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2SetupRequest\n");
1074 #ifdef DEBUG_ASN_PRINT
1075          for(int i=0; i< encBufSize; i++)
1076          {
1077             printf("%x",encBuf[i]);
1078          }
1079 #endif
1080       }
1081       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
1082       {
1083          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
1084       }
1085       break;
1086    }while(true);
1087
1088    duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
1089    duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
1090    
1091    FreeE2SetupReq(e2apMsg);
1092    return ret;
1093 }/* End of BuildAndSendE2SetupReq */
1094
1095 /*******************************************************************
1096  *
1097  * @brief Builds Ric Request Id
1098  *
1099  * @details
1100  *
1101  *    Function : BuildRicRequestId
1102  *
1103  *    Functionality: Building the Ric Request Id
1104  *
1105  * @params[in] RICrequestID_t *ricReqId
1106  * @return ROK     - success
1107  *         RFAILED - failure
1108  *
1109  * ****************************************************************/
1110
1111 uint8_t BuildRicRequestId(RICrequestID_t *ricReqId)
1112 {
1113    if(ricReqId == NULLP)
1114    {
1115       return RFAILED;
1116    }
1117
1118    ricReqId->ricRequestorID = 1;
1119    ricReqId->ricInstanceID  = 1;
1120    return ROK;
1121 }
1122
1123 /*******************************************************************
1124  *
1125  * @brief Fills the mandatory RicAdmitted List Items
1126  *
1127  * @details
1128  *
1129  *    Function : fillRicAdmitList
1130  *
1131  *    Functionality: Fills the mandatory Ric Admitted List Items
1132  *
1133  * @params[in] RICaction_Admitted_ItemIEs_t *ricAdmitItems
1134  * @return ROK     - success
1135  *         RFAILED - failure
1136  *
1137  * ****************************************************************/
1138
1139 uint8_t fillRicAdmitList(RICaction_Admitted_ItemIEs_t *ricAdmitItems)
1140 {
1141
1142    if(ricAdmitItems != NULLP)
1143    {
1144       ricAdmitItems->id = ProtocolIE_IDE2_id_RICaction_Admitted_Item;
1145       ricAdmitItems->criticality = CriticalityE2_reject;
1146       ricAdmitItems->value.present = RICaction_Admitted_ItemIEs__value_PR_RICaction_Admitted_Item;
1147       ricAdmitItems->value.choice.RICaction_Admitted_Item.ricActionID = 1; 
1148    }
1149    else
1150    {
1151       return RFAILED;
1152    }
1153    return ROK;
1154 }
1155 /*******************************************************************
1156  *
1157  * @brief Builds the mandatory RicAdmitted List Params
1158  *
1159  * @details
1160  *
1161  *    Function : BuildRicAdmitList
1162  *
1163  *    Functionality: Builds the mandatory Ric Admitted List Params
1164  *
1165  * @params[in] RICaction_Admitted_List_t *admitListPtr
1166  * @return ROK     - success
1167  *         RFAILED - failure
1168  *
1169  * ****************************************************************/
1170
1171 uint8_t BuildRicAdmitList(RICaction_Admitted_List_t *admitListPtr)
1172 {
1173    uint8_t idx ;
1174    uint8_t elementCnt;  
1175    uint8_t ret= ROK;
1176    elementCnt = 1;
1177
1178    if(admitListPtr == NULLP)
1179    {
1180       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC Admit List failed");
1181       ret = RFAILED;
1182    }
1183    else
1184    {
1185       admitListPtr->list.count = elementCnt;
1186       admitListPtr->list.size  = elementCnt * sizeof(RICaction_Admitted_ItemIEs_t);
1187       DU_ALLOC(admitListPtr->list.array, admitListPtr->list.size);
1188       if(admitListPtr->list.array == NULLP)
1189       {
1190          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC Admit List failed");
1191          ret = RFAILED;
1192       }
1193       else
1194       {
1195          for(idx=0 ; idx<elementCnt ; idx++ )
1196          {
1197             DU_ALLOC(admitListPtr->list.array[idx], sizeof(RICaction_Admitted_ItemIEs_t));
1198             if(admitListPtr->list.array[idx] == NULLP)
1199             {
1200                ret = RFAILED;
1201             }
1202          }
1203          if(ret != RFAILED)
1204          {
1205             idx=0;
1206             fillRicAdmitList((RICaction_Admitted_ItemIEs_t *)admitListPtr->list.array[idx]);
1207          }
1208       }
1209    }    
1210    return ret;
1211 }
1212 /*******************************************************************
1213  *
1214  * @breif Deallocation of BuildAndSendRicSubscriptionRsp memory
1215  *
1216  * @details
1217  *
1218  *    Function : FreeRicSubscriptionRsp
1219  *
1220  * Functionality:Free the RicSubscriptionRsp
1221  *
1222  * @param[in] E2AP_PDU_t *e2apRicMsg
1223  *
1224  * @return void
1225  *      
1226  *
1227  ******************************************************************/
1228 void FreeRicSubscriptionRsp(E2AP_PDU_t  *e2apRicMsg)
1229 {
1230    RICsubscriptionResponse_t  *ricSubscriptionRsp= NULLP;
1231    uint8_t idx=0;
1232    uint8_t idx1=0;
1233    RICaction_Admitted_List_t *admitListPtr;
1234
1235    if(e2apRicMsg != NULLP)
1236    {
1237       if(e2apRicMsg->choice.successfulOutcome != NULLP)
1238       {
1239          ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
1240          if(ricSubscriptionRsp)
1241          {
1242             if(ricSubscriptionRsp->protocolIEs.list.array != NULLP)
1243             {
1244                for(idx=0; idx<ricSubscriptionRsp->protocolIEs.list.count; idx++)
1245                {
1246                   if(ricSubscriptionRsp->protocolIEs.list.array[idx] != NULLP)
1247                   {
1248                      switch(ricSubscriptionRsp->protocolIEs.list.array[idx]->id)
1249                      {
1250                         case ProtocolIE_IDE2_id_RICrequestID:
1251                            break;
1252
1253                         case ProtocolIE_IDE2_id_RANfunctionID:
1254                            break;
1255
1256                         case ProtocolIE_IDE2_id_RICactions_Admitted:
1257                            {
1258                               admitListPtr = &ricSubscriptionRsp->protocolIEs.list.\
1259                                              array[idx]->value.choice.RICaction_Admitted_List;
1260                               if(admitListPtr->list.array != NULLP)
1261                               {
1262                                  for(idx1=0 ; idx1<admitListPtr->list.count; idx1++ )
1263                                  {
1264                                     if(admitListPtr->list.array[idx1] != NULLP)
1265                                     {
1266                                        DU_FREE(admitListPtr->list.array[idx1],
1267                                              sizeof(RICaction_Admitted_ItemIEs_t));
1268                                     }
1269                                  }
1270                                  DU_FREE(admitListPtr->list.array, admitListPtr->list.size);     
1271                               }
1272                               break;
1273                            }
1274                         default:
1275                            break;
1276                      }
1277                      DU_FREE(ricSubscriptionRsp->protocolIEs.list.array[idx], \
1278                            sizeof(RICsubscriptionResponse_IEs_t));
1279                   }
1280                }
1281                DU_FREE(ricSubscriptionRsp->protocolIEs.list.array, \
1282                      ricSubscriptionRsp->protocolIEs.list.size);
1283             }
1284          }   
1285          DU_FREE(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1286       }         
1287       DU_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));        
1288    }
1289 }
1290 /*******************************************************************
1291  *
1292  * @brief Builds and Send the RicSubscriptionRsp
1293  *
1294  * @details
1295  *
1296  *    Function : BuildAndSendRicSubscriptionRsp
1297  *
1298  * functionality:Fills the RicSubscriptionRsp
1299  *
1300  * @return ROK     - success
1301  *         RFAILED - failure
1302  *
1303  ******************************************************************/
1304 uint8_t  FillRicSubscriptionRsp(RICsubscriptionResponse_t  *ricSubscriptionRsp )
1305 {
1306    uint8_t idx=0;
1307    uint8_t ret = ROK;
1308    uint8_t elementCnt = 0;
1309    uint8_t BuildRicRequestIdret=ROK;
1310    uint8_t BuildRicAdmitListret=ROK;
1311
1312    elementCnt=3;
1313    ricSubscriptionRsp->protocolIEs.list.count = elementCnt;
1314    ricSubscriptionRsp->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionResponse_IEs_t);
1315    DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array, \
1316          ricSubscriptionRsp->protocolIEs.list.size);
1317    if(ricSubscriptionRsp->protocolIEs.list.array == NULLP)
1318    {
1319       DU_LOG("\nERROR  -->  E2AP : Memory allocation for FillRicSubscriptionRsp  failed");
1320       ret = RFAILED;
1321    }
1322    else
1323    {
1324       for(idx=0; idx<ricSubscriptionRsp->protocolIEs.list.count; idx++)
1325       {
1326          DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array[idx], \
1327                sizeof(RICsubscriptionResponse_IEs_t));
1328          if(ricSubscriptionRsp->protocolIEs.list.array[idx] == NULLP)
1329          {
1330             ret = RFAILED;
1331          }
1332       }
1333       if(ret != RFAILED)
1334       {
1335
1336          idx=0;
1337          ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
1338          ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1339          ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
1340                                                                          RICsubscriptionRequest_IEs__value_PR_RICrequestID;
1341          BuildRicRequestIdret =
1342             BuildRicRequestId(&ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RICrequestID);
1343          if(BuildRicRequestIdret != ROK)
1344          {
1345             ret = RFAILED;
1346          }
1347          else
1348          {
1349             idx++;
1350             ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
1351             ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1352             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
1353                                                                             RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
1354             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1;
1355
1356             idx++;
1357             ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactions_Admitted;
1358             ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1359             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
1360                                                                             RICsubscriptionResponse_IEs__value_PR_RICaction_Admitted_List;
1361             BuildRicAdmitListret =
1362                BuildRicAdmitList(&ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RICaction_Admitted_List);
1363             if(BuildRicAdmitListret != ROK)
1364             {
1365                ret = RFAILED;
1366             }
1367          }
1368       }
1369    }    
1370    return ret;
1371 }
1372 /*******************************************************************
1373  *
1374  * @brief Builds and Send the RicSubscriptionRsp
1375  *
1376  * @details
1377  *
1378  *    Function : BuildAndSendRicSubscriptionRsp
1379  *
1380  * Functionality:Fills the RicSubscriptionRsp
1381  *
1382  * @return ROK     - success
1383  *         RFAILED - failure
1384  *
1385  ******************************************************************/
1386
1387 uint8_t BuildAndSendRicSubscriptionRsp()
1388 {
1389
1390    E2AP_PDU_t         *e2apRicMsg = NULLP;
1391    RICsubscriptionResponse_t  *ricSubscriptionRsp=NULLP;
1392    asn_enc_rval_t     encRetVal; 
1393    uint8_t ret = RFAILED;
1394    uint8_t FillRicricSubscriptionRspret;
1395
1396    while(true)
1397    {
1398       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Response\n");
1399
1400       DU_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t)); 
1401       if(e2apRicMsg == NULLP)
1402       {
1403          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1404          break;
1405       }
1406       e2apRicMsg->present =  E2AP_PDU_PR_successfulOutcome;
1407       DU_ALLOC(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1408       if(e2apRicMsg->choice.successfulOutcome == NULLP)
1409       {
1410          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC subscription Response failed");
1411          break;
1412       }
1413
1414       e2apRicMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
1415       e2apRicMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
1416       e2apRicMsg->choice.successfulOutcome->value.present = \
1417                                                             SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse;
1418       ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
1419
1420       FillRicricSubscriptionRspret = FillRicSubscriptionRsp(ricSubscriptionRsp);
1421       if(FillRicricSubscriptionRspret != ROK)
1422       {
1423          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICsubscriptionResponseIE failed");
1424          break;
1425       }
1426
1427       /* Prints the Msg formed */
1428       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
1429
1430       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1431       encBufSize = 0;
1432       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\
1433             encBuf);
1434       if(encRetVal.encoded == ENCODE_FAIL)
1435       {
1436          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Response structure (at %s)\n",\
1437                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1438          break;
1439       }
1440       else
1441       {
1442          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RIC subscription response \n");
1443 #ifdef DEBUG_ASN_PRINT
1444          for(int i=0; i< encBufSize; i++)
1445          {
1446             printf("%x",encBuf[i]);
1447          } 
1448 #endif
1449       } 
1450
1451       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
1452       {
1453          DU_LOG("\nERROR  -->  E2AP : Sending RIC Subscription Response failed");      
1454          break;
1455       }
1456
1457       ret = ROK;
1458       break;
1459
1460    }
1461    FreeRicSubscriptionRsp(e2apRicMsg);
1462
1463    return ret;
1464 }
1465
1466 /******************************************************************
1467  *
1468  * @brief Deallocation of memory allocated bu aper decoder for e2 setup response
1469  *
1470  * @details
1471  *
1472  *    Function : freeAperDecodingOfE2SetupRsp
1473  *
1474  *    Functionality: Deallocation of memory allocated bu aper decoder for e2
1475  *    setup response
1476  *
1477  * @params[in] E2setupResponse_t *e2SetRspMsg;
1478  * @return void
1479  *
1480  * ****************************************************************/
1481 void freeAperDecodingOfE2SetupRsp(E2setupResponse_t *e2SetRspMsg)
1482 {
1483    uint8_t arrIdx, e2NodeConfigAddAckListIdx;
1484    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem;
1485    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAddAckList;
1486
1487    if(e2SetRspMsg)
1488    {
1489       if(e2SetRspMsg->protocolIEs.list.array)
1490       {
1491          for(arrIdx=0; arrIdx<e2SetRspMsg->protocolIEs.list.count; arrIdx++)
1492          {
1493             if(e2SetRspMsg->protocolIEs.list.array[arrIdx])
1494             {
1495                switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
1496                {
1497                   case ProtocolIE_IDE2_id_TransactionID:
1498                      break;
1499
1500                   case ProtocolIE_IDE2_id_GlobalRIC_ID:
1501                      {
1502                         free(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.pLMN_Identity.buf);
1503                         free(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID.buf);
1504                         break;
1505                      }
1506
1507                   case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
1508                      {
1509                         e2NodeConfigAddAckList = &e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
1510                         if(e2NodeConfigAddAckList->list.array )
1511                         {
1512                            for(e2NodeConfigAddAckListIdx = 0; e2NodeConfigAddAckListIdx< e2NodeConfigAddAckList->list.count; e2NodeConfigAddAckListIdx++)
1513                            {
1514                               if(e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx])
1515                               {
1516                                  e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx];
1517                                  free(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.\
1518                                        e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf);
1519                                  free(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.\
1520                                        e2nodeComponentInterfaceTypeF1);
1521                                  free(e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx]);
1522                               }
1523                            }
1524                            free(e2NodeConfigAddAckList->list.array);
1525                         }
1526                         break;
1527                      }
1528                }
1529                free(e2SetRspMsg->protocolIEs.list.array[arrIdx]);  
1530             }
1531          }
1532          free(e2SetRspMsg->protocolIEs.list.array);
1533       }
1534    }
1535 }
1536 /******************************************************************
1537  *
1538  * @brief Processes E2 Setup Response sent by RIC
1539  *
1540  * @details
1541  *
1542  *    Function : procE2SetupRsp
1543  *
1544  *    Functionality: Processes E2 Setup Response sent by RIC
1545  *
1546  * @params[in] E2AP_PDU_t ASN decoded E2AP message
1547  * @return ROK     - success
1548  *         RFAILED - failure
1549  *
1550  * ****************************************************************/
1551 uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg)
1552 {
1553    uint8_t arrIdx =0, transId=0; 
1554    uint32_t recvBufLen;             
1555    E2setupResponse_t *e2SetRspMsg;
1556    CmLList         *node;
1557    E2NodeComponent *e2NodeComponentInfo;
1558
1559    DU_LOG("\nINFO   -->  E2AP : E2 Setup Response received"); 
1560    duCb.e2Status = TRUE; //Set E2 status as true
1561    e2SetRspMsg = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
1562
1563    for(arrIdx=0; arrIdx<e2SetRspMsg->protocolIEs.list.count; arrIdx++)
1564    {
1565       switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
1566       {
1567          case ProtocolIE_IDE2_id_TransactionID:
1568             {
1569                transId = e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
1570                if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
1571                      (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
1572                {
1573                   memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
1574                }
1575                else
1576                {
1577                   DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
1578                   return RFAILED;
1579                }
1580                break;
1581             }
1582
1583          case ProtocolIE_IDE2_id_GlobalRIC_ID:
1584             {
1585                /* To store the Ric Id Params */
1586                recvBufLen = sizeof(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value\
1587                      .choice.GlobalRIC_ID.pLMN_Identity.size);
1588                   memcpy(&duCb.e2apDb.ricId.plmnId, e2SetRspMsg->protocolIEs.list.array[arrIdx]\
1589                         ->value.choice.GlobalRIC_ID.pLMN_Identity.buf, recvBufLen);
1590                bitStringToInt(&e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID, &duCb.e2apDb.ricId);
1591                /*TODO : duCb.e2apDb.ricId.plmnId memory to be deallocated after the usage */
1592                break;
1593             }
1594
1595          case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
1596             break;
1597
1598          default:
1599             DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2SetupRsp:%ld",
1600                   e2SetRspMsg->protocolIEs.list.array[arrIdx]->id);
1601             break;
1602       }
1603    }
1604    freeAperDecodingOfE2SetupRsp(e2SetRspMsg);
1605    
1606    node = searchE2NodeComponentInfo(F1, E2_NODE_COMPONENT_ADD);
1607    if(!node)
1608    {
1609       DU_LOG("\nERROR  --> E2AP : Received e2NodeComponentInfo is null");
1610       return RFAILED;
1611    }
1612    else
1613    {
1614       e2NodeComponentInfo = (E2NodeComponent*)node->node;
1615       cmLListDelFrm(&duCb.e2apDb.e2NodeComponentList, node);
1616       DU_FREE(e2NodeComponentInfo->componentRequestPart, e2NodeComponentInfo->reqBufSize);
1617       DU_FREE(e2NodeComponentInfo->componentResponsePart, e2NodeComponentInfo->rspBufSize);
1618       DU_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent));
1619       DU_FREE(node, sizeof(CmLList));
1620    }
1621
1622    BuildAndSendE2NodeConfigUpdate();
1623    return ROK;
1624 }
1625
1626 /******************************************************************
1627  *
1628  * @brief Processes RIC Subscription Req sent by RIC
1629  *
1630  * @details
1631  *
1632  *    Function : procRicSubsReq
1633  *
1634  *    Functionality: Processes E2 Setup Response sent by CU
1635  *
1636  * @params[in] E2AP_PDU_t ASN decoded E2AP message
1637  * @return ROK     - success
1638  *         RFAILED - failure
1639  *
1640  * ****************************************************************/
1641
1642 uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg)
1643 {
1644    uint8_t idx; 
1645    uint8_t ied; 
1646    uint8_t ret = ROK;
1647    CmLList  *ricSubscriptionNode = NULLP;
1648    RICsubscriptionRequest_t *ricSubsReq;
1649    RicSubscription *ricSubscriptionInfo;
1650    RICaction_ToBeSetup_ItemIEs_t *actionItem;
1651
1652    DU_LOG("\nINFO   -->  E2AP : RIC Subscription request received"); 
1653    ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
1654
1655    for(idx=0; idx<ricSubsReq->protocolIEs.list.count; idx++)
1656    {
1657       if(ricSubsReq->protocolIEs.list.array[idx])
1658       {
1659          switch(ricSubsReq->protocolIEs.list.array[idx]->id)
1660          {
1661             case ProtocolIE_IDE2_id_RICrequestID:
1662                {
1663                   /* TODO :- ricSubscriptionInfo details will be stored based on
1664                    * RAN function id, so first we need to search RAN function and then add
1665                    * subscription details to that ran function */
1666                   DU_ALLOC(ricSubscriptionInfo, sizeof(RicSubscription));
1667                   if(!ricSubscriptionInfo)
1668                   {
1669                      DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for ricSubscriptionInfo");
1670                      return RFAILED;
1671                   }
1672                   ricSubscriptionInfo->requestId.requestorId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID;
1673                   ricSubscriptionInfo->requestId.instanceId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID;
1674                   DU_ALLOC(ricSubscriptionNode, sizeof(CmLList));
1675                   if(ricSubscriptionNode)
1676                   {
1677                      ricSubscriptionNode->node = (PTR) ricSubscriptionInfo;
1678                      cmLListAdd2Tail(&duCb.e2apDb.ranFunction[0].subscriptionList,ricSubscriptionNode);
1679                   }
1680                   break;
1681                }
1682             case ProtocolIE_IDE2_id_RANfunctionID:
1683                {
1684                   duCb.e2apDb.ranFunction[0].id = ricSubsReq->protocolIEs.list.array[idx]-> \
1685                                           value.choice.RANfunctionID; 
1686                   break;
1687                }
1688             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
1689                {
1690                   if(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\
1691                         list.array)
1692                   {
1693                      actionItem =(RICaction_ToBeSetup_ItemIEs_t *)ricSubsReq->protocolIEs.list\
1694                                  .array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List\
1695                                  .list.array[0];
1696
1697                      for(ied = 0; ied < ricSubsReq->protocolIEs.list.array[idx]->value.choice.\
1698                            RICsubscriptionDetails.ricAction_ToBeSetup_List.list.count; ied++)
1699                      {
1700                         switch(actionItem->id)
1701                         {
1702                            case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item:
1703                               {
1704                                  ricSubscriptionInfo->actionSequence[0].id  = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
1705                                  ricSubscriptionInfo->actionSequence[0].type = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType;
1706                                  break;
1707                               }
1708                            default:
1709                               DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id);
1710                               break;
1711                         }
1712                         free(actionItem);
1713                      }
1714                      free(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\
1715                            list.array);
1716
1717 #ifdef KPI_CALCULATION 
1718                      /* This is a dummy trigger for statistics request. It will
1719                       * be removed in next gerrit and actual statistics request
1720                       * will be sent when RIC subscription request is received
1721                       * from RIC */
1722                      ricSubscriptionInfo->actionSequence[0].definition.styleType = 1;
1723                      BuildAndSendStatsReq(ricSubscriptionInfo->actionSequence[0].definition);
1724 #endif
1725                   }
1726                   break;
1727                }
1728
1729             default:
1730                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RIC SubsReq:%ld",
1731                      ricSubsReq->protocolIEs.list.array[idx]->id);
1732                break;
1733          }
1734          free(ricSubsReq->protocolIEs.list.array[idx]);
1735       }
1736    }
1737    free(ricSubsReq->protocolIEs.list.array);
1738    ret = BuildAndSendRicSubscriptionRsp();
1739    {
1740       BuildAndSendRicIndication(ricSubscriptionInfo);
1741    }
1742
1743    return ret;
1744 }
1745
1746 /*******************************************************************
1747  *
1748  * @brief Free the RicIndication Message
1749  *
1750  * @details
1751  *
1752  *    Function : FreeRicIndication
1753  *
1754  * Functionality: Free the RicIndication Message
1755  *
1756  * @return void
1757  *         
1758  *
1759  ******************************************************************/
1760 void FreeRicIndication(E2AP_PDU_t  *e2apMsg) 
1761 {
1762    uint8_t idx=0;
1763    RICindication_t *ricIndicationMsg= NULLP;
1764
1765
1766    if(e2apMsg != NULLP)
1767    {
1768       if(e2apMsg->choice.initiatingMessage != NULLP)
1769       {
1770          ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
1771          if(ricIndicationMsg!= NULLP)
1772          {
1773             if(ricIndicationMsg->protocolIEs.list.array != NULLP)
1774             {
1775                for(idx=0; idx<ricIndicationMsg->protocolIEs.list.count; idx++)
1776                {
1777                   if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP)
1778                   {
1779                      switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
1780                      {
1781                         case ProtocolIE_IDE2_id_RICrequestID:
1782                            break;
1783
1784                         case ProtocolIE_IDE2_id_RANfunctionID:
1785                            break;
1786
1787                         case ProtocolIE_IDE2_id_RICactionID:
1788                            break;
1789
1790                         case ProtocolIE_IDE2_id_RICindicationType:
1791                            break;
1792
1793                         case ProtocolIE_IDE2_id_RICindicationHeader:
1794                            {
1795                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\
1796                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
1797                               break;
1798                            }
1799                         case ProtocolIE_IDE2_id_RICindicationMessage:
1800                            {
1801                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\
1802                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
1803                               break;
1804                            }
1805                         default:
1806                            break;
1807                      }
1808                      DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t));
1809                   }
1810                }
1811                DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size);
1812             }
1813          }
1814          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1815       }
1816       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1817    }
1818 }
1819 /*******************************************************************
1820  *
1821  * brief Fill the RicIndication Message
1822  *
1823  * @details
1824  *
1825  *    Function : FillRicIndication
1826  *
1827  * Functionality:Fills the RicIndication Message
1828  *
1829  * @return ROK     - success
1830  *         RFAILED - failure
1831  *
1832  ******************************************************************/
1833 uint8_t FillRicIndication(RICindication_t *ricIndicationMsg, RicSubscription *ricSubscriptionInfo)
1834 {
1835    uint8_t elementCnt=0;
1836    uint8_t idx=0;
1837    uint8_t ret = ROK;
1838    elementCnt = 6;
1839
1840    ricIndicationMsg->protocolIEs.list.count = elementCnt;
1841    ricIndicationMsg->protocolIEs.list.size  = elementCnt * sizeof(RICindication_t);
1842    /* Initialize the Ric Indication members */
1843    DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, \
1844          ricIndicationMsg->protocolIEs.list.size);
1845    if(ricIndicationMsg->protocolIEs.list.array == NULLP)
1846    {
1847       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1848       ret = RFAILED;
1849    }
1850    else
1851    {
1852       for(idx=0; idx<elementCnt; idx++)
1853       {
1854          DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx],\
1855                sizeof(RICindication_IEs_t));
1856          if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
1857          {
1858             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1859             ret = RFAILED;
1860          }
1861       }
1862       if(ret != RFAILED)
1863       {
1864          idx = 0;
1865
1866          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
1867          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1868          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1869                                                                         RICindication_IEs__value_PR_RICrequestID;
1870          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID =ricSubscriptionInfo->requestId.requestorId;
1871          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID = ricSubscriptionInfo->requestId.instanceId;
1872
1873          idx++;
1874          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
1875          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1876          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1877                                                                         RICindication_IEs__value_PR_RANfunctionID;
1878          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = duCb.e2apDb.ranFunction[0].id;
1879
1880          idx++;
1881          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
1882          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1883          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1884                                                                         RICindication_IEs__value_PR_RICactionID;
1885          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = ricSubscriptionInfo->actionSequence[0].id;
1886
1887          idx++;
1888          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
1889          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1890          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1891                                                                         RICindication_IEs__value_PR_RICindicationType;
1892          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = ricSubscriptionInfo->actionSequence[0].type;
1893
1894          idx++;
1895          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
1896          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1897          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1898                                                                         RICindication_IEs__value_PR_RICindicationHeader;
1899          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size = 3 *
1900             sizeof(uint8_t);
1901          DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf ,\
1902                ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
1903          if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf == NULLP)
1904          {
1905             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1906             ret = RFAILED;
1907          }
1908          else
1909          {
1910             buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
1911                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf);
1912             idx++;
1913             /* TO BE CHANGED: RIC INDICATION DATA */
1914             /* For now filling a dummy octect data, need to tested with PRBs*/
1915             ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
1916             ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1917             ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1918                                                                            RICindication_IEs__value_PR_RICindicationMessage;
1919             ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size = 3 *
1920                sizeof(uint8_t);
1921             DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf ,\
1922                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
1923             if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf == NULLP)
1924             {
1925                DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1926                ret = RFAILED;
1927             }
1928             else
1929             {
1930                buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
1931                      ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf);
1932             }
1933          }
1934       }
1935    }
1936    return ret;
1937 }
1938
1939 /*******************************************************************
1940  *
1941  * @brief Builds and Send the RicIndication Message
1942  *
1943  * @details
1944  *
1945  *    Function : BuildAndSendRicIndication
1946  *
1947  * Functionality:Fills the RicIndication Message
1948  *
1949  * @return ROK     - success
1950  *         RFAILED - failure
1951  *
1952  ******************************************************************/
1953
1954 uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo)
1955 {
1956    E2AP_PDU_t                 *e2apMsg = NULLP;
1957    RICindication_t            *ricIndicationMsg=NULLP;
1958    asn_enc_rval_t             encRetVal;        /* Encoder return value */
1959    uint8_t ret = RFAILED; 
1960    uint8_t FillRicIndicationret = ROK;
1961
1962    while(true)
1963    {
1964       DU_LOG("\nINFO   -->  E2AP : Building RIC Indication Message\n");
1965
1966       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1967       if(e2apMsg == NULLP)
1968       {
1969          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1970          break;
1971       }
1972
1973       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
1974       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1975       if(e2apMsg->choice.initiatingMessage == NULLP)
1976       {
1977          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1978          break;
1979       }
1980       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
1981       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
1982       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication;
1983
1984       ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
1985
1986       FillRicIndicationret = FillRicIndication(ricIndicationMsg, ricSubscriptionInfo);
1987       if(FillRicIndicationret != ROK)
1988       {
1989          break;
1990       }
1991       /* Prints the Msg formed */
1992       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1993       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1994       encBufSize = 0;
1995       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
1996             encBuf);
1997       if(encRetVal.encoded == ENCODE_FAIL)
1998       {
1999          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Indication Message (at %s)\n",\
2000                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2001          break;
2002       }
2003       else
2004       {
2005          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Indication Message \n");
2006 #ifdef DEBUG_ASN_PRINT
2007          for(int i=0; i< encBufSize; i++)
2008          {
2009             printf("%x",encBuf[i]);
2010          } 
2011 #endif
2012       }
2013
2014       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
2015       {
2016          DU_LOG("\nINFO   -->  E2AP : Sending RIC Indication Message");      
2017
2018       }
2019       ret = ROK;
2020       break;
2021    }
2022    FreeRicIndication(e2apMsg);  
2023    return ret;
2024 }
2025
2026 /*******************************************************************
2027  *
2028  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
2029  *
2030  * @details
2031  *
2032  *    Function : FreeE2NodeConfigUpdate 
2033  *
2034  *    Functionality:
2035  *       - freeing the memory allocated for E2nodeConfigurationUpdate
2036  *
2037  * @params[in] E2AP_PDU_t *e2apMsg 
2038  * @return ROK     - success
2039  *         RFAILED - failure
2040  *
2041  * ****************************************************************/
2042 void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg)
2043 {
2044    uint8_t arrIdx =0;
2045    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate;
2046
2047    if(e2apMsg != NULLP)
2048    {
2049       if(e2apMsg->choice.initiatingMessage != NULLP)
2050       {
2051          e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
2052          if(e2NodeConfigUpdate->protocolIEs.list.array != NULLP)
2053          {
2054             for(arrIdx = 0; arrIdx < e2NodeConfigUpdate->protocolIEs.list.count; arrIdx++)
2055             {
2056                DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
2057             }
2058             DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
2059          }
2060          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2061       }
2062       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2063    }
2064 }
2065
2066 /*******************************************************************
2067  *
2068  * @brief Buld and send the E2 node config update msg 
2069  *
2070  * @details
2071  *
2072  *    Function : BuildAndSendE2NodeConfigUpdate
2073  *
2074  *    Functionality:
2075  *         - Buld and send the E2 node config update msg
2076  *
2077  * @params[in] 
2078  * @return ROK     - success
2079  *         RFAILED - failure
2080  *
2081  * ****************************************************************/
2082
2083 uint8_t BuildAndSendE2NodeConfigUpdate()
2084 {
2085    uint8_t arrIdx = 0,elementCnt = 1;
2086    uint8_t ret = ROK;
2087    E2AP_PDU_t        *e2apMsg = NULLP;
2088    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate = NULLP;
2089    asn_enc_rval_t     encRetVal;       /* Encoder return value */
2090
2091    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update\n");
2092    do
2093    {
2094       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2095       if(e2apMsg == NULLP)
2096       {
2097          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2098          break;
2099       }
2100       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
2101       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2102       if(e2apMsg->choice.initiatingMessage == NULLP)
2103       {
2104          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2105          DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2106          return RFAILED;
2107       }
2108       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2109       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
2110       e2apMsg->choice.initiatingMessage->value.present = \
2111       InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate;
2112       e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
2113
2114       e2NodeConfigUpdate->protocolIEs.list.count = elementCnt;
2115       e2NodeConfigUpdate->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdate_IEs_t*);
2116       /* Initialize the Ric Indication members */
2117       DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array, \
2118             e2NodeConfigUpdate->protocolIEs.list.size);
2119       if(e2NodeConfigUpdate->protocolIEs.list.array == NULLP)
2120       {
2121          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
2122          break;
2123       }
2124       
2125       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
2126       {
2127          DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
2128          if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx] == NULLP)
2129          {
2130             
2131             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
2132             break;
2133          }
2134       }
2135
2136       arrIdx = 0;
2137       /* TransactionID */
2138       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2139       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2140       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_TransactionID;
2141       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = TRANS_ID;
2142
2143
2144       /* Prints the Msg formed */
2145       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2146
2147       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2148       encBufSize = 0;
2149       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
2150             encBuf);
2151       if(encRetVal.encoded == ENCODE_FAIL)
2152       {
2153          DU_LOG("\nERROR  -->  E2AP : Could not encode E2nodeConfigurationUpdate structure (at %s)\n",\
2154                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2155          break;
2156       }
2157       else
2158       {
2159          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2nodeConfigurationUpdate\n");
2160 #ifdef DEBUG_ASN_PRINT
2161          for(int i=0; i< encBufSize; i++)
2162          {
2163             printf("%x",encBuf[i]);
2164          }
2165 #endif
2166       }
2167       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize))
2168       {
2169          DU_LOG("\nERROR  -->  E2AP : Sending E2 node config update failed");
2170          return RFAILED;
2171       }
2172
2173       break;
2174    }while(true);
2175    
2176    FreeE2NodeConfigUpdate(e2apMsg);
2177    return ret;
2178 }
2179
2180 /*******************************************************************
2181  *
2182  * @brief Deallocate the memory allocated for E2ResetRequest msg
2183  *
2184  * @details
2185  *
2186  *    Function : FreeE2ResetRequest
2187  *
2188  *    Functionality:
2189  *       - freeing the memory allocated for E2ResetRequest
2190  *
2191  * @params[in] E2AP_PDU_t *e2apMsg
2192  * @return ROK     - success
2193  *         RFAILED - failure
2194  *
2195  * ****************************************************************/
2196 void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg)
2197 {
2198    uint8_t ieIdx =0;
2199    ResetRequestE2_t  *resetReq = NULLP;
2200
2201    if(e2apMsg != NULLP)
2202    {
2203       if(e2apMsg->choice.initiatingMessage != NULLP)
2204       {
2205          resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
2206          if(resetReq->protocolIEs.list.array)
2207          {
2208             for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
2209             {
2210                DU_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
2211             }
2212             DU_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
2213          }
2214          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2215       }
2216       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2217    }
2218 }
2219
2220 /*******************************************************************
2221  *
2222  * @brief Build and send the E2 reset request msg
2223  *
2224  * @details
2225  *
2226  *    Function : BuildAndSendE2ResetRequest
2227  *
2228  *    Functionality:
2229  *         - Buld and send the E2 reset request msg to RIC
2230  *
2231  * @params[in]
2232  * @return ROK     - success
2233  *         RFAILED - failure
2234  *
2235  * ****************************************************************/
2236 uint8_t BuildAndSendE2ResetRequest(E2CauseType failureType, E2Cause failureCause)
2237 {
2238    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
2239    uint8_t ret = RFAILED;
2240    E2AP_PDU_t        *e2apMsg = NULLP;
2241    ResetRequestE2_t  *resetReq = NULLP;
2242    asn_enc_rval_t     encRetVal;       /* Encoder return value */
2243
2244    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Request\n");
2245
2246    do
2247    {
2248       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2249       if(e2apMsg == NULLP)
2250       {
2251          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for E2AP-PDU failed");
2252          break;
2253       }
2254
2255       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
2256       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2257       if(e2apMsg->choice.initiatingMessage == NULLP)
2258       {
2259          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for initiatingMessage");
2260          break;
2261       }
2262
2263       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
2264       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2265       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
2266       resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
2267
2268       elementCnt = 2;
2269       resetReq->protocolIEs.list.count = elementCnt;
2270       resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
2271
2272       DU_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
2273       if(!resetReq->protocolIEs.list.array)
2274       {
2275          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
2276             Reset Request IE array");
2277          break;
2278       }
2279
2280       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
2281       {
2282          DU_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
2283          if(!resetReq->protocolIEs.list.array[ieIdx])
2284          {
2285             DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
2286             Reset Request IE array element");
2287             break;
2288          }
2289       }
2290
2291       /* In case of failure */
2292       if(ieIdx < elementCnt)
2293          break;
2294
2295       ieIdx = 0;
2296       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2297       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
2298       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
2299       transId = assignTransactionId();
2300       resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
2301
2302       ieIdx++;
2303       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
2304       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
2305       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
2306       resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present = failureType;
2307       switch(resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present)
2308       {
2309          case CauseE2_PR_NOTHING:
2310             break;
2311          case CauseE2_PR_ricRequest:
2312             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricRequest = failureCause;
2313             break;
2314          case CauseE2_PR_ricService:
2315             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricService = failureCause;
2316             break;
2317          case CauseE2_PR_e2Node:
2318             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.e2Node = failureCause;
2319             break;
2320          case CauseE2_PR_transport:
2321             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.transport = failureCause;
2322             break;
2323          case CauseE2_PR_protocol:
2324             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.protocol = failureCause;
2325             break;
2326          case CauseE2_PR_misc:
2327             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.misc = failureCause;
2328             break;
2329       }
2330
2331       /* Prints the Msg formed */
2332       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2333
2334       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2335       encBufSize = 0;
2336       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
2337             encBuf);
2338       if(encRetVal.encoded == ENCODE_FAIL)
2339       {
2340          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupRequest structure (at %s)\n",\
2341                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2342          break;
2343       }
2344       else
2345       {
2346          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2SetupRequest\n");
2347 #ifdef DEBUG_ASN_PRINT
2348          for(int i=0; i< encBufSize; i++)
2349          {
2350             printf("%x",encBuf[i]);
2351          }
2352 #endif
2353       }
2354       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
2355       {
2356          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
2357          break;
2358       }
2359
2360       /* In case the message is sent successfully, store the transaction info to
2361        * be used when response is received */
2362       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
2363       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
2364
2365       ret = ROK;
2366       break;
2367    }while(true);
2368
2369    /* Free all memory */
2370    FreeE2ResetRequest(e2apMsg);
2371    return ret;
2372 }
2373
2374 /*******************************************************************
2375  *
2376  * @brief Deallocate the memory allocated for Reset Response msg
2377  *
2378  * @details
2379  *
2380  *    Function : freeAperDecodingOfE2ResetRsp
2381  *
2382  *    Functionality:
2383  *       - freeing the memory allocated for Reset response
2384  *
2385  * @params[in] ResetResponseE2_t *resetResponse
2386  * @return void
2387  *
2388  * ****************************************************************/
2389 void freeAperDecodingOfE2ResetRsp(ResetResponseE2_t *resetResponse)
2390 {
2391    uint8_t ieIdx;
2392
2393    if(resetResponse)
2394    {
2395       if(resetResponse->protocolIEs.list.array)
2396       {
2397          for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
2398          {
2399             if(resetResponse->protocolIEs.list.array[ieIdx])
2400             {
2401                switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
2402                {
2403                   case ProtocolIE_IDE2_id_TransactionID:
2404                      break;
2405
2406                   case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
2407                      break;
2408                }
2409                free(resetResponse->protocolIEs.list.array[ieIdx]);
2410             }
2411          }
2412          free(resetResponse->protocolIEs.list.array);
2413       }
2414    }
2415 }
2416
2417 /******************************************************************
2418  *
2419  * @brief Processes E2 Reset Response sent by RIC
2420  *
2421  * @details
2422  *
2423  *    Function : procResetResponse
2424  *
2425  *    Functionality: Processes E2 Reset Response sent by RIC
2426  *
2427  * @params[in] E2AP_PDU_t ASN decoded E2AP message
2428  * @return ROK     - success
2429  *         RFAILED - failure
2430  *
2431  * ****************************************************************/
2432 uint8_t procResetResponse(E2AP_PDU_t *e2apMsg)
2433 {
2434    uint8_t ieIdx =0, transId;
2435    ResetResponseE2_t *resetResponse;
2436
2437    DU_LOG("\nINFO   -->  E2AP : E2 Reset Response received");
2438    resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;;
2439
2440    for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
2441    {
2442       switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
2443       {
2444          case ProtocolIE_IDE2_id_TransactionID:
2445             transId = resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
2446             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) && \
2447                   (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
2448             {
2449                memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
2450             }
2451             else
2452             {
2453                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
2454                return RFAILED;
2455             }
2456             break;
2457          case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
2458             /* As per ORAN WG3 E2AP spec v3.0, section 9.2.2
2459                Criticality Diagnostics IE is sent by Near-RT RIC when parts of a received message i.e. 
2460                Reset Request in this case, have not been comprehended or were missing, or if the message 
2461                contained logical errors.
2462
2463                Processing of this ID should be implemented when negative call flows are to be supported.
2464              */
2465             break;
2466          default:
2467             DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2 Reset Response : %ld",
2468                   resetResponse->protocolIEs.list.array[ieIdx]->id);
2469             break;
2470       }
2471    }
2472
2473    freeAperDecodingOfE2ResetRsp(resetResponse);
2474    return ROK;
2475 }
2476
2477 /******************************************************************
2478  *
2479  * @brief Deallocation of memory allocated bu aper decoder for e2 setup Failure
2480  *
2481  * @details
2482  *
2483  *    Function : freeAperDecodingOfE2SetupFailure
2484  *
2485  *    Functionality: Deallocation of memory allocated bu aper decoder for e2
2486  *    setup Failure
2487  *
2488  * @params[in] E2setupFailure_t *e2SetupFailure;
2489  * @return void
2490  *
2491  * ****************************************************************/
2492 void freeAperDecodingOfE2SetupFailure(E2setupFailure_t *e2SetupFailure)
2493 {
2494    uint8_t arrIdx;
2495
2496    if(e2SetupFailure)
2497    {
2498       if(e2SetupFailure->protocolIEs.list.array)
2499       {
2500          for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
2501          {
2502             if(e2SetupFailure->protocolIEs.list.array[arrIdx])
2503             {
2504                free(e2SetupFailure->protocolIEs.list.array[arrIdx]);  
2505             }
2506          }
2507          free(e2SetupFailure->protocolIEs.list.array);
2508       }
2509    }
2510 }
2511 /******************************************************************
2512  *
2513  * @brief Processes E2 Setup Failure sent by RIC
2514  *
2515  * @details
2516  *
2517  *    Function : procE2SetupFailure
2518  *
2519  *    Functionality: Processes E2 Setup failure sent by RIC
2520  *
2521  * @params[in] E2AP_PDU_t ASN decoded E2AP message
2522  * @return ROK     - success
2523  *         RFAILED - failure
2524  *
2525  * ****************************************************************/
2526 void procE2SetupFailure(E2AP_PDU_t *e2apMsg)
2527 {
2528    uint8_t arrIdx =0, transId =0, timerValue=0; 
2529    E2setupFailure_t *e2SetupFailure;
2530
2531    DU_LOG("\nINFO   -->  E2AP : E2 Setup failure received"); 
2532    e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
2533
2534    for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
2535    {
2536       switch(e2SetupFailure->protocolIEs.list.array[arrIdx]->id)
2537       {
2538          case ProtocolIE_IDE2_id_TransactionID:
2539          {
2540             transId = e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
2541             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
2542                   (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
2543             {
2544                memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
2545             }
2546             else
2547             {
2548                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
2549                return ;
2550             }
2551             break;
2552          }
2553          case ProtocolIE_IDE2_id_TimeToWaitE2:
2554             {
2555                timerValue = covertE2WaitTimerEnumToValue(e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
2556                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR)) == FALSE)
2557                {
2558                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR, timerValue);
2559                }
2560                else
2561                {
2562                   DU_LOG("\nERROR   -->  E2AP : EVENT_E2_SETUP_TMR timer is already running");
2563                   return;
2564                }
2565                break; 
2566             }
2567       }
2568    }
2569
2570    freeAperDecodingOfE2SetupFailure(e2SetupFailure);
2571 }
2572 /*******************************************************************
2573  *
2574  * @brief Handles received E2AP message and sends back response  
2575  *
2576  * @details
2577  *
2578  *    Function : E2APMsgHdlr
2579  *
2580  *    Functionality:
2581  *         - Decodes received E2AP control message
2582  *         - Prepares response message, encodes and sends to SCTP
2583  *
2584  * @params[in] 
2585  * @return ROK     - success
2586  *         RFAILED - failure
2587  *
2588  * ****************************************************************/
2589 void E2APMsgHdlr(Buffer *mBuf)
2590 {
2591    int i =0;
2592    char *recvBuf = NULLP;
2593    MsgLen copyCnt =0;
2594    MsgLen recvBufLen =0;
2595    E2AP_PDU_t *e2apMsg = NULLP;
2596    asn_dec_rval_t rval ={0}; /* Decoder return value */
2597    E2AP_PDU_t e2apasnmsg={0} ;
2598
2599    DU_LOG("\nDEBUG   -->  E2AP : Received E2AP message buffer");
2600    ODU_PRINT_MSG(mBuf, 0,0);
2601
2602    /* Copy mBuf into char array to decode it */
2603    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
2604    DU_ALLOC(recvBuf, (Size)recvBufLen);
2605
2606    if(recvBuf == NULLP)
2607    {
2608       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
2609       return;
2610    }
2611    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
2612    {
2613       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
2614       return;
2615    }
2616
2617 #ifdef DEBUG_ASN_PRINT
2618    printf("\nDEBUG   -->  E2AP : Received flat buffer to be decoded : ");
2619    for(i=0; i< recvBufLen; i++)
2620    {
2621       printf("%x",recvBuf[i]);
2622    }
2623 #endif
2624
2625    /* Decoding flat buffer into E2AP messsage */
2626    e2apMsg = &e2apasnmsg;
2627    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
2628
2629    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
2630    DU_FREE(recvBuf, (Size)recvBufLen);
2631
2632    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
2633    {
2634       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
2635       return;
2636    }
2637    printf("\n");
2638    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2639
2640    switch(e2apMsg->present)
2641    {
2642       case E2AP_PDU_PR_unsuccessfulOutcome:
2643          {
2644             switch(e2apMsg->choice.unsuccessfulOutcome->value.present)
2645             {
2646                case UnsuccessfulOutcomeE2__value_PR_E2setupFailure:
2647                   {
2648                      procE2SetupFailure(e2apMsg);
2649                      break;
2650                   }
2651                default:
2652                   {
2653                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome  [%d]",\
2654                            e2apMsg->choice.unsuccessfulOutcome->value.present);
2655                      return;
2656                   }
2657             }
2658             break;
2659          }
2660       case E2AP_PDU_PR_successfulOutcome:
2661          {
2662             switch(e2apMsg->choice.successfulOutcome->value.present)
2663             {
2664                case SuccessfulOutcomeE2__value_PR_E2setupResponse:
2665                   {
2666                      if(!duCb.e2Status)
2667                      {
2668                         procE2SetupRsp(e2apMsg);
2669                      }
2670                      break;
2671                   }
2672                case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge:
2673                   {
2674                      DU_LOG("\nDEBUG   -->  E2AP : E2 node Config update ack message recevied");
2675                      break;
2676                   }
2677                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
2678                   {
2679                      procResetResponse(e2apMsg);
2680                      break;
2681                   }
2682                default:
2683                   {
2684                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome  [%d]",\
2685                            e2apMsg->choice.successfulOutcome->value.present);
2686                      return;
2687                   }
2688             }/* End of switch(successfulOutcome) */
2689             free(e2apMsg->choice.successfulOutcome);
2690             break;
2691          }
2692
2693       case E2AP_PDU_PR_initiatingMessage:
2694          {
2695             switch(e2apMsg->choice.initiatingMessage->value.present)
2696             {
2697                case InitiatingMessageE2__value_PR_RICsubscriptionRequest: 
2698                   {
2699                      procRicSubsReq(e2apMsg);
2700                      break;
2701                   }
2702                default:
2703                   {
2704                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\
2705                            e2apMsg->choice.initiatingMessage->value.present);
2706                      return;
2707                   }
2708             }/* End of switch(initiatingMessage) */
2709             free(e2apMsg->choice.initiatingMessage);
2710             break;
2711          }
2712       default:
2713          {
2714             DU_LOG("\nERROR  -->  E2AP : Invalid type of e2apMsg->present [%d]",e2apMsg->present);
2715             return;
2716          }
2717          free(e2apMsg);
2718
2719    }/* End of switch(e2apMsg->present) */
2720
2721 } /* End of E2APMsgHdlr */
2722
2723 /**********************************************************************
2724   End of file
2725  **********************************************************************/