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