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