a8ea182a387e201f710e60ead57c9e4327fb5283
[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                   if(duCb.e2apDb.ranFunction[ranFuncId-1].id == ranFuncId)
2300                   {
2301                      ranFuncDb = &duCb.e2apDb.ranFunction[ranFuncId-1];
2302
2303                      if(ranFuncDb->numPendingSubsRsp >= MAX_PENDING_SUBSCRIPTION_RSP)
2304                      {
2305                         failureCause.causeType = E2_RIC_REQUEST;
2306                         failureCause.cause = E2_FUNCTION_RESOURCE_LIMIT; 
2307                         ret = RFAILED;
2308                         break;
2309                      }
2310
2311                      DU_ALLOC(ricSubscriptionInfo, sizeof(RicSubscription));
2312                      if(!ricSubscriptionInfo)
2313                      {
2314                         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for ricSubscriptionInfo");
2315                         failureCause.causeType = E2_MISCELLANEOUS;
2316                         failureCause.cause = E2_MISCELLANEOUS_CAUSE_UNSPECIFIED;
2317                         ret = RFAILED;
2318                         break;
2319                      }
2320                      ricSubscriptionInfo->requestId.requestorId = ricReqId.requestorId;
2321                      ricSubscriptionInfo->requestId.instanceId = ricReqId.instanceId;
2322
2323                      memset(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp], 0, sizeof(PendingSubsRspInfo));
2324                      memcpy(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp].requestId, 
2325                      &ricReqId, sizeof(RicRequestId));
2326                      ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp].ranFuncId = ranFuncId;
2327                   }
2328                   else
2329                   {
2330                      failureCause.causeType = E2_RIC_REQUEST;
2331                      failureCause.cause = E2_RAN_FUNCTION_ID_INVALID;
2332                      ret = RFAILED;
2333                   }
2334                   break;
2335                }
2336
2337             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
2338                {
2339                   subsDetails = &ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails;
2340
2341                   /* Decode, Validate and record Event Trigger Definition */
2342                   if(extractEventTriggerDef(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricEventTriggerDefinition, \
2343                      &failureCause) != ROK)
2344                   {
2345                      ret = RFAILED;
2346                      break;
2347                   }
2348
2349                   /* Decode, Validate and record RIC actions */
2350                   if(extractRicActionToBeSetup(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricAction_ToBeSetup_List, \
2351                      &failureCause, &ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp]) != ROK)
2352                   {
2353                      ret = RFAILED;
2354                      break;
2355                   }
2356                }
2357                break;
2358
2359             default:
2360                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RIC SubsReq:%ld",
2361                      ricSubsReq->protocolIEs.list.array[idx]->id);
2362                break;
2363          }
2364
2365          if(ret == RFAILED)
2366             break;
2367       }
2368    }
2369
2370    freeAperDecodingOfRicSubsReq(ricSubsReq);
2371
2372    if(ret == ROK)
2373    {
2374       /* Add RAN subcription detail to RAN function */
2375       DU_ALLOC(ricSubscriptionNode, sizeof(CmLList));
2376       if(ricSubscriptionNode)
2377       {
2378          ricSubscriptionNode->node = (PTR) ricSubscriptionInfo;
2379          cmLListAdd2Tail(&ranFuncDb->subscriptionList, ricSubscriptionNode);
2380       }
2381
2382       ranFuncDb->numPendingSubsRsp++;
2383
2384 #ifdef KPI_CALCULATION
2385       /* Send statistics request to other DU entities */
2386       BuildAndSendStatsReq(ranFuncId, ricSubscriptionInfo);
2387 #endif      
2388
2389       /* TODO : Trigger RIC Indication once statistics indication is
2390        * received from MAC . 
2391        * TBD in future gerrit */
2392        //BuildAndSendRicIndication(ricSubscriptionInfo);
2393    }
2394    else
2395    {
2396       DU_FREE(ricSubscriptionInfo, sizeof(RicSubscription));
2397
2398       if(ranFuncDb)
2399       {
2400          memset(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp], 0, sizeof(PendingSubsRspInfo));
2401       }
2402
2403       /* Send RIC Subcription Failure */
2404       BuildAndSendRicSubscriptionFailure(ricReqId, ranFuncId, failureCause);
2405    }
2406
2407    return ret;
2408 }
2409
2410 /******************************************************************
2411  *
2412  * @brief Free RIC Subscription Failure
2413  *
2414  * @details
2415  *
2416  *    Function : FreeRicSubscriptionFailure
2417  *
2418  *    Functionality: Free RIC Subscription Failure
2419  *
2420  * @params[in] E2AP PDU
2421  * @return void
2422  *
2423  * ****************************************************************/
2424 void FreeRicSubscriptionFailure(E2AP_PDU_t *e2apMsg)
2425 {
2426    uint8_t elemIdx = 0;
2427    RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP;
2428
2429    if(e2apMsg)
2430    {
2431       if(e2apMsg->choice.unsuccessfulOutcome)
2432       {
2433          ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
2434          if(ricSubscriptionFailure->protocolIEs.list.array)
2435          {
2436             for(elemIdx = 0; elemIdx < ricSubscriptionFailure->protocolIEs.list.count; elemIdx++)
2437             {
2438                DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t));
2439             }
2440             DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size);
2441          }
2442          DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
2443       }
2444       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2445    }
2446 }
2447
2448 /******************************************************************
2449  *
2450  * @brief Fill and Send RIC Subscription Failure to RIC
2451  *
2452  * @details
2453  *
2454  *    Function : BuildAndSendRicSubscriptionFailure
2455  *
2456  *    Functionality: Fill and Send RIC Subscription Failure to RIC
2457  *
2458  * @params[in] RIC Request ID
2459  *             RAN Function ID
2460  *             Cause of Failure
2461  * @return ROK     - success
2462  *         RFAILED - failure
2463  *
2464  * ****************************************************************/
2465 uint8_t BuildAndSendRicSubscriptionFailure(RicRequestId ricReqId, uint16_t ranFuncId, E2FailureCause failureCause)
2466 {
2467    uint8_t          ret = RFAILED;
2468    uint8_t          elementCnt = 0, elemIdx = 0;
2469    E2AP_PDU_t       *e2apMsg = NULLP;
2470    asn_enc_rval_t   encRetVal;        /* Encoder return value */
2471    RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP;
2472    RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
2473
2474    while(true)
2475    {
2476       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Failure\n");
2477
2478       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2479       if(e2apMsg == NULLP)
2480       {
2481          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
2482          break;
2483       }
2484
2485       e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome;
2486       DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
2487       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
2488       {
2489          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
2490          break;
2491       }
2492       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
2493       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
2494       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure;
2495
2496       ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
2497
2498       elementCnt = 3;
2499       ricSubscriptionFailure->protocolIEs.list.count = elementCnt;
2500       ricSubscriptionFailure->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionFailure_IEs_t *);
2501       DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size);
2502       if(!ricSubscriptionFailure->protocolIEs.list.array)
2503       {
2504          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
2505          break;
2506       }
2507
2508       for(elemIdx = 0; elemIdx < elementCnt; elemIdx++)
2509       {
2510          DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t));
2511          if(!ricSubscriptionFailure->protocolIEs.list.array[elemIdx])
2512          {
2513             DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d] for IE at index [%d]", \
2514                __func__, __LINE__, elemIdx);
2515             break;
2516          }
2517       }
2518       if(elemIdx < elementCnt)
2519          break;
2520
2521       elemIdx = 0;
2522
2523       /* RIC Request ID */
2524       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
2525       ricSubsFailIe->id = ProtocolIE_IDE2_id_RICrequestID;
2526       ricSubsFailIe->criticality = CriticalityE2_reject;
2527       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RICrequestID;
2528       ricSubsFailIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
2529       ricSubsFailIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
2530
2531       /* RAN Function ID */
2532       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
2533       ricSubsFailIe->id = ProtocolIE_IDE2_id_RANfunctionID;
2534       ricSubsFailIe->criticality = CriticalityE2_reject;
2535       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RANfunctionID;
2536       ricSubsFailIe->value.choice.RANfunctionID = ranFuncId;
2537
2538       /* Cause */
2539       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
2540       ricSubsFailIe->id = ProtocolIE_IDE2_id_CauseE2;
2541       ricSubsFailIe->criticality = CriticalityE2_reject;
2542       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_CauseE2;
2543       fillE2Cause(&ricSubsFailIe->value.choice.CauseE2, failureCause);
2544
2545       /* Prints the Msg formed */
2546       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2547       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2548       encBufSize = 0;
2549       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2550       if(encRetVal.encoded == ENCODE_FAIL)
2551       {
2552          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Failure Message (at %s)\n",\
2553                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2554          break;
2555       }
2556       else
2557       {
2558          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Failure Message \n");
2559 #ifdef DEBUG_ASN_PRINT
2560          for(int i=0; i< encBufSize; i++)
2561          {
2562             printf("%x",encBuf[i]);
2563          }
2564 #endif
2565       }
2566
2567       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
2568       {
2569          DU_LOG("\nINFO   -->  E2AP : Sending RIC Subscription Failure");
2570
2571       }
2572       ret = ROK;
2573       break;
2574    }
2575    FreeRicSubscriptionFailure(e2apMsg);
2576    return ret;
2577 }
2578
2579 /*******************************************************************
2580  *
2581  * @brief Free the RicIndication Message
2582  *
2583  * @details
2584  *
2585  *    Function : FreeRicIndication
2586  *
2587  * Functionality: Free the RicIndication Message
2588  *
2589  * @return void
2590  *         
2591  *
2592  ******************************************************************/
2593 void FreeRicIndication(E2AP_PDU_t  *e2apMsg) 
2594 {
2595    uint8_t idx = 0;
2596    RICindication_t *ricIndicationMsg= NULLP;
2597
2598    if(e2apMsg != NULLP)
2599    {
2600       if(e2apMsg->choice.initiatingMessage != NULLP)
2601       {
2602          ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
2603          if(ricIndicationMsg!= NULLP)
2604          {
2605             if(ricIndicationMsg->protocolIEs.list.array != NULLP)
2606             {
2607                for(idx=0; idx<ricIndicationMsg->protocolIEs.list.count; idx++)
2608                {
2609                   if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP)
2610                   {
2611                      switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
2612                      {
2613                         case ProtocolIE_IDE2_id_RICrequestID:
2614                            break;
2615
2616                         case ProtocolIE_IDE2_id_RANfunctionID:
2617                            break;
2618
2619                         case ProtocolIE_IDE2_id_RICactionID:
2620                            break;
2621
2622                         case ProtocolIE_IDE2_id_RICindicationType:
2623                            break;
2624
2625                         case ProtocolIE_IDE2_id_RICindicationHeader:
2626                            {
2627                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\
2628                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
2629                               break;
2630                            }
2631                         case ProtocolIE_IDE2_id_RICindicationMessage:
2632                            {
2633                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\
2634                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
2635                               break;
2636                            }
2637                         default:
2638                            break;
2639                      }
2640                      DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t));
2641                   }
2642                }
2643                DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size);
2644             }
2645          }
2646          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2647       }
2648       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2649    }
2650 }
2651
2652 /*******************************************************************
2653  *
2654  * brief Fill the RicIndication Message
2655  *
2656  * @details
2657  *
2658  *    Function : FillRicIndication
2659  *
2660  * Functionality:Fills the RicIndication Message
2661  *
2662  * @return ROK     - success
2663  *         RFAILED - failure
2664  *
2665  ******************************************************************/
2666 uint8_t FillRicIndication(RICindication_t *ricIndicationMsg, RicSubscription *ricSubscriptionInfo)
2667 {
2668    uint8_t elementCnt=0;
2669    uint8_t idx=0;
2670    uint8_t ret = ROK;
2671    elementCnt = 6;
2672
2673    ricIndicationMsg->protocolIEs.list.count = elementCnt;
2674    ricIndicationMsg->protocolIEs.list.size  = elementCnt * sizeof(RICindication_t);
2675    /* Initialize the Ric Indication members */
2676    DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, \
2677          ricIndicationMsg->protocolIEs.list.size);
2678    if(ricIndicationMsg->protocolIEs.list.array == NULLP)
2679    {
2680       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
2681       ret = RFAILED;
2682    }
2683    else
2684    {
2685       for(idx=0; idx<elementCnt; idx++)
2686       {
2687          DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx],\
2688                sizeof(RICindication_IEs_t));
2689          if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
2690          {
2691             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
2692             ret = RFAILED;
2693          }
2694       }
2695       if(ret != RFAILED)
2696       {
2697          idx = 0;
2698
2699          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
2700          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2701          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
2702                                                                         RICindication_IEs__value_PR_RICrequestID;
2703          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID =ricSubscriptionInfo->requestId.requestorId;
2704          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID = ricSubscriptionInfo->requestId.instanceId;
2705
2706          idx++;
2707          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
2708          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2709          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
2710                                                                         RICindication_IEs__value_PR_RANfunctionID;
2711          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = duCb.e2apDb.ranFunction[0].id;
2712
2713          idx++;
2714          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
2715          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2716          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
2717                                                                         RICindication_IEs__value_PR_RICactionID;
2718          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = ricSubscriptionInfo->actionSequence[0].id;
2719
2720          idx++;
2721          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
2722          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2723          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
2724                                                                         RICindication_IEs__value_PR_RICindicationType;
2725          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = ricSubscriptionInfo->actionSequence[0].type;
2726
2727          idx++;
2728          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
2729          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2730          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
2731                                                                         RICindication_IEs__value_PR_RICindicationHeader;
2732          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size = 3 *
2733             sizeof(uint8_t);
2734          DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf ,\
2735                ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
2736          if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf == NULLP)
2737          {
2738             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
2739             ret = RFAILED;
2740          }
2741          else
2742          {
2743             buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
2744                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf);
2745             idx++;
2746             /* TO BE CHANGED: RIC INDICATION DATA */
2747             /* For now filling a dummy octect data, need to tested with PRBs*/
2748             ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
2749             ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2750             ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
2751                                                                            RICindication_IEs__value_PR_RICindicationMessage;
2752             ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size = 3 *
2753                sizeof(uint8_t);
2754             DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf ,\
2755                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
2756             if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf == NULLP)
2757             {
2758                DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
2759                ret = RFAILED;
2760             }
2761             else
2762             {
2763                buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
2764                      ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf);
2765             }
2766          }
2767       }
2768    }
2769    return ret;
2770 }
2771
2772 /*******************************************************************
2773  *
2774  * @brief Builds and Send the RicIndication Message
2775  *
2776  * @details
2777  *
2778  *    Function : BuildAndSendRicIndication
2779  *
2780  * Functionality:Fills the RicIndication Message
2781  *
2782  * @return ROK     - success
2783  *         RFAILED - failure
2784  *
2785  ******************************************************************/
2786
2787 uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo)
2788 {
2789    E2AP_PDU_t                 *e2apMsg = NULLP;
2790    RICindication_t            *ricIndicationMsg=NULLP;
2791    asn_enc_rval_t             encRetVal;        /* Encoder return value */
2792    uint8_t ret = RFAILED; 
2793    uint8_t FillRicIndicationret = ROK;
2794
2795    while(true)
2796    {
2797       DU_LOG("\nINFO   -->  E2AP : Building RIC Indication Message\n");
2798
2799       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2800       if(e2apMsg == NULLP)
2801       {
2802          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2803          break;
2804       }
2805
2806       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
2807       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2808       if(e2apMsg->choice.initiatingMessage == NULLP)
2809       {
2810          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2811          break;
2812       }
2813       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
2814       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2815       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication;
2816
2817       ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
2818
2819       FillRicIndicationret = FillRicIndication(ricIndicationMsg, ricSubscriptionInfo);
2820       if(FillRicIndicationret != ROK)
2821       {
2822          break;
2823       }
2824       /* Prints the Msg formed */
2825       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2826       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2827       encBufSize = 0;
2828       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
2829             encBuf);
2830       if(encRetVal.encoded == ENCODE_FAIL)
2831       {
2832          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Indication Message (at %s)\n",\
2833                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2834          break;
2835       }
2836       else
2837       {
2838          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Indication Message \n");
2839 #ifdef DEBUG_ASN_PRINT
2840          for(int i=0; i< encBufSize; i++)
2841          {
2842             printf("%x",encBuf[i]);
2843          } 
2844 #endif
2845       }
2846
2847       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
2848       {
2849          DU_LOG("\nINFO   -->  E2AP : Sending RIC Indication Message");      
2850
2851       }
2852       ret = ROK;
2853       break;
2854    }
2855    FreeRicIndication(e2apMsg);  
2856    return ret;
2857 }
2858
2859 /*******************************************************************
2860  *
2861  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
2862  *
2863  * @details
2864  *
2865  *    Function : FreeE2NodeConfigUpdate 
2866  *
2867  *    Functionality:
2868  *       - freeing the memory allocated for E2nodeConfigurationUpdate
2869  *
2870  * @params[in] E2AP_PDU_t *e2apMsg 
2871  * @return ROK     - success
2872  *         RFAILED - failure
2873  *
2874  * ****************************************************************/
2875 void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg)
2876 {
2877    uint8_t arrIdx =0;
2878    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate;
2879
2880    if(e2apMsg != NULLP)
2881    {
2882       if(e2apMsg->choice.initiatingMessage != NULLP)
2883       {
2884          e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
2885          if(e2NodeConfigUpdate->protocolIEs.list.array != NULLP)
2886          {
2887             for(arrIdx = 0; arrIdx < e2NodeConfigUpdate->protocolIEs.list.count; arrIdx++)
2888             {
2889                DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
2890             }
2891             DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
2892          }
2893          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2894       }
2895       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2896    }
2897 }
2898
2899 /*******************************************************************
2900  *
2901  * @brief Buld and send the E2 node config update msg 
2902  *
2903  * @details
2904  *
2905  *    Function : BuildAndSendE2NodeConfigUpdate
2906  *
2907  *    Functionality:
2908  *         - Buld and send the E2 node config update msg
2909  *
2910  * @params[in] 
2911  * @return ROK     - success
2912  *         RFAILED - failure
2913  *
2914  * ****************************************************************/
2915
2916 uint8_t BuildAndSendE2NodeConfigUpdate()
2917 {
2918    uint8_t arrIdx = 0,elementCnt = 1;
2919    uint8_t ret = ROK;
2920    E2AP_PDU_t        *e2apMsg = NULLP;
2921    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate = NULLP;
2922    asn_enc_rval_t     encRetVal;       /* Encoder return value */
2923
2924    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update\n");
2925    do
2926    {
2927       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2928       if(e2apMsg == NULLP)
2929       {
2930          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2931          break;
2932       }
2933       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
2934       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2935       if(e2apMsg->choice.initiatingMessage == NULLP)
2936       {
2937          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2938          DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2939          return RFAILED;
2940       }
2941       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2942       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
2943       e2apMsg->choice.initiatingMessage->value.present = \
2944       InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate;
2945       e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
2946
2947       e2NodeConfigUpdate->protocolIEs.list.count = elementCnt;
2948       e2NodeConfigUpdate->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdate_IEs_t*);
2949       /* Initialize the Ric Indication members */
2950       DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array, \
2951             e2NodeConfigUpdate->protocolIEs.list.size);
2952       if(e2NodeConfigUpdate->protocolIEs.list.array == NULLP)
2953       {
2954          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
2955          break;
2956       }
2957       
2958       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
2959       {
2960          DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
2961          if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx] == NULLP)
2962          {
2963             
2964             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
2965             break;
2966          }
2967       }
2968
2969       arrIdx = 0;
2970       /* TransactionID */
2971       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2972       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2973       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_TransactionID;
2974       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = TRANS_ID;
2975
2976
2977       /* Prints the Msg formed */
2978       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2979
2980       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2981       encBufSize = 0;
2982       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
2983             encBuf);
2984       if(encRetVal.encoded == ENCODE_FAIL)
2985       {
2986          DU_LOG("\nERROR  -->  E2AP : Could not encode E2nodeConfigurationUpdate structure (at %s)\n",\
2987                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2988          break;
2989       }
2990       else
2991       {
2992          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2nodeConfigurationUpdate\n");
2993 #ifdef DEBUG_ASN_PRINT
2994          for(int i=0; i< encBufSize; i++)
2995          {
2996             printf("%x",encBuf[i]);
2997          }
2998 #endif
2999       }
3000       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize))
3001       {
3002          DU_LOG("\nERROR  -->  E2AP : Sending E2 node config update failed");
3003          return RFAILED;
3004       }
3005
3006       break;
3007    }while(true);
3008    
3009    FreeE2NodeConfigUpdate(e2apMsg);
3010    return ret;
3011 }
3012
3013 /*******************************************************************
3014  *
3015  * @brief Deallocate the memory allocated for E2ResetRequest msg
3016  *
3017  * @details
3018  *
3019  *    Function : FreeE2ResetRequest
3020  *
3021  *    Functionality:
3022  *       - freeing the memory allocated for E2ResetRequest
3023  *
3024  * @params[in] E2AP_PDU_t *e2apMsg
3025  * @return ROK     - success
3026  *         RFAILED - failure
3027  *
3028  * ****************************************************************/
3029 void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg)
3030 {
3031    uint8_t ieIdx =0;
3032    ResetRequestE2_t  *resetReq = NULLP;
3033
3034    if(e2apMsg != NULLP)
3035    {
3036       if(e2apMsg->choice.initiatingMessage != NULLP)
3037       {
3038          resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
3039          if(resetReq->protocolIEs.list.array)
3040          {
3041             for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
3042             {
3043                DU_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
3044             }
3045             DU_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
3046          }
3047          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3048       }
3049       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3050    }
3051 }
3052
3053 /*******************************************************************
3054  *
3055  * @brief Build and send the E2 reset request msg
3056  *
3057  * @details
3058  *
3059  *    Function : BuildAndSendE2ResetRequest
3060  *
3061  *    Functionality:
3062  *         - Buld and send the E2 reset request msg to RIC
3063  *
3064  * @params[in]
3065  * @return ROK     - success
3066  *         RFAILED - failure
3067  *
3068  * ****************************************************************/
3069 uint8_t BuildAndSendE2ResetRequest(E2FailureCause resetCause)
3070 {
3071    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
3072    uint8_t ret = RFAILED;
3073    E2AP_PDU_t        *e2apMsg = NULLP;
3074    ResetRequestE2_t  *resetReq = NULLP;
3075    asn_enc_rval_t     encRetVal;       /* Encoder return value */
3076
3077    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Request\n");
3078
3079    do
3080    {
3081       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3082       if(e2apMsg == NULLP)
3083       {
3084          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for E2AP-PDU failed");
3085          break;
3086       }
3087
3088       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
3089       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3090       if(e2apMsg->choice.initiatingMessage == NULLP)
3091       {
3092          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for initiatingMessage");
3093          break;
3094       }
3095
3096       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
3097       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
3098       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
3099       resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
3100
3101       elementCnt = 2;
3102       resetReq->protocolIEs.list.count = elementCnt;
3103       resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
3104
3105       DU_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
3106       if(!resetReq->protocolIEs.list.array)
3107       {
3108          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
3109             Reset Request IE array");
3110          break;
3111       }
3112
3113       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
3114       {
3115          DU_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
3116          if(!resetReq->protocolIEs.list.array[ieIdx])
3117          {
3118             DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
3119             Reset Request IE array element");
3120             break;
3121          }
3122       }
3123
3124       /* In case of failure */
3125       if(ieIdx < elementCnt)
3126          break;
3127
3128       ieIdx = 0;
3129       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
3130       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
3131       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
3132       transId = assignTransactionId();
3133       resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
3134
3135       ieIdx++;
3136       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
3137       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
3138       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
3139       fillE2Cause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, resetCause);
3140
3141       /* Prints the Msg formed */
3142       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3143
3144       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3145       encBufSize = 0;
3146       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
3147             encBuf);
3148       if(encRetVal.encoded == ENCODE_FAIL)
3149       {
3150          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupRequest structure (at %s)\n",\
3151                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3152          break;
3153       }
3154       else
3155       {
3156          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2SetupRequest\n");
3157 #ifdef DEBUG_ASN_PRINT
3158          for(int i=0; i< encBufSize; i++)
3159          {
3160             printf("%x",encBuf[i]);
3161          }
3162 #endif
3163       }
3164       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
3165       {
3166          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
3167          break;
3168       }
3169
3170       /* In case the message is sent successfully, store the transaction info to
3171        * be used when response is received */
3172       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
3173       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
3174
3175       ret = ROK;
3176       break;
3177    }while(true);
3178
3179    /* Free all memory */
3180    FreeE2ResetRequest(e2apMsg);
3181    return ret;
3182 }
3183
3184 /*******************************************************************
3185  *
3186  * @brief Deallocate the memory allocated for Reset Response msg
3187  *
3188  * @details
3189  *
3190  *    Function : freeAperDecodingOfE2ResetRsp
3191  *
3192  *    Functionality:
3193  *       - freeing the memory allocated for Reset response
3194  *
3195  * @params[in] ResetResponseE2_t *resetResponse
3196  * @return void
3197  *
3198  * ****************************************************************/
3199 void freeAperDecodingOfE2ResetRsp(ResetResponseE2_t *resetResponse)
3200 {
3201    uint8_t ieIdx;
3202
3203    if(resetResponse)
3204    {
3205       if(resetResponse->protocolIEs.list.array)
3206       {
3207          for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
3208          {
3209             if(resetResponse->protocolIEs.list.array[ieIdx])
3210             {
3211                switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
3212                {
3213                   case ProtocolIE_IDE2_id_TransactionID:
3214                      break;
3215
3216                   case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
3217                      break;
3218                }
3219                free(resetResponse->protocolIEs.list.array[ieIdx]);
3220             }
3221          }
3222          free(resetResponse->protocolIEs.list.array);
3223       }
3224    }
3225 }
3226
3227 /******************************************************************
3228  *
3229  * @brief Processes E2 Reset Response sent by RIC
3230  *
3231  * @details
3232  *
3233  *    Function : procResetResponse
3234  *
3235  *    Functionality: Processes E2 Reset Response sent by RIC
3236  *
3237  * @params[in] E2AP_PDU_t ASN decoded E2AP message
3238  * @return ROK     - success
3239  *         RFAILED - failure
3240  *
3241  * ****************************************************************/
3242 uint8_t procResetResponse(E2AP_PDU_t *e2apMsg)
3243 {
3244    uint8_t ieIdx =0, transId;
3245    ResetResponseE2_t *resetResponse;
3246
3247    DU_LOG("\nINFO   -->  E2AP : E2 Reset Response received");
3248    resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;;
3249
3250    for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
3251    {
3252       switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
3253       {
3254          case ProtocolIE_IDE2_id_TransactionID:
3255             transId = resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
3256             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) && \
3257                   (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
3258             {
3259                memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
3260             }
3261             else
3262             {
3263                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
3264                return RFAILED;
3265             }
3266             break;
3267          case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
3268             /* As per ORAN WG3 E2AP spec v3.0, section 9.2.2
3269                Criticality Diagnostics IE is sent by Near-RT RIC when parts of a received message i.e. 
3270                Reset Request in this case, have not been comprehended or were missing, or if the message 
3271                contained logical errors.
3272
3273                Processing of this ID should be implemented when negative call flows are to be supported.
3274              */
3275             break;
3276          default:
3277             DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2 Reset Response : %ld",
3278                   resetResponse->protocolIEs.list.array[ieIdx]->id);
3279             break;
3280       }
3281    }
3282
3283    freeAperDecodingOfE2ResetRsp(resetResponse);
3284    return ROK;
3285 }
3286
3287 /******************************************************************
3288  *
3289  * @brief Deallocation of memory allocated bu aper decoder for e2 setup Failure
3290  *
3291  * @details
3292  *
3293  *    Function : freeAperDecodingOfE2SetupFailure
3294  *
3295  *    Functionality: Deallocation of memory allocated bu aper decoder for e2
3296  *    setup Failure
3297  *
3298  * @params[in] E2setupFailure_t *e2SetupFailure;
3299  * @return void
3300  *
3301  * ****************************************************************/
3302 void freeAperDecodingOfE2SetupFailure(E2setupFailure_t *e2SetupFailure)
3303 {
3304    uint8_t arrIdx;
3305
3306    if(e2SetupFailure)
3307    {
3308       if(e2SetupFailure->protocolIEs.list.array)
3309       {
3310          for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
3311          {
3312             if(e2SetupFailure->protocolIEs.list.array[arrIdx])
3313             {
3314                free(e2SetupFailure->protocolIEs.list.array[arrIdx]);  
3315             }
3316          }
3317          free(e2SetupFailure->protocolIEs.list.array);
3318       }
3319    }
3320 }
3321 /******************************************************************
3322  *
3323  * @brief Processes E2 Setup Failure sent by RIC
3324  *
3325  * @details
3326  *
3327  *    Function : procE2SetupFailure
3328  *
3329  *    Functionality: Processes E2 Setup failure sent by RIC
3330  *
3331  * @params[in] E2AP_PDU_t ASN decoded E2AP message
3332  * @return ROK     - success
3333  *         RFAILED - failure
3334  *
3335  * ****************************************************************/
3336 void procE2SetupFailure(E2AP_PDU_t *e2apMsg)
3337 {
3338    uint8_t arrIdx =0, transId =0, timerValue=0; 
3339    E2setupFailure_t *e2SetupFailure;
3340
3341    DU_LOG("\nINFO   -->  E2AP : E2 Setup failure received"); 
3342    e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
3343
3344    for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
3345    {
3346       switch(e2SetupFailure->protocolIEs.list.array[arrIdx]->id)
3347       {
3348          case ProtocolIE_IDE2_id_TransactionID:
3349          {
3350             transId = e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
3351             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
3352                   (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
3353             {
3354                memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
3355             }
3356             else
3357             {
3358                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
3359                return ;
3360             }
3361             break;
3362          }
3363          case ProtocolIE_IDE2_id_TimeToWaitE2:
3364             {
3365                timerValue = covertE2WaitTimerEnumToValue(e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
3366                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR)) == FALSE)
3367                {
3368                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR, timerValue);
3369                }
3370                else
3371                {
3372                   DU_LOG("\nERROR   -->  E2AP : EVENT_E2_SETUP_TMR timer is already running");
3373                   return;
3374                }
3375                break; 
3376             }
3377       }
3378    }
3379
3380    freeAperDecodingOfE2SetupFailure(e2SetupFailure);
3381 }
3382 /******************************************************************
3383  *
3384  * @brief Deallocation of memory allocated bu aper decoder for RIC service Query
3385  *
3386  * @details
3387  *
3388  *    Function : freeAperDecodingOfRicServiceQuery
3389  *
3390  *    Functionality: Deallocation of memory allocated bu aper decoder for RIC
3391  *    service Query
3392  *
3393  * @params[in] RICserviceQuery_t *ricServiceQuery;
3394  * @return void
3395  *
3396  * ****************************************************************/
3397
3398 void freeAperDecodingOfRicServiceQuery(RICserviceQuery_t *ricServiceQuery)
3399 {
3400    uint8_t arrIdx,ranFuncIdx;
3401     RANfunctionsID_List_t *ranFuncAddedList;
3402
3403    if(ricServiceQuery)
3404    {
3405       if(ricServiceQuery->protocolIEs.list.array)
3406       {
3407          for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
3408          {
3409             if(ricServiceQuery->protocolIEs.list.array[arrIdx])
3410             {
3411                switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
3412                {
3413                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
3414                   {
3415                      ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
3416                      if(ranFuncAddedList->list.array)
3417                      {
3418                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
3419                         {
3420                            free(ranFuncAddedList->list.array[ranFuncIdx]);
3421                         }
3422                         free(ranFuncAddedList->list.array);;
3423                      }
3424                      break;
3425                   }
3426                   default:
3427                      break;
3428                }
3429                free(ricServiceQuery->protocolIEs.list.array[arrIdx]);
3430             }
3431          }
3432          free(ricServiceQuery->protocolIEs.list.array);
3433       }
3434    }
3435 }
3436 /*******************************************************************
3437  *
3438  * @brief Build RanFunction Delete List
3439  *
3440  * @details
3441  *
3442  *    Function : BuildRanFunctionDeleteList
3443  *
3444  * Functionality:  Build RanFunction Delete List
3445  *
3446  * @params[in]
3447  *    RANfunctionsID List
3448  *    Count of the RAN function
3449  *    Received RAN function list
3450  *
3451  * @return ROK     - success
3452  *         RFAILED - failure
3453  *
3454  ******************************************************************/
3455
3456 uint8_t BuildRanFunctionDeleteList(RANfunctionsID_List_t *deleteList, uint8_t count, RanFuncInfo *recvdRanFunc)
3457 {
3458    uint8_t ranFuncIdx=0;
3459    RANfunctionID_ItemIEs_t *delRanFuncItem;
3460
3461    if(count)
3462    {
3463       deleteList->list.count = count;
3464       deleteList->list.size = deleteList->list.count * sizeof(RANfunctionID_ItemIEs_t*);
3465       DU_ALLOC(deleteList->list.array, deleteList->list.size);
3466       if(deleteList->list.array == NULLP)
3467       {
3468          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
3469          return RFAILED;
3470       }
3471       for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
3472       {
3473          DU_ALLOC(deleteList->list.array[ranFuncIdx], sizeof(RANfunctionID_ItemIEs_t));
3474          if(deleteList->list.array[ranFuncIdx] == NULLP)
3475          {
3476             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
3477             return RFAILED;
3478          }
3479          delRanFuncItem= (RANfunctionID_ItemIEs_t *) deleteList->list.array[ranFuncIdx];
3480          delRanFuncItem->id = ProtocolIE_IDE2_id_RANfunctionID_Item;
3481          delRanFuncItem->criticality = CriticalityE2_ignore;
3482          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionID = recvdRanFunc[ranFuncIdx].id;
3483          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionRevision = recvdRanFunc[ranFuncIdx].revisionCounter;
3484
3485       }
3486    }
3487    return ROK;
3488 }
3489 /*******************************************************************
3490  *
3491  * @brief De Allocate  Ric Service Update message
3492  *
3493  * @details
3494  *
3495  *    Function : FreeRicServiceUpdate
3496  *
3497  *    Functionality: De-Allocating Ric Service Update message
3498  *
3499  * @params[in] E2AP_PDU_t *e2apMsg
3500
3501  * @return void
3502  *
3503  * ****************************************************************/
3504
3505 void FreeRicServiceUpdate(E2AP_PDU_t *e2apMsg)
3506 {
3507    uint8_t arrIdx = 0;
3508    uint8_t ranFuncAddListIdx=0, ranFuncDelIdx=0;
3509    RICserviceUpdate_t *ricServiceUpdate;
3510    RANfunctions_List_t *ranFunctionsList;
3511    RANfunction_ItemIEs_t *ranFuncItemIe;
3512    RANfunction_Item_t  *ranFunItem;
3513    RANfunctionsID_List_t *deleteList;
3514
3515    /* De-allocating Memory */
3516    if(e2apMsg != NULLP)
3517    {
3518       if(e2apMsg->choice.initiatingMessage != NULLP)
3519       {
3520          ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
3521          if(ricServiceUpdate->protocolIEs.list.array != NULLP)
3522          {
3523             for(arrIdx = 0; arrIdx < ricServiceUpdate->protocolIEs.list.count; arrIdx++)
3524             {
3525                if(ricServiceUpdate->protocolIEs.list.array[arrIdx] != NULLP)
3526                {
3527                   switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
3528                   {
3529                      case ProtocolIE_IDE2_id_TransactionID:
3530                         break;
3531
3532                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
3533                      case ProtocolIE_IDE2_id_RANfunctionsModified:
3534                         {
3535                            ranFunctionsList = &(ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List);
3536                            if(ranFunctionsList->list.array)
3537                            {
3538                               for(ranFuncAddListIdx= 0; ranFuncAddListIdx< ranFunctionsList->list.count; ranFuncAddListIdx++)
3539                               {
3540                                  if(ranFunctionsList->list.array[ranFuncAddListIdx])
3541                                  {
3542                                     ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncAddListIdx];
3543                                     ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
3544                                     DU_FREE(ranFunItem->ranFunctionOID.buf, ranFunItem->ranFunctionOID.size);
3545                                     DU_FREE(ranFunItem->ranFunctionDefinition.buf, ranFunItem->ranFunctionDefinition.size);
3546                                     DU_FREE(ranFunctionsList->list.array[ranFuncAddListIdx], sizeof(RANfunction_ItemIEs_t));
3547                                  }
3548                               }
3549                               DU_FREE(ranFunctionsList->list.array, ranFunctionsList->list.size);
3550                            }
3551                            break;
3552                         }
3553                      case ProtocolIE_IDE2_id_RANfunctionsDeleted:
3554                         {
3555                            deleteList= &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
3556                            if(deleteList->list.array)
3557                            {
3558                               for(ranFuncDelIdx = 0; ranFuncDelIdx< deleteList->list.count; ranFuncDelIdx++)
3559                               {
3560                                  DU_FREE(deleteList->list.array[ranFuncDelIdx], sizeof(RANfunctionID_ItemIEs_t));
3561                               }
3562                               DU_FREE(deleteList->list.array, deleteList->list.size);
3563   
3564                            }
3565                            break;
3566                         }
3567                      default:
3568                         DU_LOG("\nERROR  --> E2AP: Invalid event at ricServiceUpdate %ld ",\
3569                               (ricServiceUpdate->protocolIEs.list.array[arrIdx]->id));
3570                         break;
3571                   }
3572                   DU_FREE(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
3573                }
3574             }
3575             DU_FREE(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
3576          }
3577          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3578       }
3579       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3580    }
3581 }
3582
3583 /*******************************************************************
3584  *
3585  * @brief Builds and Send the RicServiceUpdateuest
3586  *
3587  * @details
3588  *
3589  *    Function : BuildAndSendRicServiceUpdate
3590  *
3591  * Functionality:Fills the RicServiceUpdateuest
3592  *
3593  * @return ROK     - success
3594  *         RFAILED - failure
3595  *
3596  ******************************************************************/
3597
3598 uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate)
3599 {
3600    uint8_t arrIdx = 0, elementCnt=0;
3601    uint8_t transId = 0, ret = RFAILED;
3602    bool memAllocFailed =false;
3603    E2AP_PDU_t        *e2apMsg = NULLP;
3604    RICserviceUpdate_t  *ricServiceUpdate = NULLP;
3605    asn_enc_rval_t     encRetVal;       /* Encoder return value */
3606
3607    DU_LOG("\nINFO   -->  E2AP : Building Ric Service Update\n");
3608    do
3609    {
3610       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3611       if(e2apMsg == NULLP)
3612       {
3613          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
3614          break;
3615       }
3616       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
3617       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3618       if(e2apMsg->choice.initiatingMessage == NULLP)
3619       {
3620          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
3621          break;
3622       }
3623       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
3624       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
3625       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceUpdate;
3626       ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
3627       
3628       /* For TransId IE, set elementCnt to 1.
3629       If there is any item in the RAN function add list, RAN function modification list, or RAN function delete list, increment the elementCnt.*/
3630
3631       elementCnt =1;
3632       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
3633         elementCnt++;
3634       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
3635          elementCnt++;
3636       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
3637          elementCnt++;
3638        
3639       ricServiceUpdate->protocolIEs.list.count = elementCnt;
3640       ricServiceUpdate->protocolIEs.list.size = elementCnt * sizeof(RICserviceUpdate_IEs_t*);
3641
3642       /* Initialize the E2Setup members */
3643       DU_ALLOC(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
3644       if(ricServiceUpdate->protocolIEs.list.array == NULLP)
3645       {
3646          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
3647          break;
3648       }
3649       
3650       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
3651       {
3652          DU_ALLOC(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
3653          if(ricServiceUpdate->protocolIEs.list.array[arrIdx] == NULLP)
3654          {
3655             memAllocFailed = true;
3656             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayIdx [%d]", arrIdx);
3657             break;
3658          }
3659       }
3660       if(memAllocFailed == true)
3661          break;
3662
3663       arrIdx = 0;
3664
3665       /* TransactionID */
3666       ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
3667       ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3668       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
3669       if(serviceUpdate.dir == E2_NODE_INITIATED)
3670          transId = assignTransactionId();
3671       else
3672         transId = serviceUpdate.transId;
3673       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
3674
3675       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
3676       {
3677          arrIdx++;
3678          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAdded;
3679          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3680          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
3681          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,\
3682          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded, serviceUpdate.recvRanFuncList.ranFunToBeAdded) !=ROK)
3683          {
3684             break;
3685          }
3686       }
3687
3688       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
3689       {
3690          arrIdx++;
3691          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsModified;
3692          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3693          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
3694          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,
3695          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeModified, serviceUpdate.recvRanFuncList.ranFunToBeModified) !=ROK)
3696          {
3697             break;
3698          }
3699       }
3700
3701       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
3702       {
3703          arrIdx++;
3704          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsDeleted;
3705          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3706          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctionsID_List;
3707          if(BuildRanFunctionDeleteList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List,\
3708          serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted, serviceUpdate.recvRanFuncList.ranFunToBeDeleted) != ROK)
3709          {
3710             break;
3711          }
3712       }
3713       /* Prints the Msg formed */
3714       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3715
3716       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3717       encBufSize = 0;
3718       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3719       if(encRetVal.encoded == ENCODE_FAIL)
3720       {
3721          DU_LOG("\nERROR  -->  E2AP : Could not encode RicServiceUpdateuest structure (at %s)\n",\
3722                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3723          break;
3724       }
3725       else
3726       {
3727          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RicServiceUpdateuest\n");
3728 #ifdef DEBUG_ASN_PRINT
3729          for(int i=0; i< encBufSize; i++)
3730          {
3731             printf("%x",encBuf[i]);
3732          }
3733 #endif
3734       }
3735       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
3736       {
3737          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
3738          break;
3739       }
3740       ret = ROK;
3741       break;
3742    }while(true);
3743    
3744    if(ret == ROK)
3745    {
3746       if(serviceUpdate.dir == E2_NODE_INITIATED)
3747       {
3748          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
3749          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
3750       }
3751       else
3752       {
3753          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId = transId;
3754          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
3755       }
3756       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.dir = serviceUpdate.dir;
3757       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.transId =transId;
3758       memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.recvRanFuncList, &serviceUpdate.recvRanFuncList, sizeof(E2TmpRanFunList));
3759    }
3760    FreeRicServiceUpdate(e2apMsg);
3761    return ret;
3762 }
3763 /******************************************************************
3764  *
3765  * @brief Processes RIC service Query sent by RIC
3766  *
3767  * @details
3768  *
3769  *    Function : procRicServiceQuery
3770  *
3771  *    Functionality: Processes RIC service Query sent by RIC
3772  *
3773  * @params[in] E2AP_PDU_t ASN decoded E2AP message
3774  * @return ROK     - success
3775  *         RFAILED - failure
3776  *
3777  * ****************************************************************/
3778
3779 void procRicServiceQuery(E2AP_PDU_t *e2apMsg)
3780 {
3781    ConfigType action;
3782    uint16_t arrIdx =0, ranFuncIdx=0,tmpIdx=0;
3783    uint16_t id,revisionCcounter;
3784    bool tmpArray[MAX_RAN_FUNCTION] = {false};
3785    RICserviceQuery_t *ricServiceQuery=NULL;
3786    RicServiceUpdate ricUpdate;
3787    RANfunctionID_ItemIEs_t *ranFuncAddedItemIe;
3788    RANfunctionsID_List_t *ranFuncAddedList;
3789
3790    DU_LOG("\nINFO   -->  E2AP : RIC Service Query received");
3791    memset(&ricUpdate, 0, sizeof(RicServiceUpdate));
3792    ricUpdate.dir = RIC_INITIATED;
3793    ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
3794
3795    for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
3796    {
3797       switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
3798       {
3799          /* TODO completing in next patch/gerrit */
3800          case ProtocolIE_IDE2_id_TransactionID:
3801          {
3802             ricUpdate.transId = ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
3803             break;
3804          }
3805
3806          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
3807          {
3808             ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
3809             if(ranFuncAddedList->list.array)
3810             {
3811                for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
3812                {
3813                   if(ranFuncAddedList->list.array[ranFuncIdx])
3814                   {
3815                      /* Using the RAN function Id, identify the RAN function to be modified or deleted.  */
3816                      
3817                      ranFuncAddedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAddedList->list.array[ranFuncIdx];
3818                      id = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionID;
3819                      revisionCcounter = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision;
3820                      
3821                      if((id != duCb.e2apDb.ranFunction[id-1].id))
3822                      {
3823                         action = CONFIG_DEL;
3824                      }
3825                      else if((id == duCb.e2apDb.ranFunction[id-1].id)&&(revisionCcounter!=duCb.e2apDb.ranFunction[id-1].revisionCounter))
3826                      {
3827                         action = CONFIG_MOD;
3828                      }
3829
3830                      if(action == CONFIG_DEL)
3831                      {
3832                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].id = id;
3833                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].revisionCounter = revisionCcounter;
3834                         ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted++;
3835                      }
3836                      else if(action == CONFIG_MOD)
3837                      {
3838                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].id = id;
3839                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].revisionCounter = revisionCcounter;
3840                         ricUpdate.recvRanFuncList.numOfRanFunToBeModified++;
3841                      }
3842
3843                      /* If any ID is set to true, it means that the ID has been used in either modification or deletion list. 
3844                       * Else we will add the IDs into the added list */
3845                      tmpArray[id-1] = true;
3846                   }
3847                }
3848             }
3849             break;
3850          }
3851       }
3852    }
3853
3854    /*  Traversing the whole RAN function list in ducb to check if any new Ran function ids have been added. */
3855    for(arrIdx =0; arrIdx<MAX_RAN_FUNCTION; arrIdx++)
3856    {
3857       tmpIdx= ricUpdate.recvRanFuncList.numOfRanFunToBeAdded;
3858       if((duCb.e2apDb.ranFunction[arrIdx].id >0)&&(!tmpArray[arrIdx]))
3859       {
3860          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[arrIdx].id;
3861          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[arrIdx].revisionCounter;
3862          ricUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
3863       }
3864    }
3865
3866    if(BuildAndSendRicServiceUpdate(ricUpdate)!= ROK)
3867    {
3868       DU_LOG("\nERROR  -->  E2AP : Failed to build and send ric service update message");
3869    }
3870
3871    freeAperDecodingOfRicServiceQuery(ricServiceQuery);
3872 }
3873
3874 /******************************************************************
3875  *
3876  * @brief Deallocation of memory allocated by aper decoder for 
3877  *    RIC service update ack
3878  *
3879  * @details
3880  *
3881  *    Function : freeAperDecodingOfRicServiceUpdateAck
3882  *
3883  *    Functionality: Deallocation of memory allocated by aper decoder 
3884  *    for RIC service update ack
3885  *
3886  * @params[in] RICserviceUpdateAck_t *ricServiceAck;
3887  * @return void
3888  *
3889  * ****************************************************************/
3890
3891 void freeAperDecodingOfRicServiceUpdateAck(RICserviceUpdateAcknowledge_t *ricServiceAck)
3892 {
3893    uint8_t arrIdx=0,ranFuncIdx=0;
3894    RANfunctionsID_List_t *ranFuncAddedList=NULL;
3895
3896    if(ricServiceAck)
3897    {
3898       if(ricServiceAck->protocolIEs.list.array)
3899       {
3900          for(arrIdx=0; arrIdx<ricServiceAck->protocolIEs.list.count; arrIdx++)
3901          {
3902             if(ricServiceAck->protocolIEs.list.array[arrIdx])
3903             {
3904                switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id)
3905                {
3906                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
3907                   {
3908                      ranFuncAddedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
3909                      if(ranFuncAddedList->list.array)
3910                      {
3911                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
3912                         {
3913                            free(ranFuncAddedList->list.array[ranFuncIdx]);
3914                         }
3915                         free(ranFuncAddedList->list.array);
3916                      }
3917                      break;
3918                   }
3919                   default:
3920                      break;
3921                }
3922                free(ricServiceAck->protocolIEs.list.array[arrIdx]);  
3923             }
3924          }
3925          free(ricServiceAck->protocolIEs.list.array);
3926       }
3927    }
3928 }
3929
3930 /******************************************************************
3931  *
3932  * @brief Processes RIC service update ack sent by RIC
3933  *
3934  * @details
3935  *
3936  *    Function : procRicServiceUpdateAck
3937  *
3938  *    Functionality: Processes RIC service update ack sent by RIC
3939  *
3940  * @params[in] E2AP_PDU_t ASN decoded E2AP message
3941  * @return ROK     - success
3942  *         RFAILED - failure
3943  *
3944  * ****************************************************************/
3945
3946 void procRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
3947 {
3948    uint8_t arrIdx =0, transId =0; 
3949    uint16_t id =0, tmpIdx=0, ranFuncIdx=0;
3950    RicServiceUpdate serviceUpdate;
3951    RANfunctionsIDcause_List_t *rejectedList=NULL;
3952    RICserviceUpdateAcknowledge_t *ricServiceAck=NULL;
3953    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
3954    
3955    DU_LOG("\nINFO   -->  E2AP : RIC service update ack received"); 
3956    memset(&serviceUpdate, 0, sizeof(RicServiceUpdate));
3957    ricServiceAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
3958    
3959    for(arrIdx=0; arrIdx<ricServiceAck->protocolIEs.list.count; arrIdx++)
3960    {
3961       switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id)
3962       {
3963          case ProtocolIE_IDE2_id_TransactionID:
3964          {
3965             transId = ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
3966             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
3967             (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
3968             {
3969               memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
3970             }
3971             else if((duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId == transId) &&\
3972             (duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
3973             {
3974               memset(&duCb.e2apDb.e2TransInfo.ricInitTransaction[transId], 0, sizeof(E2TransInfo));
3975             }
3976             else
3977             {
3978                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
3979                return ;
3980             }
3981             break;
3982          }
3983          
3984          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
3985             break;
3986
3987          case ProtocolIE_IDE2_id_RANfunctionsRejected:
3988          {
3989             rejectedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
3990             if(rejectedList->list.array)
3991             {
3992                for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
3993                {
3994                   ranFuncRejectedItemIe =  (RANfunctionIDcause_ItemIEs_t*)rejectedList->list.array[ranFuncIdx];
3995                   id = ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID;
3996                   tmpIdx= serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded;
3997                   serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[id-1].id;
3998                   serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[id-1].revisionCounter;
3999                   serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
4000                }
4001             }
4002             break;
4003          }
4004
4005       }
4006    }
4007
4008    if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
4009    {
4010       serviceUpdate.dir = E2_NODE_INITIATED;
4011       BuildAndSendRicServiceUpdate(serviceUpdate);
4012    }
4013    freeAperDecodingOfRicServiceUpdateAck(ricServiceAck);
4014 }
4015
4016 /******************************************************************
4017  *
4018  * @brief Deallocation of memory allocated by aper decoder for 
4019  *       RIC service update failure
4020  *
4021  * @details
4022  *
4023  *    Function : freeAperDecodingOfRicServiceUpdateFailure
4024  *
4025  *    Functionality: Deallocation of memory allocated by aper decoder 
4026  *    for RIC service update failure
4027  *
4028  * @params[in] RICserviceUpdateFailure_t *ricServiceFailure;
4029  * @return void
4030  *
4031  * ****************************************************************/
4032
4033 void freeAperDecodingOfRicServiceUpdateFailure(RICserviceUpdateFailure_t *ricServiceFailure)
4034 {
4035    uint8_t arrIdx=0;
4036
4037    if(ricServiceFailure)
4038    {
4039       if(ricServiceFailure->protocolIEs.list.array)
4040       {
4041          for(arrIdx=0; arrIdx<ricServiceFailure->protocolIEs.list.count; arrIdx++)
4042          {
4043             if(ricServiceFailure->protocolIEs.list.array[arrIdx])
4044             {
4045                free(ricServiceFailure->protocolIEs.list.array[arrIdx]);  
4046             }
4047          }
4048          free(ricServiceFailure->protocolIEs.list.array);
4049       }
4050    }
4051 }
4052
4053 /******************************************************************
4054  *
4055  * @brief Processes RIC service update failure sent by RIC
4056  *
4057  * @details
4058  *
4059  *    Function : procRicServiceUpdateFailure
4060  *
4061  *    Functionality: Processes RIC service update failure sent by RIC
4062  *
4063  * @params[in] E2AP_PDU_t ASN decoded E2AP message
4064  * @return ROK     - success
4065  *         RFAILED - failure
4066  *
4067  * ****************************************************************/
4068
4069 void procRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
4070 {
4071    uint8_t arrIdx =0, timerValue=0; 
4072    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
4073
4074    DU_LOG("\nINFO   -->  E2AP : RIC service update failure received"); 
4075    ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
4076
4077    for(arrIdx=0; arrIdx<ricServiceFailure->protocolIEs.list.count; arrIdx++)
4078    {
4079       switch(ricServiceFailure->protocolIEs.list.array[arrIdx]->id)
4080       {
4081          case ProtocolIE_IDE2_id_TransactionID:
4082             {
4083                break;
4084             }
4085          case ProtocolIE_IDE2_id_TimeToWaitE2:
4086             {
4087                timerValue = covertE2WaitTimerEnumToValue(ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
4088                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR)) == FALSE)
4089                {
4090                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR, timerValue);
4091                }
4092                else
4093                {
4094                   DU_LOG("\nERROR   -->  E2AP : EVENT_RIC_SERVICE_UPDATE_TMR  timer is already running");
4095                   return;
4096                }
4097                break; 
4098             }
4099          case ProtocolIE_IDE2_id_CauseE2:
4100             {
4101                break;
4102             }
4103       }
4104    }
4105
4106    freeAperDecodingOfRicServiceUpdateFailure(ricServiceFailure);
4107 }
4108
4109 /*******************************************************************
4110  *
4111  * @brief Handles received E2AP message and sends back response  
4112  *
4113  * @details
4114  *
4115  *    Function : E2APMsgHdlr
4116  *
4117  *    Functionality:
4118  *         - Decodes received E2AP control message
4119  *         - Prepares response message, encodes and sends to SCTP
4120  *
4121  * @params[in] 
4122  * @return ROK     - success
4123  *         RFAILED - failure
4124  *
4125  * ****************************************************************/
4126 void E2APMsgHdlr(Buffer *mBuf)
4127 {
4128    int i =0;
4129    char *recvBuf = NULLP;
4130    MsgLen copyCnt =0;
4131    MsgLen recvBufLen =0;
4132    E2AP_PDU_t *e2apMsg = NULLP;
4133    asn_dec_rval_t rval ={0}; /* Decoder return value */
4134    E2AP_PDU_t e2apasnmsg={0} ;
4135
4136    DU_LOG("\nDEBUG   -->  E2AP : Received E2AP message buffer");
4137    ODU_PRINT_MSG(mBuf, 0,0);
4138
4139    /* Copy mBuf into char array to decode it */
4140    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
4141    DU_ALLOC(recvBuf, (Size)recvBufLen);
4142
4143    if(recvBuf == NULLP)
4144    {
4145       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
4146       return;
4147    }
4148    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
4149    {
4150       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
4151       return;
4152    }
4153
4154 #ifdef DEBUG_ASN_PRINT
4155    printf("\nDEBUG   -->  E2AP : Received flat buffer to be decoded : ");
4156    for(i=0; i< recvBufLen; i++)
4157    {
4158       printf("%x",recvBuf[i]);
4159    }
4160 #endif
4161
4162    /* Decoding flat buffer into E2AP messsage */
4163    e2apMsg = &e2apasnmsg;
4164    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
4165
4166    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
4167    DU_FREE(recvBuf, (Size)recvBufLen);
4168
4169    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
4170    {
4171       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
4172       return;
4173    }
4174    printf("\n");
4175    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4176
4177    switch(e2apMsg->present)
4178    {
4179       case E2AP_PDU_PR_unsuccessfulOutcome:
4180          {
4181             switch(e2apMsg->choice.unsuccessfulOutcome->value.present)
4182             {
4183                case UnsuccessfulOutcomeE2__value_PR_E2setupFailure:
4184                   {
4185                      procE2SetupFailure(e2apMsg);
4186                      break;
4187                   }
4188                default:
4189                   {
4190                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome  [%d]",\
4191                            e2apMsg->choice.unsuccessfulOutcome->value.present);
4192                      return;
4193                   }
4194             }
4195             break;
4196          }
4197       case E2AP_PDU_PR_successfulOutcome:
4198          {
4199             switch(e2apMsg->choice.successfulOutcome->value.present)
4200             {
4201                case SuccessfulOutcomeE2__value_PR_E2setupResponse:
4202                   {
4203                      if(!duCb.e2Status)
4204                      {
4205                         procE2SetupRsp(e2apMsg);
4206                      }
4207                      break;
4208                   }
4209                case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge:
4210                   {
4211                      DU_LOG("\nDEBUG   -->  E2AP : E2 node Config update ack message recevied");
4212                      break;
4213                   }
4214                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
4215                   {
4216                      procResetResponse(e2apMsg);
4217                      break;
4218                   }
4219                case SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge:
4220                   {
4221                      procRicServiceUpdateAck(e2apMsg);
4222                      break;
4223                   }
4224
4225
4226                default:
4227                   {
4228                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome  [%d]",\
4229                            e2apMsg->choice.successfulOutcome->value.present);
4230                      return;
4231                   }
4232             }/* End of switch(successfulOutcome) */
4233             free(e2apMsg->choice.successfulOutcome);
4234             break;
4235          }
4236
4237       case E2AP_PDU_PR_initiatingMessage:
4238          {
4239             switch(e2apMsg->choice.initiatingMessage->value.present)
4240             {
4241                case InitiatingMessageE2__value_PR_RICsubscriptionRequest: 
4242                   {
4243                      procRicSubscriptionRequest(e2apMsg);
4244                      break;
4245                   }
4246                case InitiatingMessageE2__value_PR_RICserviceQuery:
4247                   {
4248                      procRicServiceQuery(e2apMsg);
4249                      break;
4250                   }
4251                default:
4252                   {
4253                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\
4254                            e2apMsg->choice.initiatingMessage->value.present);
4255                      return;
4256                   }
4257             }/* End of switch(initiatingMessage) */
4258             free(e2apMsg->choice.initiatingMessage);
4259             break;
4260          }
4261       default:
4262          {
4263             DU_LOG("\nERROR  -->  E2AP : Invalid type of e2apMsg->present [%d]",e2apMsg->present);
4264             return;
4265          }
4266          free(e2apMsg);
4267
4268    }/* End of switch(e2apMsg->present) */
4269
4270 } /* End of E2APMsgHdlr */
4271
4272 /**********************************************************************
4273   End of file
4274  **********************************************************************/