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