ac86380ee2128fd295569d2f84b310678cf2ab8e
[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 Request Id
1160  *
1161  * @details
1162  *
1163  *    Function : BuildRicRequestId
1164  *
1165  *    Functionality: Building the Ric Request Id
1166  *
1167  * @params[in] RICrequestID_t *ricReqId
1168  * @return ROK     - success
1169  *         RFAILED - failure
1170  *
1171  * ****************************************************************/
1172
1173 uint8_t BuildRicRequestId(RICrequestID_t *ricReqId)
1174 {
1175    if(ricReqId == NULLP)
1176    {
1177       return RFAILED;
1178    }
1179
1180    ricReqId->ricRequestorID = 1;
1181    ricReqId->ricInstanceID  = 1;
1182    return ROK;
1183 }
1184
1185 /*******************************************************************
1186  *
1187  * @brief Fills the mandatory RicAdmitted List Items
1188  *
1189  * @details
1190  *
1191  *    Function : fillRicAdmitList
1192  *
1193  *    Functionality: Fills the mandatory Ric Admitted List Items
1194  *
1195  * @params[in] RICaction_Admitted_ItemIEs_t *ricAdmitItems
1196  * @return ROK     - success
1197  *         RFAILED - failure
1198  *
1199  * ****************************************************************/
1200
1201 uint8_t fillRicAdmitList(RICaction_Admitted_ItemIEs_t *ricAdmitItems)
1202 {
1203
1204    if(ricAdmitItems != NULLP)
1205    {
1206       ricAdmitItems->id = ProtocolIE_IDE2_id_RICaction_Admitted_Item;
1207       ricAdmitItems->criticality = CriticalityE2_reject;
1208       ricAdmitItems->value.present = RICaction_Admitted_ItemIEs__value_PR_RICaction_Admitted_Item;
1209       ricAdmitItems->value.choice.RICaction_Admitted_Item.ricActionID = 1; 
1210    }
1211    else
1212    {
1213       return RFAILED;
1214    }
1215    return ROK;
1216 }
1217 /*******************************************************************
1218  *
1219  * @brief Builds the mandatory RicAdmitted List Params
1220  *
1221  * @details
1222  *
1223  *    Function : BuildRicAdmitList
1224  *
1225  *    Functionality: Builds the mandatory Ric Admitted List Params
1226  *
1227  * @params[in] RICaction_Admitted_List_t *admitListPtr
1228  * @return ROK     - success
1229  *         RFAILED - failure
1230  *
1231  * ****************************************************************/
1232
1233 uint8_t BuildRicAdmitList(RICaction_Admitted_List_t *admitListPtr)
1234 {
1235    uint8_t idx ;
1236    uint8_t elementCnt;  
1237    uint8_t ret= ROK;
1238    elementCnt = 1;
1239
1240    if(admitListPtr == NULLP)
1241    {
1242       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC Admit List failed");
1243       ret = RFAILED;
1244    }
1245    else
1246    {
1247       admitListPtr->list.count = elementCnt;
1248       admitListPtr->list.size  = elementCnt * sizeof(RICaction_Admitted_ItemIEs_t);
1249       DU_ALLOC(admitListPtr->list.array, admitListPtr->list.size);
1250       if(admitListPtr->list.array == NULLP)
1251       {
1252          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC Admit List failed");
1253          ret = RFAILED;
1254       }
1255       else
1256       {
1257          for(idx=0 ; idx<elementCnt ; idx++ )
1258          {
1259             DU_ALLOC(admitListPtr->list.array[idx], sizeof(RICaction_Admitted_ItemIEs_t));
1260             if(admitListPtr->list.array[idx] == NULLP)
1261             {
1262                ret = RFAILED;
1263             }
1264          }
1265          if(ret != RFAILED)
1266          {
1267             idx=0;
1268             fillRicAdmitList((RICaction_Admitted_ItemIEs_t *)admitListPtr->list.array[idx]);
1269          }
1270       }
1271    }    
1272    return ret;
1273 }
1274 /*******************************************************************
1275  *
1276  * @breif Deallocation of BuildAndSendRicSubscriptionRsp memory
1277  *
1278  * @details
1279  *
1280  *    Function : FreeRicSubscriptionRsp
1281  *
1282  * Functionality:Free the RicSubscriptionRsp
1283  *
1284  * @param[in] E2AP_PDU_t *e2apRicMsg
1285  *
1286  * @return void
1287  *      
1288  *
1289  ******************************************************************/
1290 void FreeRicSubscriptionRsp(E2AP_PDU_t  *e2apRicMsg)
1291 {
1292    RICsubscriptionResponse_t  *ricSubscriptionRsp= NULLP;
1293    uint8_t idx=0;
1294    uint8_t idx1=0;
1295    RICaction_Admitted_List_t *admitListPtr;
1296
1297    if(e2apRicMsg != NULLP)
1298    {
1299       if(e2apRicMsg->choice.successfulOutcome != NULLP)
1300       {
1301          ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
1302          if(ricSubscriptionRsp)
1303          {
1304             if(ricSubscriptionRsp->protocolIEs.list.array != NULLP)
1305             {
1306                for(idx=0; idx<ricSubscriptionRsp->protocolIEs.list.count; idx++)
1307                {
1308                   if(ricSubscriptionRsp->protocolIEs.list.array[idx] != NULLP)
1309                   {
1310                      switch(ricSubscriptionRsp->protocolIEs.list.array[idx]->id)
1311                      {
1312                         case ProtocolIE_IDE2_id_RICrequestID:
1313                            break;
1314
1315                         case ProtocolIE_IDE2_id_RANfunctionID:
1316                            break;
1317
1318                         case ProtocolIE_IDE2_id_RICactions_Admitted:
1319                            {
1320                               admitListPtr = &ricSubscriptionRsp->protocolIEs.list.\
1321                                              array[idx]->value.choice.RICaction_Admitted_List;
1322                               if(admitListPtr->list.array != NULLP)
1323                               {
1324                                  for(idx1=0 ; idx1<admitListPtr->list.count; idx1++ )
1325                                  {
1326                                     if(admitListPtr->list.array[idx1] != NULLP)
1327                                     {
1328                                        DU_FREE(admitListPtr->list.array[idx1],
1329                                              sizeof(RICaction_Admitted_ItemIEs_t));
1330                                     }
1331                                  }
1332                                  DU_FREE(admitListPtr->list.array, admitListPtr->list.size);     
1333                               }
1334                               break;
1335                            }
1336                         default:
1337                            break;
1338                      }
1339                      DU_FREE(ricSubscriptionRsp->protocolIEs.list.array[idx], \
1340                            sizeof(RICsubscriptionResponse_IEs_t));
1341                   }
1342                }
1343                DU_FREE(ricSubscriptionRsp->protocolIEs.list.array, \
1344                      ricSubscriptionRsp->protocolIEs.list.size);
1345             }
1346          }   
1347          DU_FREE(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1348       }         
1349       DU_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));        
1350    }
1351 }
1352 /*******************************************************************
1353  *
1354  * @brief Builds and Send the RicSubscriptionRsp
1355  *
1356  * @details
1357  *
1358  *    Function : BuildAndSendRicSubscriptionRsp
1359  *
1360  * functionality:Fills the RicSubscriptionRsp
1361  *
1362  * @return ROK     - success
1363  *         RFAILED - failure
1364  *
1365  ******************************************************************/
1366 uint8_t  FillRicSubscriptionRsp(RICsubscriptionResponse_t  *ricSubscriptionRsp )
1367 {
1368    uint8_t idx=0;
1369    uint8_t ret = ROK;
1370    uint8_t elementCnt = 0;
1371    uint8_t BuildRicRequestIdret=ROK;
1372    uint8_t BuildRicAdmitListret=ROK;
1373
1374    elementCnt=3;
1375    ricSubscriptionRsp->protocolIEs.list.count = elementCnt;
1376    ricSubscriptionRsp->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionResponse_IEs_t);
1377    DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array, \
1378          ricSubscriptionRsp->protocolIEs.list.size);
1379    if(ricSubscriptionRsp->protocolIEs.list.array == NULLP)
1380    {
1381       DU_LOG("\nERROR  -->  E2AP : Memory allocation for FillRicSubscriptionRsp  failed");
1382       ret = RFAILED;
1383    }
1384    else
1385    {
1386       for(idx=0; idx<ricSubscriptionRsp->protocolIEs.list.count; idx++)
1387       {
1388          DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array[idx], \
1389                sizeof(RICsubscriptionResponse_IEs_t));
1390          if(ricSubscriptionRsp->protocolIEs.list.array[idx] == NULLP)
1391          {
1392             ret = RFAILED;
1393          }
1394       }
1395       if(ret != RFAILED)
1396       {
1397
1398          idx=0;
1399          ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
1400          ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1401          ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
1402                                                                          RICsubscriptionRequest_IEs__value_PR_RICrequestID;
1403          BuildRicRequestIdret =
1404             BuildRicRequestId(&ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RICrequestID);
1405          if(BuildRicRequestIdret != ROK)
1406          {
1407             ret = RFAILED;
1408          }
1409          else
1410          {
1411             idx++;
1412             ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
1413             ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1414             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
1415                                                                             RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
1416             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1;
1417
1418             idx++;
1419             ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactions_Admitted;
1420             ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1421             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
1422                                                                             RICsubscriptionResponse_IEs__value_PR_RICaction_Admitted_List;
1423             BuildRicAdmitListret =
1424                BuildRicAdmitList(&ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RICaction_Admitted_List);
1425             if(BuildRicAdmitListret != ROK)
1426             {
1427                ret = RFAILED;
1428             }
1429          }
1430       }
1431    }    
1432    return ret;
1433 }
1434 /*******************************************************************
1435  *
1436  * @brief Builds and Send the RicSubscriptionRsp
1437  *
1438  * @details
1439  *
1440  *    Function : BuildAndSendRicSubscriptionRsp
1441  *
1442  * Functionality:Fills the RicSubscriptionRsp
1443  *
1444  * @return ROK     - success
1445  *         RFAILED - failure
1446  *
1447  ******************************************************************/
1448
1449 uint8_t BuildAndSendRicSubscriptionRsp()
1450 {
1451
1452    E2AP_PDU_t         *e2apRicMsg = NULLP;
1453    RICsubscriptionResponse_t  *ricSubscriptionRsp=NULLP;
1454    asn_enc_rval_t     encRetVal; 
1455    uint8_t ret = RFAILED;
1456    uint8_t FillRicricSubscriptionRspret;
1457
1458    while(true)
1459    {
1460       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Response\n");
1461
1462       DU_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t)); 
1463       if(e2apRicMsg == NULLP)
1464       {
1465          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1466          break;
1467       }
1468       e2apRicMsg->present =  E2AP_PDU_PR_successfulOutcome;
1469       DU_ALLOC(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1470       if(e2apRicMsg->choice.successfulOutcome == NULLP)
1471       {
1472          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC subscription Response failed");
1473          break;
1474       }
1475
1476       e2apRicMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
1477       e2apRicMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
1478       e2apRicMsg->choice.successfulOutcome->value.present = \
1479                                                             SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse;
1480       ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
1481
1482       FillRicricSubscriptionRspret = FillRicSubscriptionRsp(ricSubscriptionRsp);
1483       if(FillRicricSubscriptionRspret != ROK)
1484       {
1485          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICsubscriptionResponseIE failed");
1486          break;
1487       }
1488
1489       /* Prints the Msg formed */
1490       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
1491
1492       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1493       encBufSize = 0;
1494       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\
1495             encBuf);
1496       if(encRetVal.encoded == ENCODE_FAIL)
1497       {
1498          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Response structure (at %s)\n",\
1499                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1500          break;
1501       }
1502       else
1503       {
1504          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RIC subscription response \n");
1505 #ifdef DEBUG_ASN_PRINT
1506          for(int i=0; i< encBufSize; i++)
1507          {
1508             printf("%x",encBuf[i]);
1509          } 
1510 #endif
1511       } 
1512
1513       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
1514       {
1515          DU_LOG("\nERROR  -->  E2AP : Sending RIC Subscription Response failed");      
1516          break;
1517       }
1518
1519       ret = ROK;
1520       break;
1521
1522    }
1523    FreeRicSubscriptionRsp(e2apRicMsg);
1524
1525    return ret;
1526 }
1527
1528 /******************************************************************
1529  *
1530  * @brief Deallocation of memory allocated bu aper decoder for e2 setup response
1531  *
1532  * @details
1533  *
1534  *    Function : freeAperDecodingOfE2SetupRsp
1535  *
1536  *    Functionality: Deallocation of memory allocated bu aper decoder for e2
1537  *    setup response
1538  *
1539  * @params[in] E2setupResponse_t *e2SetRspMsg;
1540  * @return void
1541  *
1542  * ****************************************************************/
1543 void freeAperDecodingOfE2SetupRsp(E2setupResponse_t *e2SetRspMsg)
1544 {
1545    uint8_t arrIdx, e2NodeConfigAddAckListIdx;
1546    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem;
1547    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAddAckList;
1548
1549    if(e2SetRspMsg)
1550    {
1551       if(e2SetRspMsg->protocolIEs.list.array)
1552       {
1553          for(arrIdx=0; arrIdx<e2SetRspMsg->protocolIEs.list.count; arrIdx++)
1554          {
1555             if(e2SetRspMsg->protocolIEs.list.array[arrIdx])
1556             {
1557                switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
1558                {
1559                   case ProtocolIE_IDE2_id_TransactionID:
1560                      break;
1561
1562                   case ProtocolIE_IDE2_id_GlobalRIC_ID:
1563                      {
1564                         free(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.pLMN_Identity.buf);
1565                         free(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID.buf);
1566                         break;
1567                      }
1568
1569                   case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
1570                      {
1571                         e2NodeConfigAddAckList = &e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
1572                         if(e2NodeConfigAddAckList->list.array )
1573                         {
1574                            for(e2NodeConfigAddAckListIdx = 0; e2NodeConfigAddAckListIdx< e2NodeConfigAddAckList->list.count; e2NodeConfigAddAckListIdx++)
1575                            {
1576                               if(e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx])
1577                               {
1578                                  e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx];
1579                                  free(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.\
1580                                        e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf);
1581                                  free(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.\
1582                                        e2nodeComponentInterfaceTypeF1);
1583                                  free(e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx]);
1584                               }
1585                            }
1586                            free(e2NodeConfigAddAckList->list.array);
1587                         }
1588                         break;
1589                      }
1590                }
1591                free(e2SetRspMsg->protocolIEs.list.array[arrIdx]);  
1592             }
1593          }
1594          free(e2SetRspMsg->protocolIEs.list.array);
1595       }
1596    }
1597 }
1598 /******************************************************************
1599  *
1600  * @brief Processes E2 Setup Response sent by RIC
1601  *
1602  * @details
1603  *
1604  *    Function : procE2SetupRsp
1605  *
1606  *    Functionality: Processes E2 Setup Response sent by RIC
1607  *
1608  * @params[in] E2AP_PDU_t ASN decoded E2AP message
1609  * @return ROK     - success
1610  *         RFAILED - failure
1611  *
1612  * ****************************************************************/
1613 uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg)
1614 {
1615    uint8_t arrIdx =0, transId=0; 
1616    uint32_t recvBufLen;             
1617    E2setupResponse_t *e2SetRspMsg;
1618    CmLList         *node;
1619    E2NodeComponent *e2NodeComponentInfo;
1620
1621    DU_LOG("\nINFO   -->  E2AP : E2 Setup Response received"); 
1622    duCb.e2Status = TRUE; //Set E2 status as true
1623    e2SetRspMsg = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
1624
1625    for(arrIdx=0; arrIdx<e2SetRspMsg->protocolIEs.list.count; arrIdx++)
1626    {
1627       switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
1628       {
1629          case ProtocolIE_IDE2_id_TransactionID:
1630             {
1631                transId = e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
1632                if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
1633                      (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
1634                {
1635                   memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
1636                }
1637                else
1638                {
1639                   DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
1640                   return RFAILED;
1641                }
1642                break;
1643             }
1644
1645          case ProtocolIE_IDE2_id_GlobalRIC_ID:
1646             {
1647                /* To store the Ric Id Params */
1648                recvBufLen = sizeof(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value\
1649                      .choice.GlobalRIC_ID.pLMN_Identity.size);
1650                   memcpy(&duCb.e2apDb.ricId.plmnId, e2SetRspMsg->protocolIEs.list.array[arrIdx]\
1651                         ->value.choice.GlobalRIC_ID.pLMN_Identity.buf, recvBufLen);
1652                bitStringToInt(&e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID, &duCb.e2apDb.ricId);
1653                /*TODO : duCb.e2apDb.ricId.plmnId memory to be deallocated after the usage */
1654                break;
1655             }
1656
1657          case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
1658             break;
1659
1660          default:
1661             DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2SetupRsp:%ld",
1662                   e2SetRspMsg->protocolIEs.list.array[arrIdx]->id);
1663             break;
1664       }
1665    }
1666    freeAperDecodingOfE2SetupRsp(e2SetRspMsg);
1667    
1668    node = searchE2NodeComponentInfo(F1, E2_NODE_COMPONENT_ADD);
1669    if(!node)
1670    {
1671       DU_LOG("\nERROR  --> E2AP : Received e2NodeComponentInfo is null");
1672       return RFAILED;
1673    }
1674    else
1675    {
1676       e2NodeComponentInfo = (E2NodeComponent*)node->node;
1677       cmLListDelFrm(&duCb.e2apDb.e2NodeComponentList, node);
1678       DU_FREE(e2NodeComponentInfo->componentRequestPart, e2NodeComponentInfo->reqBufSize);
1679       DU_FREE(e2NodeComponentInfo->componentResponsePart, e2NodeComponentInfo->rspBufSize);
1680       DU_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent));
1681       DU_FREE(node, sizeof(CmLList));
1682    }
1683
1684    BuildAndSendE2NodeConfigUpdate();
1685    return ROK;
1686 }
1687
1688 /*******************************************************************
1689  *
1690  * @brief Free RIC Subscription Request
1691  *
1692  * @details
1693  *
1694  *    Function : freeAperDecodingOfRicSubsReq
1695  *
1696  * Functionality : Free RIC Subscription Request
1697  *
1698  * @return void
1699  *
1700  ******************************************************************/
1701 void freeAperDecodingOfRicSubsReq(RICsubscriptionRequest_t *ricSubscriptionReq)
1702 {
1703    uint8_t idx = 0;
1704    uint8_t elementIdx = 0;
1705    RICsubscriptionDetails_t *subsDetails = NULLP;
1706    RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
1707
1708    if(ricSubscriptionReq->protocolIEs.list.array)
1709    {
1710       for(idx=0; idx < ricSubscriptionReq->protocolIEs.list.count; idx++)
1711       {
1712          switch(ricSubscriptionReq->protocolIEs.list.array[idx]->id)
1713          {
1714             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
1715                {
1716                   subsDetails = &(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails);
1717                   free(subsDetails->ricEventTriggerDefinition.buf);
1718
1719                   if(subsDetails->ricAction_ToBeSetup_List.list.array)
1720                   {
1721                      for(elementIdx = 0; elementIdx < subsDetails->ricAction_ToBeSetup_List.list.count; elementIdx++)
1722                      {
1723                         if(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
1724                         {
1725                            actionItem = (RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.\
1726                               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)
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                   if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType == RICactionType_report)
2198                   {
2199                      ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
2200                      ricSubscriptionInfo->actionSequence[ricActionId-1].id = ricActionId;
2201                      ricSubscriptionInfo->actionSequence[ricActionId-1].type = REPORT;
2202
2203                      if(extractRicActionDef(ranFuncDb, &ricSubscriptionInfo->actionSequence[ricActionId-1].definition, \
2204                         actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, failureCause) == ROK)
2205                      {
2206                         ricSubscriptionInfo->actionSequence[ricActionId-1].action = CONFIG_ADD;
2207                         ricSubscriptionInfo->numOfActions++;
2208                      }
2209                      else
2210                      {
2211                         memset(&ricSubscriptionInfo->actionSequence[ricActionId-1], 0, sizeof(ActionInfo));
2212                         /* TODO : Since this action addition failed, add to
2213                          * reject-action-list in subscription response */
2214                      }
2215                   }
2216                   break;
2217                }
2218             default:
2219                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id);
2220                break;
2221          }
2222       }
2223    }
2224
2225    /* If there is even 1 action that can be added, return ROK */
2226    if(ricSubscriptionInfo->numOfActions)
2227       return ROK;
2228
2229    if(failureCause->causeType == E2_NOTHING)
2230    {
2231       failureCause->causeType = E2_RIC_REQUEST;
2232       failureCause->cause = E2_ACTION_NOT_SUPPORTED;
2233    }
2234    return RFAILED;
2235 }
2236
2237 /******************************************************************
2238  *
2239  * @brief Processes RIC Subscription Req sent by RIC
2240  *
2241  * @details
2242  *
2243  *    Function : procRicSubscriptionRequest
2244  *
2245  *    Functionality: Processes RIC Subscription Request from RIC
2246  *
2247  * @params[in] E2AP_PDU_t ASN decoded E2AP message
2248  * @return ROK     - success
2249  *         RFAILED - failure
2250  *
2251  * ****************************************************************/
2252 uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg)
2253 {
2254    uint8_t idx = 0; 
2255    uint8_t ret = ROK;
2256    uint16_t ranFuncId = 0;
2257    RicRequestId ricReqId;
2258    CmLList  *ricSubscriptionNode = NULLP;
2259    RanFunction *ranFuncDb = NULLP;
2260    RICsubscriptionRequest_t *ricSubsReq = NULLP;
2261    RICsubscriptionDetails_t *subsDetails = NULLP;
2262    RicSubscription *ricSubscriptionInfo = NULLP;
2263    E2FailureCause failureCause;
2264
2265    DU_LOG("\nINFO   -->  E2AP : RIC Subscription request received"); 
2266
2267    memset(&failureCause, 0, sizeof(E2FailureCause));
2268    memset(&ricReqId, 0, sizeof(RicRequestId));
2269
2270    ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
2271    for(idx=0; idx<ricSubsReq->protocolIEs.list.count; idx++)
2272    {
2273       if(ricSubsReq->protocolIEs.list.array[idx])
2274       {
2275          switch(ricSubsReq->protocolIEs.list.array[idx]->id)
2276          {
2277             case ProtocolIE_IDE2_id_RICrequestID:
2278                {
2279                   ricReqId.requestorId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID;
2280                   ricReqId.instanceId  = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID;
2281
2282                   break;
2283                }
2284
2285             case ProtocolIE_IDE2_id_RANfunctionID:
2286                {
2287                   ranFuncId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID; 
2288
2289                   /* Validating RAN Function id */
2290                   if(duCb.e2apDb.ranFunction[ranFuncId-1].id == ranFuncId)
2291                   {
2292                      ranFuncDb = &duCb.e2apDb.ranFunction[ranFuncId-1];
2293
2294                      DU_ALLOC(ricSubscriptionInfo, sizeof(RicSubscription));
2295                      if(!ricSubscriptionInfo)
2296                      {
2297                         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for ricSubscriptionInfo");
2298                         failureCause.causeType = E2_MISCELLANEOUS;
2299                         failureCause.cause = E2_MISCELLANEOUS_CAUSE_UNSPECIFIED;
2300                         ret = RFAILED;
2301                         break;
2302                      }
2303                      ricSubscriptionInfo->requestId.requestorId = ricReqId.requestorId;
2304                      ricSubscriptionInfo->requestId.instanceId = ricReqId.instanceId;
2305                   }
2306                   else
2307                   {
2308                      failureCause.causeType = E2_RIC_REQUEST;
2309                      failureCause.cause = E2_RAN_FUNCTION_ID_INVALID;
2310                      ret = RFAILED;
2311                   }
2312                   break;
2313                }
2314
2315             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
2316                {
2317                   subsDetails = &ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails;
2318
2319                   /* Decode, Validate and record Event Trigger Definition */
2320                   if(extractEventTriggerDef(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricEventTriggerDefinition, \
2321                      &failureCause) != ROK)
2322                   {
2323                      ret = RFAILED;
2324                      break;
2325                   }
2326
2327                   /* Decode, Validate and record RIC actions */
2328                   if(extractRicActionToBeSetup(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricAction_ToBeSetup_List, \
2329                      &failureCause) != ROK)
2330                   {
2331                      ret = RFAILED;
2332                      break;
2333                   }
2334                }
2335                break;
2336
2337             default:
2338                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RIC SubsReq:%ld",
2339                      ricSubsReq->protocolIEs.list.array[idx]->id);
2340                break;
2341          }
2342
2343          if(ret == RFAILED)
2344             break;
2345       }
2346    }
2347
2348    freeAperDecodingOfRicSubsReq(ricSubsReq);
2349
2350    if(ret == ROK)
2351    {
2352       /* Add RAN subcription detail to RAN function */
2353       DU_ALLOC(ricSubscriptionNode, sizeof(CmLList));
2354       if(ricSubscriptionNode)
2355       {
2356          ricSubscriptionNode->node = (PTR) ricSubscriptionInfo;
2357          cmLListAdd2Tail(&ranFuncDb->subscriptionList, ricSubscriptionNode);
2358       }
2359
2360 #ifdef KPI_CALCULATION
2361       /* Send statistics request to other DU entities */
2362       BuildAndSendStatsReq(ranFuncId, ricSubscriptionInfo);
2363 #endif      
2364
2365       /* TODO : Trigger RIC subscription response once statistics response is
2366        * received from MAC . 
2367        * TBD in next gerrit */
2368       ret = BuildAndSendRicSubscriptionRsp();
2369       {
2370          BuildAndSendRicIndication(ricSubscriptionInfo);
2371       }
2372    }
2373    else
2374    {
2375       DU_FREE(ricSubscriptionInfo, sizeof(RicSubscription));
2376
2377       /* Send RIC Subcription Failure */
2378       BuildAndSendRicSubscriptionFailure(ricReqId, ranFuncId, failureCause);
2379    }
2380
2381    return ret;
2382 }
2383
2384 /******************************************************************
2385  *
2386  * @brief Free RIC Subscription Failure
2387  *
2388  * @details
2389  *
2390  *    Function : FreeRicSubscriptionFailure
2391  *
2392  *    Functionality: Free RIC Subscription Failure
2393  *
2394  * @params[in] E2AP PDU
2395  * @return void
2396  *
2397  * ****************************************************************/
2398 void FreeRicSubscriptionFailure(E2AP_PDU_t *e2apMsg)
2399 {
2400    uint8_t elemIdx = 0;
2401    RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP;
2402
2403    if(e2apMsg)
2404    {
2405       if(e2apMsg->choice.unsuccessfulOutcome)
2406       {
2407          ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
2408          if(ricSubscriptionFailure->protocolIEs.list.array)
2409          {
2410             for(elemIdx = 0; elemIdx < ricSubscriptionFailure->protocolIEs.list.count; elemIdx++)
2411             {
2412                DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t));
2413             }
2414             DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size);
2415          }
2416          DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
2417       }
2418       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2419    }
2420 }
2421
2422 /******************************************************************
2423  *
2424  * @brief Fill and Send RIC Subscription Failure to RIC
2425  *
2426  * @details
2427  *
2428  *    Function : BuildAndSendRicSubscriptionFailure
2429  *
2430  *    Functionality: Fill and Send RIC Subscription Failure to RIC
2431  *
2432  * @params[in] RIC Request ID
2433  *             RAN Function ID
2434  *             Cause of Failure
2435  * @return ROK     - success
2436  *         RFAILED - failure
2437  *
2438  * ****************************************************************/
2439 uint8_t BuildAndSendRicSubscriptionFailure(RicRequestId ricReqId, uint16_t ranFuncId, E2FailureCause failureCause)
2440 {
2441    uint8_t          ret = RFAILED;
2442    uint8_t          elementCnt = 0, elemIdx = 0;
2443    E2AP_PDU_t       *e2apMsg = NULLP;
2444    asn_enc_rval_t   encRetVal;        /* Encoder return value */
2445    RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP;
2446    RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
2447
2448    while(true)
2449    {
2450       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Failure\n");
2451
2452       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2453       if(e2apMsg == NULLP)
2454       {
2455          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
2456          break;
2457       }
2458
2459       e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome;
2460       DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
2461       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
2462       {
2463          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
2464          break;
2465       }
2466       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
2467       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
2468       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure;
2469
2470       ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
2471
2472       elementCnt = 3;
2473       ricSubscriptionFailure->protocolIEs.list.count = elementCnt;
2474       ricSubscriptionFailure->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionFailure_IEs_t *);
2475       DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size);
2476       if(!ricSubscriptionFailure->protocolIEs.list.array)
2477       {
2478          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
2479          break;
2480       }
2481
2482       for(elemIdx = 0; elemIdx < elementCnt; elemIdx++)
2483       {
2484          DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t));
2485          if(!ricSubscriptionFailure->protocolIEs.list.array[elemIdx])
2486          {
2487             DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d] for IE at index [%d]", \
2488                __func__, __LINE__, elemIdx);
2489             break;
2490          }
2491       }
2492       if(elemIdx < elementCnt)
2493          break;
2494
2495       elemIdx = 0;
2496
2497       /* RIC Request ID */
2498       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
2499       ricSubsFailIe->id = ProtocolIE_IDE2_id_RICrequestID;
2500       ricSubsFailIe->criticality = CriticalityE2_reject;
2501       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RICrequestID;
2502       ricSubsFailIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
2503       ricSubsFailIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
2504
2505       /* RAN Function ID */
2506       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
2507       ricSubsFailIe->id = ProtocolIE_IDE2_id_RANfunctionID;
2508       ricSubsFailIe->criticality = CriticalityE2_reject;
2509       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RANfunctionID;
2510       ricSubsFailIe->value.choice.RANfunctionID = ranFuncId;
2511
2512       /* Cause */
2513       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
2514       ricSubsFailIe->id = ProtocolIE_IDE2_id_CauseE2;
2515       ricSubsFailIe->criticality = CriticalityE2_reject;
2516       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_CauseE2;
2517       fillE2Cause(&ricSubsFailIe->value.choice.CauseE2, failureCause);
2518
2519       /* Prints the Msg formed */
2520       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2521       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2522       encBufSize = 0;
2523       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2524       if(encRetVal.encoded == ENCODE_FAIL)
2525       {
2526          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Failure Message (at %s)\n",\
2527                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2528          break;
2529       }
2530       else
2531       {
2532          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Failure Message \n");
2533 #ifdef DEBUG_ASN_PRINT
2534          for(int i=0; i< encBufSize; i++)
2535          {
2536             printf("%x",encBuf[i]);
2537          }
2538 #endif
2539       }
2540
2541       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
2542       {
2543          DU_LOG("\nINFO   -->  E2AP : Sending RIC Subscription Failure");
2544
2545       }
2546       ret = ROK;
2547       break;
2548    }
2549    FreeRicSubscriptionFailure(e2apMsg);
2550    return ret;
2551 }
2552
2553 /*******************************************************************
2554  *
2555  * @brief Free the RicIndication Message
2556  *
2557  * @details
2558  *
2559  *    Function : FreeRicIndication
2560  *
2561  * Functionality: Free the RicIndication Message
2562  *
2563  * @return void
2564  *         
2565  *
2566  ******************************************************************/
2567 void FreeRicIndication(E2AP_PDU_t  *e2apMsg) 
2568 {
2569    uint8_t idx = 0;
2570    RICindication_t *ricIndicationMsg= NULLP;
2571
2572    if(e2apMsg != NULLP)
2573    {
2574       if(e2apMsg->choice.initiatingMessage != NULLP)
2575       {
2576          ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
2577          if(ricIndicationMsg!= NULLP)
2578          {
2579             if(ricIndicationMsg->protocolIEs.list.array != NULLP)
2580             {
2581                for(idx=0; idx<ricIndicationMsg->protocolIEs.list.count; idx++)
2582                {
2583                   if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP)
2584                   {
2585                      switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
2586                      {
2587                         case ProtocolIE_IDE2_id_RICrequestID:
2588                            break;
2589
2590                         case ProtocolIE_IDE2_id_RANfunctionID:
2591                            break;
2592
2593                         case ProtocolIE_IDE2_id_RICactionID:
2594                            break;
2595
2596                         case ProtocolIE_IDE2_id_RICindicationType:
2597                            break;
2598
2599                         case ProtocolIE_IDE2_id_RICindicationHeader:
2600                            {
2601                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\
2602                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
2603                               break;
2604                            }
2605                         case ProtocolIE_IDE2_id_RICindicationMessage:
2606                            {
2607                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\
2608                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
2609                               break;
2610                            }
2611                         default:
2612                            break;
2613                      }
2614                      DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t));
2615                   }
2616                }
2617                DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size);
2618             }
2619          }
2620          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2621       }
2622       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2623    }
2624 }
2625
2626 /*******************************************************************
2627  *
2628  * brief Fill the RicIndication Message
2629  *
2630  * @details
2631  *
2632  *    Function : FillRicIndication
2633  *
2634  * Functionality:Fills the RicIndication Message
2635  *
2636  * @return ROK     - success
2637  *         RFAILED - failure
2638  *
2639  ******************************************************************/
2640 uint8_t FillRicIndication(RICindication_t *ricIndicationMsg, RicSubscription *ricSubscriptionInfo)
2641 {
2642    uint8_t elementCnt=0;
2643    uint8_t idx=0;
2644    uint8_t ret = ROK;
2645    elementCnt = 6;
2646
2647    ricIndicationMsg->protocolIEs.list.count = elementCnt;
2648    ricIndicationMsg->protocolIEs.list.size  = elementCnt * sizeof(RICindication_t);
2649    /* Initialize the Ric Indication members */
2650    DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, \
2651          ricIndicationMsg->protocolIEs.list.size);
2652    if(ricIndicationMsg->protocolIEs.list.array == NULLP)
2653    {
2654       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
2655       ret = RFAILED;
2656    }
2657    else
2658    {
2659       for(idx=0; idx<elementCnt; idx++)
2660       {
2661          DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx],\
2662                sizeof(RICindication_IEs_t));
2663          if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
2664          {
2665             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
2666             ret = RFAILED;
2667          }
2668       }
2669       if(ret != RFAILED)
2670       {
2671          idx = 0;
2672
2673          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
2674          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2675          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
2676                                                                         RICindication_IEs__value_PR_RICrequestID;
2677          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID =ricSubscriptionInfo->requestId.requestorId;
2678          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID = ricSubscriptionInfo->requestId.instanceId;
2679
2680          idx++;
2681          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
2682          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2683          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
2684                                                                         RICindication_IEs__value_PR_RANfunctionID;
2685          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = duCb.e2apDb.ranFunction[0].id;
2686
2687          idx++;
2688          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
2689          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2690          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
2691                                                                         RICindication_IEs__value_PR_RICactionID;
2692          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = ricSubscriptionInfo->actionSequence[0].id;
2693
2694          idx++;
2695          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
2696          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2697          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
2698                                                                         RICindication_IEs__value_PR_RICindicationType;
2699          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = ricSubscriptionInfo->actionSequence[0].type;
2700
2701          idx++;
2702          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
2703          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2704          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
2705                                                                         RICindication_IEs__value_PR_RICindicationHeader;
2706          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size = 3 *
2707             sizeof(uint8_t);
2708          DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf ,\
2709                ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
2710          if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf == NULLP)
2711          {
2712             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
2713             ret = RFAILED;
2714          }
2715          else
2716          {
2717             buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
2718                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf);
2719             idx++;
2720             /* TO BE CHANGED: RIC INDICATION DATA */
2721             /* For now filling a dummy octect data, need to tested with PRBs*/
2722             ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
2723             ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2724             ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
2725                                                                            RICindication_IEs__value_PR_RICindicationMessage;
2726             ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size = 3 *
2727                sizeof(uint8_t);
2728             DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf ,\
2729                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
2730             if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf == NULLP)
2731             {
2732                DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
2733                ret = RFAILED;
2734             }
2735             else
2736             {
2737                buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
2738                      ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf);
2739             }
2740          }
2741       }
2742    }
2743    return ret;
2744 }
2745
2746 /*******************************************************************
2747  *
2748  * @brief Builds and Send the RicIndication Message
2749  *
2750  * @details
2751  *
2752  *    Function : BuildAndSendRicIndication
2753  *
2754  * Functionality:Fills the RicIndication Message
2755  *
2756  * @return ROK     - success
2757  *         RFAILED - failure
2758  *
2759  ******************************************************************/
2760
2761 uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo)
2762 {
2763    E2AP_PDU_t                 *e2apMsg = NULLP;
2764    RICindication_t            *ricIndicationMsg=NULLP;
2765    asn_enc_rval_t             encRetVal;        /* Encoder return value */
2766    uint8_t ret = RFAILED; 
2767    uint8_t FillRicIndicationret = ROK;
2768
2769    while(true)
2770    {
2771       DU_LOG("\nINFO   -->  E2AP : Building RIC Indication Message\n");
2772
2773       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2774       if(e2apMsg == NULLP)
2775       {
2776          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2777          break;
2778       }
2779
2780       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
2781       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2782       if(e2apMsg->choice.initiatingMessage == NULLP)
2783       {
2784          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2785          break;
2786       }
2787       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
2788       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2789       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication;
2790
2791       ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
2792
2793       FillRicIndicationret = FillRicIndication(ricIndicationMsg, ricSubscriptionInfo);
2794       if(FillRicIndicationret != ROK)
2795       {
2796          break;
2797       }
2798       /* Prints the Msg formed */
2799       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2800       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2801       encBufSize = 0;
2802       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
2803             encBuf);
2804       if(encRetVal.encoded == ENCODE_FAIL)
2805       {
2806          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Indication Message (at %s)\n",\
2807                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2808          break;
2809       }
2810       else
2811       {
2812          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Indication Message \n");
2813 #ifdef DEBUG_ASN_PRINT
2814          for(int i=0; i< encBufSize; i++)
2815          {
2816             printf("%x",encBuf[i]);
2817          } 
2818 #endif
2819       }
2820
2821       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
2822       {
2823          DU_LOG("\nINFO   -->  E2AP : Sending RIC Indication Message");      
2824
2825       }
2826       ret = ROK;
2827       break;
2828    }
2829    FreeRicIndication(e2apMsg);  
2830    return ret;
2831 }
2832
2833 /*******************************************************************
2834  *
2835  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
2836  *
2837  * @details
2838  *
2839  *    Function : FreeE2NodeConfigUpdate 
2840  *
2841  *    Functionality:
2842  *       - freeing the memory allocated for E2nodeConfigurationUpdate
2843  *
2844  * @params[in] E2AP_PDU_t *e2apMsg 
2845  * @return ROK     - success
2846  *         RFAILED - failure
2847  *
2848  * ****************************************************************/
2849 void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg)
2850 {
2851    uint8_t arrIdx =0;
2852    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate;
2853
2854    if(e2apMsg != NULLP)
2855    {
2856       if(e2apMsg->choice.initiatingMessage != NULLP)
2857       {
2858          e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
2859          if(e2NodeConfigUpdate->protocolIEs.list.array != NULLP)
2860          {
2861             for(arrIdx = 0; arrIdx < e2NodeConfigUpdate->protocolIEs.list.count; arrIdx++)
2862             {
2863                DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
2864             }
2865             DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
2866          }
2867          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2868       }
2869       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2870    }
2871 }
2872
2873 /*******************************************************************
2874  *
2875  * @brief Buld and send the E2 node config update msg 
2876  *
2877  * @details
2878  *
2879  *    Function : BuildAndSendE2NodeConfigUpdate
2880  *
2881  *    Functionality:
2882  *         - Buld and send the E2 node config update msg
2883  *
2884  * @params[in] 
2885  * @return ROK     - success
2886  *         RFAILED - failure
2887  *
2888  * ****************************************************************/
2889
2890 uint8_t BuildAndSendE2NodeConfigUpdate()
2891 {
2892    uint8_t arrIdx = 0,elementCnt = 1;
2893    uint8_t ret = ROK;
2894    E2AP_PDU_t        *e2apMsg = NULLP;
2895    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate = NULLP;
2896    asn_enc_rval_t     encRetVal;       /* Encoder return value */
2897
2898    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update\n");
2899    do
2900    {
2901       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2902       if(e2apMsg == NULLP)
2903       {
2904          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2905          break;
2906       }
2907       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
2908       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2909       if(e2apMsg->choice.initiatingMessage == NULLP)
2910       {
2911          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2912          DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2913          return RFAILED;
2914       }
2915       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2916       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
2917       e2apMsg->choice.initiatingMessage->value.present = \
2918       InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate;
2919       e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
2920
2921       e2NodeConfigUpdate->protocolIEs.list.count = elementCnt;
2922       e2NodeConfigUpdate->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdate_IEs_t*);
2923       /* Initialize the Ric Indication members */
2924       DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array, \
2925             e2NodeConfigUpdate->protocolIEs.list.size);
2926       if(e2NodeConfigUpdate->protocolIEs.list.array == NULLP)
2927       {
2928          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
2929          break;
2930       }
2931       
2932       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
2933       {
2934          DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
2935          if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx] == NULLP)
2936          {
2937             
2938             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
2939             break;
2940          }
2941       }
2942
2943       arrIdx = 0;
2944       /* TransactionID */
2945       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2946       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2947       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_TransactionID;
2948       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = TRANS_ID;
2949
2950
2951       /* Prints the Msg formed */
2952       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2953
2954       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2955       encBufSize = 0;
2956       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
2957             encBuf);
2958       if(encRetVal.encoded == ENCODE_FAIL)
2959       {
2960          DU_LOG("\nERROR  -->  E2AP : Could not encode E2nodeConfigurationUpdate structure (at %s)\n",\
2961                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2962          break;
2963       }
2964       else
2965       {
2966          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2nodeConfigurationUpdate\n");
2967 #ifdef DEBUG_ASN_PRINT
2968          for(int i=0; i< encBufSize; i++)
2969          {
2970             printf("%x",encBuf[i]);
2971          }
2972 #endif
2973       }
2974       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize))
2975       {
2976          DU_LOG("\nERROR  -->  E2AP : Sending E2 node config update failed");
2977          return RFAILED;
2978       }
2979
2980       break;
2981    }while(true);
2982    
2983    FreeE2NodeConfigUpdate(e2apMsg);
2984    return ret;
2985 }
2986
2987 /*******************************************************************
2988  *
2989  * @brief Deallocate the memory allocated for E2ResetRequest msg
2990  *
2991  * @details
2992  *
2993  *    Function : FreeE2ResetRequest
2994  *
2995  *    Functionality:
2996  *       - freeing the memory allocated for E2ResetRequest
2997  *
2998  * @params[in] E2AP_PDU_t *e2apMsg
2999  * @return ROK     - success
3000  *         RFAILED - failure
3001  *
3002  * ****************************************************************/
3003 void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg)
3004 {
3005    uint8_t ieIdx =0;
3006    ResetRequestE2_t  *resetReq = NULLP;
3007
3008    if(e2apMsg != NULLP)
3009    {
3010       if(e2apMsg->choice.initiatingMessage != NULLP)
3011       {
3012          resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
3013          if(resetReq->protocolIEs.list.array)
3014          {
3015             for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
3016             {
3017                DU_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
3018             }
3019             DU_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
3020          }
3021          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3022       }
3023       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3024    }
3025 }
3026
3027 /*******************************************************************
3028  *
3029  * @brief Build and send the E2 reset request msg
3030  *
3031  * @details
3032  *
3033  *    Function : BuildAndSendE2ResetRequest
3034  *
3035  *    Functionality:
3036  *         - Buld and send the E2 reset request msg to RIC
3037  *
3038  * @params[in]
3039  * @return ROK     - success
3040  *         RFAILED - failure
3041  *
3042  * ****************************************************************/
3043 uint8_t BuildAndSendE2ResetRequest(E2FailureCause resetCause)
3044 {
3045    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
3046    uint8_t ret = RFAILED;
3047    E2AP_PDU_t        *e2apMsg = NULLP;
3048    ResetRequestE2_t  *resetReq = NULLP;
3049    asn_enc_rval_t     encRetVal;       /* Encoder return value */
3050
3051    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Request\n");
3052
3053    do
3054    {
3055       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3056       if(e2apMsg == NULLP)
3057       {
3058          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for E2AP-PDU failed");
3059          break;
3060       }
3061
3062       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
3063       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3064       if(e2apMsg->choice.initiatingMessage == NULLP)
3065       {
3066          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for initiatingMessage");
3067          break;
3068       }
3069
3070       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
3071       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
3072       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
3073       resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
3074
3075       elementCnt = 2;
3076       resetReq->protocolIEs.list.count = elementCnt;
3077       resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
3078
3079       DU_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
3080       if(!resetReq->protocolIEs.list.array)
3081       {
3082          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
3083             Reset Request IE array");
3084          break;
3085       }
3086
3087       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
3088       {
3089          DU_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
3090          if(!resetReq->protocolIEs.list.array[ieIdx])
3091          {
3092             DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
3093             Reset Request IE array element");
3094             break;
3095          }
3096       }
3097
3098       /* In case of failure */
3099       if(ieIdx < elementCnt)
3100          break;
3101
3102       ieIdx = 0;
3103       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
3104       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
3105       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
3106       transId = assignTransactionId();
3107       resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
3108
3109       ieIdx++;
3110       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
3111       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
3112       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
3113       fillE2Cause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, resetCause);
3114
3115       /* Prints the Msg formed */
3116       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3117
3118       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3119       encBufSize = 0;
3120       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
3121             encBuf);
3122       if(encRetVal.encoded == ENCODE_FAIL)
3123       {
3124          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupRequest structure (at %s)\n",\
3125                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3126          break;
3127       }
3128       else
3129       {
3130          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2SetupRequest\n");
3131 #ifdef DEBUG_ASN_PRINT
3132          for(int i=0; i< encBufSize; i++)
3133          {
3134             printf("%x",encBuf[i]);
3135          }
3136 #endif
3137       }
3138       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
3139       {
3140          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
3141          break;
3142       }
3143
3144       /* In case the message is sent successfully, store the transaction info to
3145        * be used when response is received */
3146       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
3147       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
3148
3149       ret = ROK;
3150       break;
3151    }while(true);
3152
3153    /* Free all memory */
3154    FreeE2ResetRequest(e2apMsg);
3155    return ret;
3156 }
3157
3158 /*******************************************************************
3159  *
3160  * @brief Deallocate the memory allocated for Reset Response msg
3161  *
3162  * @details
3163  *
3164  *    Function : freeAperDecodingOfE2ResetRsp
3165  *
3166  *    Functionality:
3167  *       - freeing the memory allocated for Reset response
3168  *
3169  * @params[in] ResetResponseE2_t *resetResponse
3170  * @return void
3171  *
3172  * ****************************************************************/
3173 void freeAperDecodingOfE2ResetRsp(ResetResponseE2_t *resetResponse)
3174 {
3175    uint8_t ieIdx;
3176
3177    if(resetResponse)
3178    {
3179       if(resetResponse->protocolIEs.list.array)
3180       {
3181          for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
3182          {
3183             if(resetResponse->protocolIEs.list.array[ieIdx])
3184             {
3185                switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
3186                {
3187                   case ProtocolIE_IDE2_id_TransactionID:
3188                      break;
3189
3190                   case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
3191                      break;
3192                }
3193                free(resetResponse->protocolIEs.list.array[ieIdx]);
3194             }
3195          }
3196          free(resetResponse->protocolIEs.list.array);
3197       }
3198    }
3199 }
3200
3201 /******************************************************************
3202  *
3203  * @brief Processes E2 Reset Response sent by RIC
3204  *
3205  * @details
3206  *
3207  *    Function : procResetResponse
3208  *
3209  *    Functionality: Processes E2 Reset Response sent by RIC
3210  *
3211  * @params[in] E2AP_PDU_t ASN decoded E2AP message
3212  * @return ROK     - success
3213  *         RFAILED - failure
3214  *
3215  * ****************************************************************/
3216 uint8_t procResetResponse(E2AP_PDU_t *e2apMsg)
3217 {
3218    uint8_t ieIdx =0, transId;
3219    ResetResponseE2_t *resetResponse;
3220
3221    DU_LOG("\nINFO   -->  E2AP : E2 Reset Response received");
3222    resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;;
3223
3224    for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
3225    {
3226       switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
3227       {
3228          case ProtocolIE_IDE2_id_TransactionID:
3229             transId = resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
3230             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) && \
3231                   (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
3232             {
3233                memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
3234             }
3235             else
3236             {
3237                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
3238                return RFAILED;
3239             }
3240             break;
3241          case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
3242             /* As per ORAN WG3 E2AP spec v3.0, section 9.2.2
3243                Criticality Diagnostics IE is sent by Near-RT RIC when parts of a received message i.e. 
3244                Reset Request in this case, have not been comprehended or were missing, or if the message 
3245                contained logical errors.
3246
3247                Processing of this ID should be implemented when negative call flows are to be supported.
3248              */
3249             break;
3250          default:
3251             DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2 Reset Response : %ld",
3252                   resetResponse->protocolIEs.list.array[ieIdx]->id);
3253             break;
3254       }
3255    }
3256
3257    freeAperDecodingOfE2ResetRsp(resetResponse);
3258    return ROK;
3259 }
3260
3261 /******************************************************************
3262  *
3263  * @brief Deallocation of memory allocated bu aper decoder for e2 setup Failure
3264  *
3265  * @details
3266  *
3267  *    Function : freeAperDecodingOfE2SetupFailure
3268  *
3269  *    Functionality: Deallocation of memory allocated bu aper decoder for e2
3270  *    setup Failure
3271  *
3272  * @params[in] E2setupFailure_t *e2SetupFailure;
3273  * @return void
3274  *
3275  * ****************************************************************/
3276 void freeAperDecodingOfE2SetupFailure(E2setupFailure_t *e2SetupFailure)
3277 {
3278    uint8_t arrIdx;
3279
3280    if(e2SetupFailure)
3281    {
3282       if(e2SetupFailure->protocolIEs.list.array)
3283       {
3284          for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
3285          {
3286             if(e2SetupFailure->protocolIEs.list.array[arrIdx])
3287             {
3288                free(e2SetupFailure->protocolIEs.list.array[arrIdx]);  
3289             }
3290          }
3291          free(e2SetupFailure->protocolIEs.list.array);
3292       }
3293    }
3294 }
3295 /******************************************************************
3296  *
3297  * @brief Processes E2 Setup Failure sent by RIC
3298  *
3299  * @details
3300  *
3301  *    Function : procE2SetupFailure
3302  *
3303  *    Functionality: Processes E2 Setup failure sent by RIC
3304  *
3305  * @params[in] E2AP_PDU_t ASN decoded E2AP message
3306  * @return ROK     - success
3307  *         RFAILED - failure
3308  *
3309  * ****************************************************************/
3310 void procE2SetupFailure(E2AP_PDU_t *e2apMsg)
3311 {
3312    uint8_t arrIdx =0, transId =0, timerValue=0; 
3313    E2setupFailure_t *e2SetupFailure;
3314
3315    DU_LOG("\nINFO   -->  E2AP : E2 Setup failure received"); 
3316    e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
3317
3318    for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
3319    {
3320       switch(e2SetupFailure->protocolIEs.list.array[arrIdx]->id)
3321       {
3322          case ProtocolIE_IDE2_id_TransactionID:
3323          {
3324             transId = e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
3325             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
3326                   (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
3327             {
3328                memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
3329             }
3330             else
3331             {
3332                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
3333                return ;
3334             }
3335             break;
3336          }
3337          case ProtocolIE_IDE2_id_TimeToWaitE2:
3338             {
3339                timerValue = covertE2WaitTimerEnumToValue(e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
3340                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR)) == FALSE)
3341                {
3342                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR, timerValue);
3343                }
3344                else
3345                {
3346                   DU_LOG("\nERROR   -->  E2AP : EVENT_E2_SETUP_TMR timer is already running");
3347                   return;
3348                }
3349                break; 
3350             }
3351       }
3352    }
3353
3354    freeAperDecodingOfE2SetupFailure(e2SetupFailure);
3355 }
3356 /******************************************************************
3357  *
3358  * @brief Deallocation of memory allocated bu aper decoder for RIC service Query
3359  *
3360  * @details
3361  *
3362  *    Function : freeAperDecodingOfRicServiceQuery
3363  *
3364  *    Functionality: Deallocation of memory allocated bu aper decoder for RIC
3365  *    service Query
3366  *
3367  * @params[in] RICserviceQuery_t *ricServiceQuery;
3368  * @return void
3369  *
3370  * ****************************************************************/
3371
3372 void freeAperDecodingOfRicServiceQuery(RICserviceQuery_t *ricServiceQuery)
3373 {
3374    uint8_t arrIdx,ranFuncIdx;
3375     RANfunctionsID_List_t *ranFuncAddedList;
3376
3377    if(ricServiceQuery)
3378    {
3379       if(ricServiceQuery->protocolIEs.list.array)
3380       {
3381          for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
3382          {
3383             if(ricServiceQuery->protocolIEs.list.array[arrIdx])
3384             {
3385                switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
3386                {
3387                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
3388                   {
3389                      ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
3390                      if(ranFuncAddedList->list.array)
3391                      {
3392                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
3393                         {
3394                            free(ranFuncAddedList->list.array[ranFuncIdx]);
3395                         }
3396                         free(ranFuncAddedList->list.array);;
3397                      }
3398                      break;
3399                   }
3400                   default:
3401                      break;
3402                }
3403                free(ricServiceQuery->protocolIEs.list.array[arrIdx]);
3404             }
3405          }
3406          free(ricServiceQuery->protocolIEs.list.array);
3407       }
3408    }
3409 }
3410 /*******************************************************************
3411  *
3412  * @brief Build RanFunction Delete List
3413  *
3414  * @details
3415  *
3416  *    Function : BuildRanFunctionDeleteList
3417  *
3418  * Functionality:  Build RanFunction Delete List
3419  *
3420  * @params[in]
3421  *    RANfunctionsID List
3422  *    Count of the RAN function
3423  *    Received RAN function list
3424  *
3425  * @return ROK     - success
3426  *         RFAILED - failure
3427  *
3428  ******************************************************************/
3429
3430 uint8_t BuildRanFunctionDeleteList(RANfunctionsID_List_t *deleteList, uint8_t count, RanFuncInfo *recvdRanFunc)
3431 {
3432    uint8_t ranFuncIdx=0;
3433    RANfunctionID_ItemIEs_t *delRanFuncItem;
3434
3435    if(count)
3436    {
3437       deleteList->list.count = count;
3438       deleteList->list.size = deleteList->list.count * sizeof(RANfunctionID_ItemIEs_t*);
3439       DU_ALLOC(deleteList->list.array, deleteList->list.size);
3440       if(deleteList->list.array == NULLP)
3441       {
3442          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
3443          return RFAILED;
3444       }
3445       for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
3446       {
3447          DU_ALLOC(deleteList->list.array[ranFuncIdx], sizeof(RANfunctionID_ItemIEs_t));
3448          if(deleteList->list.array[ranFuncIdx] == NULLP)
3449          {
3450             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
3451             return RFAILED;
3452          }
3453          delRanFuncItem= (RANfunctionID_ItemIEs_t *) deleteList->list.array[ranFuncIdx];
3454          delRanFuncItem->id = ProtocolIE_IDE2_id_RANfunctionID_Item;
3455          delRanFuncItem->criticality = CriticalityE2_ignore;
3456          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionID = recvdRanFunc[ranFuncIdx].id;
3457          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionRevision = recvdRanFunc[ranFuncIdx].revisionCounter;
3458
3459       }
3460    }
3461    return ROK;
3462 }
3463 /*******************************************************************
3464  *
3465  * @brief De Allocate  Ric Service Update message
3466  *
3467  * @details
3468  *
3469  *    Function : FreeRicServiceUpdate
3470  *
3471  *    Functionality: De-Allocating Ric Service Update message
3472  *
3473  * @params[in] E2AP_PDU_t *e2apMsg
3474
3475  * @return void
3476  *
3477  * ****************************************************************/
3478
3479 void FreeRicServiceUpdate(E2AP_PDU_t *e2apMsg)
3480 {
3481    uint8_t arrIdx = 0;
3482    uint8_t ranFuncAddListIdx=0, ranFuncDelIdx=0;
3483    RICserviceUpdate_t *ricServiceUpdate;
3484    RANfunctions_List_t *ranFunctionsList;
3485    RANfunction_ItemIEs_t *ranFuncItemIe;
3486    RANfunction_Item_t  *ranFunItem;
3487    RANfunctionsID_List_t *deleteList;
3488
3489    /* De-allocating Memory */
3490    if(e2apMsg != NULLP)
3491    {
3492       if(e2apMsg->choice.initiatingMessage != NULLP)
3493       {
3494          ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
3495          if(ricServiceUpdate->protocolIEs.list.array != NULLP)
3496          {
3497             for(arrIdx = 0; arrIdx < ricServiceUpdate->protocolIEs.list.count; arrIdx++)
3498             {
3499                if(ricServiceUpdate->protocolIEs.list.array[arrIdx] != NULLP)
3500                {
3501                   switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
3502                   {
3503                      case ProtocolIE_IDE2_id_TransactionID:
3504                         break;
3505
3506                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
3507                      case ProtocolIE_IDE2_id_RANfunctionsModified:
3508                         {
3509                            ranFunctionsList = &(ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List);
3510                            if(ranFunctionsList->list.array)
3511                            {
3512                               for(ranFuncAddListIdx= 0; ranFuncAddListIdx< ranFunctionsList->list.count; ranFuncAddListIdx++)
3513                               {
3514                                  if(ranFunctionsList->list.array[ranFuncAddListIdx])
3515                                  {
3516                                     ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncAddListIdx];
3517                                     ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
3518                                     DU_FREE(ranFunItem->ranFunctionOID.buf, ranFunItem->ranFunctionOID.size);
3519                                     DU_FREE(ranFunItem->ranFunctionDefinition.buf, ranFunItem->ranFunctionDefinition.size);
3520                                     DU_FREE(ranFunctionsList->list.array[ranFuncAddListIdx], sizeof(RANfunction_ItemIEs_t));
3521                                  }
3522                               }
3523                               DU_FREE(ranFunctionsList->list.array, ranFunctionsList->list.size);
3524                            }
3525                            break;
3526                         }
3527                      case ProtocolIE_IDE2_id_RANfunctionsDeleted:
3528                         {
3529                            deleteList= &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
3530                            if(deleteList->list.array)
3531                            {
3532                               for(ranFuncDelIdx = 0; ranFuncDelIdx< deleteList->list.count; ranFuncDelIdx++)
3533                               {
3534                                  DU_FREE(deleteList->list.array[ranFuncDelIdx], sizeof(RANfunctionID_ItemIEs_t));
3535                               }
3536                               DU_FREE(deleteList->list.array, deleteList->list.size);
3537   
3538                            }
3539                            break;
3540                         }
3541                      default:
3542                         DU_LOG("\nERROR  --> E2AP: Invalid event at ricServiceUpdate %ld ",\
3543                               (ricServiceUpdate->protocolIEs.list.array[arrIdx]->id));
3544                         break;
3545                   }
3546                   DU_FREE(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
3547                }
3548             }
3549             DU_FREE(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
3550          }
3551          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3552       }
3553       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3554    }
3555 }
3556
3557 /*******************************************************************
3558  *
3559  * @brief Builds and Send the RicServiceUpdateuest
3560  *
3561  * @details
3562  *
3563  *    Function : BuildAndSendRicServiceUpdate
3564  *
3565  * Functionality:Fills the RicServiceUpdateuest
3566  *
3567  * @return ROK     - success
3568  *         RFAILED - failure
3569  *
3570  ******************************************************************/
3571
3572 uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate)
3573 {
3574    uint8_t arrIdx = 0, elementCnt=0;
3575    uint8_t transId = 0, ret = RFAILED;
3576    bool memAllocFailed =false;
3577    E2AP_PDU_t        *e2apMsg = NULLP;
3578    RICserviceUpdate_t  *ricServiceUpdate = NULLP;
3579    asn_enc_rval_t     encRetVal;       /* Encoder return value */
3580
3581    DU_LOG("\nINFO   -->  E2AP : Building Ric Service Update\n");
3582    do
3583    {
3584       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3585       if(e2apMsg == NULLP)
3586       {
3587          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
3588          break;
3589       }
3590       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
3591       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3592       if(e2apMsg->choice.initiatingMessage == NULLP)
3593       {
3594          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
3595          break;
3596       }
3597       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
3598       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
3599       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceUpdate;
3600       ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
3601       
3602       /* For TransId IE, set elementCnt to 1.
3603       If there is any item in the RAN function add list, RAN function modification list, or RAN function delete list, increment the elementCnt.*/
3604
3605       elementCnt =1;
3606       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
3607         elementCnt++;
3608       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
3609          elementCnt++;
3610       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
3611          elementCnt++;
3612        
3613       ricServiceUpdate->protocolIEs.list.count = elementCnt;
3614       ricServiceUpdate->protocolIEs.list.size = elementCnt * sizeof(RICserviceUpdate_IEs_t*);
3615
3616       /* Initialize the E2Setup members */
3617       DU_ALLOC(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
3618       if(ricServiceUpdate->protocolIEs.list.array == NULLP)
3619       {
3620          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
3621          break;
3622       }
3623       
3624       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
3625       {
3626          DU_ALLOC(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
3627          if(ricServiceUpdate->protocolIEs.list.array[arrIdx] == NULLP)
3628          {
3629             memAllocFailed = true;
3630             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayIdx [%d]", arrIdx);
3631             break;
3632          }
3633       }
3634       if(memAllocFailed == true)
3635          break;
3636
3637       arrIdx = 0;
3638
3639       /* TransactionID */
3640       ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
3641       ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3642       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
3643       if(serviceUpdate.dir == E2_NODE_INITIATED)
3644          transId = assignTransactionId();
3645       else
3646         transId = serviceUpdate.transId;
3647       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
3648
3649       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
3650       {
3651          arrIdx++;
3652          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAdded;
3653          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3654          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
3655          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,\
3656          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded, serviceUpdate.recvRanFuncList.ranFunToBeAdded) !=ROK)
3657          {
3658             break;
3659          }
3660       }
3661
3662       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
3663       {
3664          arrIdx++;
3665          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsModified;
3666          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3667          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
3668          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,
3669          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeModified, serviceUpdate.recvRanFuncList.ranFunToBeModified) !=ROK)
3670          {
3671             break;
3672          }
3673       }
3674
3675       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
3676       {
3677          arrIdx++;
3678          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsDeleted;
3679          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3680          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctionsID_List;
3681          if(BuildRanFunctionDeleteList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List,\
3682          serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted, serviceUpdate.recvRanFuncList.ranFunToBeDeleted) != ROK)
3683          {
3684             break;
3685          }
3686       }
3687       /* Prints the Msg formed */
3688       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3689
3690       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3691       encBufSize = 0;
3692       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3693       if(encRetVal.encoded == ENCODE_FAIL)
3694       {
3695          DU_LOG("\nERROR  -->  E2AP : Could not encode RicServiceUpdateuest structure (at %s)\n",\
3696                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3697          break;
3698       }
3699       else
3700       {
3701          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RicServiceUpdateuest\n");
3702 #ifdef DEBUG_ASN_PRINT
3703          for(int i=0; i< encBufSize; i++)
3704          {
3705             printf("%x",encBuf[i]);
3706          }
3707 #endif
3708       }
3709       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
3710       {
3711          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
3712          break;
3713       }
3714       ret = ROK;
3715       break;
3716    }while(true);
3717    
3718    if(ret == ROK)
3719    {
3720       if(serviceUpdate.dir == E2_NODE_INITIATED)
3721       {
3722          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
3723          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
3724       }
3725       else
3726       {
3727          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId = transId;
3728          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
3729       }
3730       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.dir = serviceUpdate.dir;
3731       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.transId =transId;
3732       memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.recvRanFuncList, &serviceUpdate.recvRanFuncList, sizeof(E2TmpRanFunList));
3733    }
3734    FreeRicServiceUpdate(e2apMsg);
3735    return ret;
3736 }
3737 /******************************************************************
3738  *
3739  * @brief Processes RIC service Query sent by RIC
3740  *
3741  * @details
3742  *
3743  *    Function : procRicServiceQuery
3744  *
3745  *    Functionality: Processes RIC service Query sent by RIC
3746  *
3747  * @params[in] E2AP_PDU_t ASN decoded E2AP message
3748  * @return ROK     - success
3749  *         RFAILED - failure
3750  *
3751  * ****************************************************************/
3752
3753 void procRicServiceQuery(E2AP_PDU_t *e2apMsg)
3754 {
3755    ConfigType action;
3756    uint16_t arrIdx =0, ranFuncIdx=0,tmpIdx=0;
3757    uint16_t id,revisionCcounter;
3758    bool tmpArray[MAX_RAN_FUNCTION] = {false};
3759    RICserviceQuery_t *ricServiceQuery=NULL;
3760    RicServiceUpdate ricUpdate;
3761    RANfunctionID_ItemIEs_t *ranFuncAddedItemIe;
3762    RANfunctionsID_List_t *ranFuncAddedList;
3763
3764    DU_LOG("\nINFO   -->  E2AP : RIC Service Query received");
3765    memset(&ricUpdate, 0, sizeof(RicServiceUpdate));
3766    ricUpdate.dir = RIC_INITIATED;
3767    ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
3768
3769    for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
3770    {
3771       switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
3772       {
3773          /* TODO completing in next patch/gerrit */
3774          case ProtocolIE_IDE2_id_TransactionID:
3775          {
3776             ricUpdate.transId = ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
3777             break;
3778          }
3779
3780          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
3781          {
3782             ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
3783             if(ranFuncAddedList->list.array)
3784             {
3785                for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
3786                {
3787                   if(ranFuncAddedList->list.array[ranFuncIdx])
3788                   {
3789                      /* Using the RAN function Id, identify the RAN function to be modified or deleted.  */
3790                      
3791                      ranFuncAddedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAddedList->list.array[ranFuncIdx];
3792                      id = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionID;
3793                      revisionCcounter = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision;
3794                      
3795                      if((id != duCb.e2apDb.ranFunction[id-1].id))
3796                      {
3797                         action = CONFIG_DEL;
3798                      }
3799                      else if((id == duCb.e2apDb.ranFunction[id-1].id)&&(revisionCcounter!=duCb.e2apDb.ranFunction[id-1].revisionCounter))
3800                      {
3801                         action = CONFIG_MOD;
3802                      }
3803
3804                      if(action == CONFIG_DEL)
3805                      {
3806                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].id = id;
3807                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].revisionCounter = revisionCcounter;
3808                         ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted++;
3809                      }
3810                      else if(action == CONFIG_MOD)
3811                      {
3812                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].id = id;
3813                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].revisionCounter = revisionCcounter;
3814                         ricUpdate.recvRanFuncList.numOfRanFunToBeModified++;
3815                      }
3816
3817                      /* If any ID is set to true, it means that the ID has been used in either modification or deletion list. 
3818                       * Else we will add the IDs into the added list */
3819                      tmpArray[id-1] = true;
3820                   }
3821                }
3822             }
3823             break;
3824          }
3825       }
3826    }
3827
3828    /*  Traversing the whole RAN function list in ducb to check if any new Ran function ids have been added. */
3829    for(arrIdx =0; arrIdx<MAX_RAN_FUNCTION; arrIdx++)
3830    {
3831       tmpIdx= ricUpdate.recvRanFuncList.numOfRanFunToBeAdded;
3832       if((duCb.e2apDb.ranFunction[arrIdx].id >0)&&(!tmpArray[arrIdx]))
3833       {
3834          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[arrIdx].id;
3835          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[arrIdx].revisionCounter;
3836          ricUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
3837       }
3838    }
3839
3840    if(BuildAndSendRicServiceUpdate(ricUpdate)!= ROK)
3841    {
3842       DU_LOG("\nERROR  -->  E2AP : Failed to build and send ric service update message");
3843    }
3844
3845    freeAperDecodingOfRicServiceQuery(ricServiceQuery);
3846 }
3847
3848 /******************************************************************
3849  *
3850  * @brief Deallocation of memory allocated by aper decoder for 
3851  *    RIC service update ack
3852  *
3853  * @details
3854  *
3855  *    Function : freeAperDecodingOfRicServiceUpdateAck
3856  *
3857  *    Functionality: Deallocation of memory allocated by aper decoder 
3858  *    for RIC service update ack
3859  *
3860  * @params[in] RICserviceUpdateAck_t *ricServiceAck;
3861  * @return void
3862  *
3863  * ****************************************************************/
3864
3865 void freeAperDecodingOfRicServiceUpdateAck(RICserviceUpdateAcknowledge_t *ricServiceAck)
3866 {
3867    uint8_t arrIdx=0,ranFuncIdx=0;
3868    RANfunctionsID_List_t *ranFuncAddedList=NULL;
3869
3870    if(ricServiceAck)
3871    {
3872       if(ricServiceAck->protocolIEs.list.array)
3873       {
3874          for(arrIdx=0; arrIdx<ricServiceAck->protocolIEs.list.count; arrIdx++)
3875          {
3876             if(ricServiceAck->protocolIEs.list.array[arrIdx])
3877             {
3878                switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id)
3879                {
3880                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
3881                   {
3882                      ranFuncAddedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
3883                      if(ranFuncAddedList->list.array)
3884                      {
3885                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
3886                         {
3887                            free(ranFuncAddedList->list.array[ranFuncIdx]);
3888                         }
3889                         free(ranFuncAddedList->list.array);
3890                      }
3891                      break;
3892                   }
3893                   default:
3894                      break;
3895                }
3896                free(ricServiceAck->protocolIEs.list.array[arrIdx]);  
3897             }
3898          }
3899          free(ricServiceAck->protocolIEs.list.array);
3900       }
3901    }
3902 }
3903
3904 /******************************************************************
3905  *
3906  * @brief Processes RIC service update ack sent by RIC
3907  *
3908  * @details
3909  *
3910  *    Function : procRicServiceUpdateAck
3911  *
3912  *    Functionality: Processes RIC service update ack sent by RIC
3913  *
3914  * @params[in] E2AP_PDU_t ASN decoded E2AP message
3915  * @return ROK     - success
3916  *         RFAILED - failure
3917  *
3918  * ****************************************************************/
3919
3920 void procRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
3921 {
3922    uint8_t arrIdx =0, transId =0; 
3923    uint16_t id =0, tmpIdx=0, ranFuncIdx=0;
3924    RicServiceUpdate serviceUpdate;
3925    RANfunctionsIDcause_List_t *rejectedList=NULL;
3926    RICserviceUpdateAcknowledge_t *ricServiceAck=NULL;
3927    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
3928    
3929    DU_LOG("\nINFO   -->  E2AP : RIC service update ack received"); 
3930    memset(&serviceUpdate, 0, sizeof(RicServiceUpdate));
3931    ricServiceAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
3932    
3933    for(arrIdx=0; arrIdx<ricServiceAck->protocolIEs.list.count; arrIdx++)
3934    {
3935       switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id)
3936       {
3937          case ProtocolIE_IDE2_id_TransactionID:
3938          {
3939             transId = ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
3940             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
3941             (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
3942             {
3943               memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
3944             }
3945             else if((duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId == transId) &&\
3946             (duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
3947             {
3948               memset(&duCb.e2apDb.e2TransInfo.ricInitTransaction[transId], 0, sizeof(E2TransInfo));
3949             }
3950             else
3951             {
3952                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
3953                return ;
3954             }
3955             break;
3956          }
3957          
3958          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
3959             break;
3960
3961          case ProtocolIE_IDE2_id_RANfunctionsRejected:
3962          {
3963             rejectedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
3964             if(rejectedList->list.array)
3965             {
3966                for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
3967                {
3968                   ranFuncRejectedItemIe =  (RANfunctionIDcause_ItemIEs_t*)rejectedList->list.array[ranFuncIdx];
3969                   id = ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID;
3970                   tmpIdx= serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded;
3971                   serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[id-1].id;
3972                   serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[id-1].revisionCounter;
3973                   serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
3974                }
3975             }
3976             break;
3977          }
3978
3979       }
3980    }
3981
3982    if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
3983    {
3984       serviceUpdate.dir = E2_NODE_INITIATED;
3985       BuildAndSendRicServiceUpdate(serviceUpdate);
3986    }
3987    freeAperDecodingOfRicServiceUpdateAck(ricServiceAck);
3988 }
3989
3990 /******************************************************************
3991  *
3992  * @brief Deallocation of memory allocated by aper decoder for 
3993  *       RIC service update failure
3994  *
3995  * @details
3996  *
3997  *    Function : freeAperDecodingOfRicServiceUpdateFailure
3998  *
3999  *    Functionality: Deallocation of memory allocated by aper decoder 
4000  *    for RIC service update failure
4001  *
4002  * @params[in] RICserviceUpdateFailure_t *ricServiceFailure;
4003  * @return void
4004  *
4005  * ****************************************************************/
4006
4007 void freeAperDecodingOfRicServiceUpdateFailure(RICserviceUpdateFailure_t *ricServiceFailure)
4008 {
4009    uint8_t arrIdx=0;
4010
4011    if(ricServiceFailure)
4012    {
4013       if(ricServiceFailure->protocolIEs.list.array)
4014       {
4015          for(arrIdx=0; arrIdx<ricServiceFailure->protocolIEs.list.count; arrIdx++)
4016          {
4017             if(ricServiceFailure->protocolIEs.list.array[arrIdx])
4018             {
4019                free(ricServiceFailure->protocolIEs.list.array[arrIdx]);  
4020             }
4021          }
4022          free(ricServiceFailure->protocolIEs.list.array);
4023       }
4024    }
4025 }
4026
4027 /******************************************************************
4028  *
4029  * @brief Processes RIC service update failure sent by RIC
4030  *
4031  * @details
4032  *
4033  *    Function : procRicServiceUpdateFailure
4034  *
4035  *    Functionality: Processes RIC service update failure sent by RIC
4036  *
4037  * @params[in] E2AP_PDU_t ASN decoded E2AP message
4038  * @return ROK     - success
4039  *         RFAILED - failure
4040  *
4041  * ****************************************************************/
4042
4043 void procRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
4044 {
4045    uint8_t arrIdx =0, timerValue=0; 
4046    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
4047
4048    DU_LOG("\nINFO   -->  E2AP : RIC service update failure received"); 
4049    ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
4050
4051    for(arrIdx=0; arrIdx<ricServiceFailure->protocolIEs.list.count; arrIdx++)
4052    {
4053       switch(ricServiceFailure->protocolIEs.list.array[arrIdx]->id)
4054       {
4055          case ProtocolIE_IDE2_id_TransactionID:
4056             {
4057                break;
4058             }
4059          case ProtocolIE_IDE2_id_TimeToWaitE2:
4060             {
4061                timerValue = covertE2WaitTimerEnumToValue(ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
4062                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR)) == FALSE)
4063                {
4064                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR, timerValue);
4065                }
4066                else
4067                {
4068                   DU_LOG("\nERROR   -->  E2AP : EVENT_RIC_SERVICE_UPDATE_TMR  timer is already running");
4069                   return;
4070                }
4071                break; 
4072             }
4073          case ProtocolIE_IDE2_id_CauseE2:
4074             {
4075                break;
4076             }
4077       }
4078    }
4079
4080    freeAperDecodingOfRicServiceUpdateFailure(ricServiceFailure);
4081 }
4082
4083 /*******************************************************************
4084  *
4085  * @brief Handles received E2AP message and sends back response  
4086  *
4087  * @details
4088  *
4089  *    Function : E2APMsgHdlr
4090  *
4091  *    Functionality:
4092  *         - Decodes received E2AP control message
4093  *         - Prepares response message, encodes and sends to SCTP
4094  *
4095  * @params[in] 
4096  * @return ROK     - success
4097  *         RFAILED - failure
4098  *
4099  * ****************************************************************/
4100 void E2APMsgHdlr(Buffer *mBuf)
4101 {
4102    int i =0;
4103    char *recvBuf = NULLP;
4104    MsgLen copyCnt =0;
4105    MsgLen recvBufLen =0;
4106    E2AP_PDU_t *e2apMsg = NULLP;
4107    asn_dec_rval_t rval ={0}; /* Decoder return value */
4108    E2AP_PDU_t e2apasnmsg={0} ;
4109
4110    DU_LOG("\nDEBUG   -->  E2AP : Received E2AP message buffer");
4111    ODU_PRINT_MSG(mBuf, 0,0);
4112
4113    /* Copy mBuf into char array to decode it */
4114    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
4115    DU_ALLOC(recvBuf, (Size)recvBufLen);
4116
4117    if(recvBuf == NULLP)
4118    {
4119       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
4120       return;
4121    }
4122    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
4123    {
4124       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
4125       return;
4126    }
4127
4128 #ifdef DEBUG_ASN_PRINT
4129    printf("\nDEBUG   -->  E2AP : Received flat buffer to be decoded : ");
4130    for(i=0; i< recvBufLen; i++)
4131    {
4132       printf("%x",recvBuf[i]);
4133    }
4134 #endif
4135
4136    /* Decoding flat buffer into E2AP messsage */
4137    e2apMsg = &e2apasnmsg;
4138    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
4139
4140    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
4141    DU_FREE(recvBuf, (Size)recvBufLen);
4142
4143    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
4144    {
4145       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
4146       return;
4147    }
4148    printf("\n");
4149    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4150
4151    switch(e2apMsg->present)
4152    {
4153       case E2AP_PDU_PR_unsuccessfulOutcome:
4154          {
4155             switch(e2apMsg->choice.unsuccessfulOutcome->value.present)
4156             {
4157                case UnsuccessfulOutcomeE2__value_PR_E2setupFailure:
4158                   {
4159                      procE2SetupFailure(e2apMsg);
4160                      break;
4161                   }
4162                case UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure:
4163                   {
4164                      procRicServiceUpdateFailure(e2apMsg);
4165                      break;
4166                   }
4167                default:
4168                   {
4169                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome  [%d]",\
4170                            e2apMsg->choice.unsuccessfulOutcome->value.present);
4171                      return;
4172                   }
4173             }
4174             break;
4175          }
4176       case E2AP_PDU_PR_successfulOutcome:
4177          {
4178             switch(e2apMsg->choice.successfulOutcome->value.present)
4179             {
4180                case SuccessfulOutcomeE2__value_PR_E2setupResponse:
4181                   {
4182                      if(!duCb.e2Status)
4183                      {
4184                         procE2SetupRsp(e2apMsg);
4185                      }
4186                      break;
4187                   }
4188                case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge:
4189                   {
4190                      DU_LOG("\nDEBUG   -->  E2AP : E2 node Config update ack message recevied");
4191                      break;
4192                   }
4193                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
4194                   {
4195                      procResetResponse(e2apMsg);
4196                      break;
4197                   }
4198                case SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge:
4199                   {
4200                      procRicServiceUpdateAck(e2apMsg);
4201                      break;
4202                   }
4203
4204
4205                default:
4206                   {
4207                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome  [%d]",\
4208                            e2apMsg->choice.successfulOutcome->value.present);
4209                      return;
4210                   }
4211             }/* End of switch(successfulOutcome) */
4212             free(e2apMsg->choice.successfulOutcome);
4213             break;
4214          }
4215
4216       case E2AP_PDU_PR_initiatingMessage:
4217          {
4218             switch(e2apMsg->choice.initiatingMessage->value.present)
4219             {
4220                case InitiatingMessageE2__value_PR_RICsubscriptionRequest: 
4221                   {
4222                      procRicSubscriptionRequest(e2apMsg);
4223                      break;
4224                   }
4225                case InitiatingMessageE2__value_PR_RICserviceQuery:
4226                   {
4227                      procRicServiceQuery(e2apMsg);
4228                      break;
4229                   }
4230                default:
4231                   {
4232                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\
4233                            e2apMsg->choice.initiatingMessage->value.present);
4234                      return;
4235                   }
4236             }/* End of switch(initiatingMessage) */
4237             free(e2apMsg->choice.initiatingMessage);
4238             break;
4239          }
4240       default:
4241          {
4242             DU_LOG("\nERROR  -->  E2AP : Invalid type of e2apMsg->present [%d]",e2apMsg->present);
4243             return;
4244          }
4245          free(e2apMsg);
4246
4247    }/* End of switch(e2apMsg->present) */
4248
4249 } /* End of E2APMsgHdlr */
4250
4251 /**********************************************************************
4252   End of file
4253  **********************************************************************/