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