[Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-534] Handling of reset req and Implementation...
[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 #include "MeasurementRecord.h"
55 #include "MeasurementData.h"
56 #include "MeasurementRecordItem.h"
57 #include "MeasurementDataItem.h"
58 #include "E2SM-KPM-IndicationMessage-Format1.h"
59 #include "E2SM-KPM-IndicationMessage.h"
60 #include "E2SM-KPM-IndicationHeader.h"
61 #include "E2SM-KPM-IndicationHeader-Format1.h"
62 #include "LabelInfoItem.h"
63
64 /*******************************************************************
65  *
66  * @brief Fill E2 Failure Cause
67  *
68  * @details
69  *
70  *    Function : fillE2Cause
71  *
72  *    Functionality: Fill E2 Failure Cause
73  *
74  * @params[in] E2 Cause pointer to be filled in
75  *             E2 Cause to be filled from 
76  * @return void
77  *
78  ******************************************************************/
79 void fillE2Cause(CauseE2_t *e2Cause, E2FailureCause failureCause)
80 {
81    e2Cause->present = failureCause.causeType;
82    switch(e2Cause->present)
83    {
84       case CauseE2_PR_ricRequest:
85          {
86             e2Cause->choice.ricRequest = failureCause.cause;
87             break;
88          }
89       case CauseE2_PR_ricService:
90          {
91             e2Cause->choice.ricService = failureCause.cause;
92             break;
93          }
94       case CauseE2_PR_e2Node:
95          {
96             e2Cause->choice.e2Node = failureCause.cause;
97             break;
98          }
99       case CauseE2_PR_transport:
100          {
101             e2Cause->choice.transport = failureCause.cause;
102             break;
103          }
104       case CauseE2_PR_protocol:
105          {
106             e2Cause->choice.protocol = failureCause.cause;
107             break;
108          }
109       case CauseE2_PR_misc:
110          {
111             e2Cause->choice.misc = failureCause.cause;
112             break;
113          }
114       case CauseE2_PR_NOTHING:
115       default:
116          break;
117    }
118 }
119
120 /*******************************************************************
121  *
122  * @brief Free the ErrorIndication Message
123  *
124  * @details
125  *
126  *    Function : FreeRicIndication
127  *
128  * Functionality: Free the ErrorIndication Message
129  *
130  * @params[in] 
131  *    E2AP_PDU is to freed
132  * @return void
133  *
134  ******************************************************************/
135 void FreeErrorIndication(E2AP_PDU_t  *e2apMsg) 
136 {
137    uint8_t arrIdx = 0;
138    ErrorIndicationE2_t *errorIndicationMsg= NULLP;
139
140    if(e2apMsg != NULLP)
141    {
142       if(e2apMsg->choice.initiatingMessage != NULLP)
143       {
144          errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
145          if(errorIndicationMsg!= NULLP)
146          {
147             if(errorIndicationMsg->protocolIEs.list.array != NULLP)
148             {
149                for(arrIdx=0; arrIdx<errorIndicationMsg->protocolIEs.list.count; arrIdx++)
150                {
151                   DU_FREE(errorIndicationMsg->protocolIEs.list.array[arrIdx],sizeof(ErrorIndicationE2_t));
152                }
153                DU_FREE(errorIndicationMsg->protocolIEs.list.array,errorIndicationMsg->protocolIEs.list.size);
154             }
155          }
156          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
157       }
158       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
159    }
160 }
161
162 /*******************************************************************
163  *
164  * @brief Builds and Send the ErrorIndication Message
165  *
166  * @details
167  *
168  *    Function : BuildAndSendErrorIndication
169  *
170  * Functionality:Fills the ErrorIndication Message
171  *
172  * @params[in] 
173  *    Trans id
174  *    Ric req id
175  *    Ran function id
176  *    Cause of failure
177  * @return ROK     - success
178  *         RFAILED - failure
179  *
180  ******************************************************************/
181
182 uint8_t BuildAndSendErrorIndication(int8_t transId, RicRequestId requestId, uint16_t ranFuncId,  E2FailureCause failureCause)
183 {
184    uint8_t elementCnt =0, arrIdx=0, ret = RFAILED;
185    E2AP_PDU_t         *e2apMsg = NULLP;
186    ErrorIndicationE2_t *errorIndicationMsg=NULLP;
187    asn_enc_rval_t     encRetVal;        /* Encoder return value */
188
189    while(true)
190    {
191       DU_LOG("\nINFO   -->  E2AP : Building Error Indication Message\n");
192
193       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
194       if(e2apMsg == NULLP)
195       {
196          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
197          break;
198       }
199
200       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
201       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
202       if(e2apMsg->choice.initiatingMessage == NULLP)
203       {
204          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
205          break;
206       }
207       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_ErrorIndicationE2;
208       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
209       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ErrorIndicationE2;
210
211       errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
212       
213       /* Element count is 2 for TransactionID/RICrequestID and Cause.
214        * If the RAN function id is present, the count will be increased.*/
215       elementCnt = 2;
216       if(ranFuncId>0)
217       {
218          elementCnt++;
219       }
220       
221       errorIndicationMsg->protocolIEs.list.count = elementCnt;
222       errorIndicationMsg->protocolIEs.list.size = elementCnt * sizeof(ErrorIndicationE2_IEs_t*);
223
224       /* Initialize the E2Setup members */
225       DU_ALLOC(errorIndicationMsg->protocolIEs.list.array, errorIndicationMsg->protocolIEs.list.size);
226       if(errorIndicationMsg->protocolIEs.list.array == NULLP)
227       {
228          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements in %s at line %d",__func__, __LINE__);
229          break;
230       }
231       
232       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
233       {
234          DU_ALLOC(errorIndicationMsg->protocolIEs.list.array[arrIdx], sizeof(ErrorIndicationE2_IEs_t));
235          if(errorIndicationMsg->protocolIEs.list.array[arrIdx] == NULLP)
236          {
237             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array [%d] elements in %s at line %d", arrIdx, __func__, __LINE__);
238             break;
239          }
240       }
241       if(arrIdx < elementCnt)
242          break;
243
244       arrIdx = 0;
245
246       if(transId >=0 && transId<=255)
247       {
248          /* TransactionID */
249          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
250          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
251          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_TransactionID;
252          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
253       }
254       else
255       {
256          /* RICrequestID */
257          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RICrequestID;
258          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
259          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RICrequestID;
260          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricRequestorID = requestId.requestorId;
261          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricInstanceID = requestId.instanceId;
262       }
263       
264       if(ranFuncId>0)
265       {
266          /* RAN Function ID */
267          arrIdx++;
268          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionID;
269          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
270          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RANfunctionID;
271          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionID = ranFuncId;
272       }
273
274       /* Cause */
275       arrIdx++;
276       errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
277       errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
278       errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2;
279       fillE2Cause(&errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, failureCause);
280
281       /* Prints the Msg formed */
282       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
283       memset(encBuf, 0, ENC_BUF_MAX_LEN);
284       encBufSize = 0;
285       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
286             encBuf);
287       if(encRetVal.encoded == ENCODE_FAIL)
288       {
289          DU_LOG("\nERROR  -->  E2AP : Could not encode Error Indication Message (at %s)\n",\
290                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
291          break;
292       }
293       else
294       {
295          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for Error Indication Message \n");
296 #ifdef DEBUG_ASN_PRINT
297          for(int i=0; i< encBufSize; i++)
298          {
299             printf("%x",encBuf[i]);
300          } 
301 #endif
302       }
303
304       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
305       {
306          DU_LOG("\nINFO   -->  E2AP : Sending Error Indication Message");      
307
308       }
309       ret = ROK;
310       break;
311    }
312    FreeErrorIndication(e2apMsg);        
313    return ret;
314 }
315
316 /******************************************************************
317  *
318  * @brief Deallocation of memory allocated by aper decoder for e2 
319  * Config Update Failure
320  *
321  * @details
322  *
323  *    Function : freeAperDecodingOfE2Node Config UpdateFailure
324  *
325  *    Functionality: Deallocation of memory allocated by  aper decoder 
326  *    for e2 Config Update Failure
327  *
328  * @params[in] E2nodeConfigurationUpdateFailure_t to be deallocated 
329  * @return void
330  *
331  * ****************************************************************/
332
333 void freeAperDecodingOfE2NodeConfigUpdateFailure(E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdFail)
334 {
335    uint8_t arrIdx =0;
336
337    if(e2NodeCfgUpdFail)
338    {
339       if(e2NodeCfgUpdFail->protocolIEs.list.array)
340       {
341          for(arrIdx=0; arrIdx<e2NodeCfgUpdFail->protocolIEs.list.count; arrIdx++)
342          {
343             if(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx])
344             {
345                free(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]);
346             }
347          }
348          free(e2NodeCfgUpdFail->protocolIEs.list.array);
349       }
350    }
351 }
352
353 /******************************************************************
354  *
355  * @brief Processes E2 Node Config Update Failure sent by RIC
356  *
357  * @details
358  *
359  *    Function : procE2NodeConfigUpdateFailure
360  *
361  *    Functionality: Processes E2 Node Config Update failure sent by RIC
362  *
363  * @params[in] E2AP_PDU_t ASN decoded E2AP message
364  * @return ROK     - success
365  *         RFAILED - failure
366  *
367  * ****************************************************************/
368
369 void procE2NodeConfigUpdateFailure(E2AP_PDU_t *e2apMsg)
370 {
371    uint8_t arrIdx =0, transId =0, timerValue=0;
372    E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdFail=NULL;
373
374    DU_LOG("\nINFO   -->  E2AP : E2 Node Config Update failure received");
375    e2NodeCfgUpdFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2nodeConfigurationUpdateFailure;
376
377    for(arrIdx=0; arrIdx<e2NodeCfgUpdFail->protocolIEs.list.count; arrIdx++)
378    {
379       switch(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]->id)
380       {
381          case ProtocolIE_IDE2_id_TransactionID:
382             {
383                transId = e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
384                if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
385                      (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
386                {
387                   memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
388                }
389                else
390                {
391                   DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
392                }
393                break;
394          }
395          case ProtocolIE_IDE2_id_TimeToWaitE2:
396             {
397                timerValue = convertE2WaitTimerEnumToValue(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
398                if((duChkTmr((PTR)&(duCb.e2apDb), EVENT_E2_NODE_CONFIG_UPDATE_TMR)) == FALSE)
399                {
400                   duStartTmr((PTR)&(duCb.e2apDb), EVENT_E2_NODE_CONFIG_UPDATE_TMR, timerValue);
401                }
402                else
403                {
404                   DU_LOG("\nERROR   -->  E2AP : EVENT_E2_NODE_CONFIG_UPDATE_TMR timer is already running");
405                }
406                break;
407             }
408       }
409    }
410
411    freeAperDecodingOfE2NodeConfigUpdateFailure(e2NodeCfgUpdFail);
412 }
413
414 /*******************************************************************
415  *
416  * @brief Builds Global gNodeB Params
417  *
418  * @details
419  *
420  *    Function : BuildGlobalgNBId
421  *
422  *    Functionality: Building the Plmn and gNB id
423  *
424  * @params[in] GlobalE2node_gNB_ID_t *gNbId
425  * @return ROK     - success
426  *         RFAILED - failure
427  *
428  ******************************************************************/
429
430 uint8_t BuildGlobalgNBId(GlobalE2node_gNB_ID_t *gNbId)
431 {
432    uint8_t unused = 0;
433    uint8_t byteSize = 4;
434    uint8_t gnbId = duCb.gnbId;
435    uint8_t ret = ROK;
436
437    /* fill Global gNB ID Id */
438    gNbId->global_gNB_ID.plmn_id.size = 3 * sizeof(uint8_t);
439    gNbId->global_gNB_ID.plmn_id.buf = NULLP;
440    DU_ALLOC(gNbId->global_gNB_ID.plmn_id.buf , gNbId->global_gNB_ID.plmn_id.size);
441    if(gNbId->global_gNB_ID.plmn_id.buf == NULLP)
442    {
443       DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for Plmn buffer");
444       ret = RFAILED;
445    }
446    else
447    {
448       buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
449             gNbId->global_gNB_ID.plmn_id.buf);
450       gNbId->global_gNB_ID.gnb_id.present = GNB_ID_Choice_PR_gnb_ID;
451       /* Allocate Buffer size */
452       gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size = byteSize * sizeof(uint8_t);
453       gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf = NULLP;
454       DU_ALLOC(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf, \
455             gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size);
456       if(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf == NULLP)
457       {
458          DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for gnb buffer");
459          ret = RFAILED;
460       }
461       else
462       {
463          fillBitString(&gNbId->global_gNB_ID.gnb_id.choice.gnb_ID, unused, byteSize, gnbId);
464       }
465    }
466
467    /* fill gNB-DU ID */ 
468    DU_ALLOC( gNbId->gNB_DU_ID, sizeof(GNB_DU_ID_t));
469    if(gNbId->gNB_DU_ID == NULLP)
470    {
471       DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for gNB_DU_ID ");
472       ret = RFAILED;
473    }
474    else
475    {
476       gNbId->gNB_DU_ID->size = sizeof(uint8_t);
477       DU_ALLOC( gNbId->gNB_DU_ID->buf, sizeof(uint8_t));
478       if(gNbId->gNB_DU_ID->buf)
479       {
480          gNbId->gNB_DU_ID->buf[0] =duCb.e2apDb.e2NodeId;
481       }
482       else
483       {
484          DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for gNB_DU_ID buffer");
485          ret = RFAILED;
486       }
487    }
488
489    return ret;
490 }
491
492 /*******************************************************************
493  *
494  * @brief fill the E2 node config information
495  *
496  * @details
497  *
498  *    Function : fillE2NodeConfig
499  *
500  *    Functionality: fill E2 node config information
501  *
502  * @params[in]  
503  *       Pointer to e2NodeCfg to be filled
504  *       E2 Node Component information
505  *       Type of configuration 
506  * @return ROK     - success
507  *         RFAILED - failure
508  *
509  ******************************************************************/
510
511 uint8_t fillE2NodeConfig(PTR e2NodeCfg, E2NodeComponent *e2NodeComponentInfo, ConfigType configType)
512 {
513    E2nodeComponentInterfaceType_t *interfaceType=NULLP;
514    E2nodeComponentID_t *componentID =NULLP;
515    E2nodeComponentConfiguration_t *configuration=NULLP;
516    E2nodeComponentConfigAddition_Item_t *e2NodeAddItem=NULL;
517    E2nodeComponentConfigUpdate_Item_t *e2NodeUpdateItem =NULL;
518    E2nodeComponentConfigRemoval_Item_t *e2NodeRemovalItem=NULL;
519    
520    switch(configType)
521    {
522       case CONFIG_ADD:
523       {
524          e2NodeAddItem = (E2nodeComponentConfigAddition_Item_t*)e2NodeCfg;
525          interfaceType = &e2NodeAddItem->e2nodeComponentInterfaceType;
526          componentID   = &e2NodeAddItem->e2nodeComponentID;
527          configuration = &e2NodeAddItem->e2nodeComponentConfiguration; 
528          break;
529       }
530       case CONFIG_MOD:
531       {
532          e2NodeUpdateItem = (E2nodeComponentConfigUpdate_Item_t *) e2NodeCfg;
533          interfaceType = &e2NodeUpdateItem->e2nodeComponentInterfaceType;
534          componentID   = &e2NodeUpdateItem->e2nodeComponentID;
535          configuration = &e2NodeUpdateItem->e2nodeComponentConfiguration; 
536          break;
537       }
538       case CONFIG_DEL:
539       {
540          e2NodeRemovalItem = (E2nodeComponentConfigRemoval_Item_t*) e2NodeCfg;
541          interfaceType = &e2NodeRemovalItem->e2nodeComponentInterfaceType;
542          componentID  = &e2NodeRemovalItem->e2nodeComponentID;
543          break;
544       }
545       default:
546       {
547          DU_LOG("\nERROR  --> E2AP : Configuration type %d does not supported ", configType);
548          return RFAILED;
549       }
550    }
551    /* E2nodeComponentInterfaceType */
552    *interfaceType = convertInterfaceToE2ComponentInterfaceType(e2NodeComponentInfo->interfaceType);
553    
554    /*  We now only support the F1 interface out of these interfaces
555     * (NG,XN,E1,F1,W1,S1,X2), therefore only the F1 component identifier was filled in. */
556    
557    if(*interfaceType == F1)
558    {
559       /* E2 Node Component ID */
560       componentID->present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1;
561       DU_ALLOC(componentID->choice.e2nodeComponentInterfaceTypeF1,sizeof(E2nodeComponentInterfaceF1_t));
562       if(componentID->choice.e2nodeComponentInterfaceTypeF1 == NULLP)
563       {
564          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__);
565          return RFAILED;
566       }
567       componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t);
568       DU_ALLOC(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
569             componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
570
571       if(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP)
572       {
573          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__);
574          return RFAILED;
575       }
576       memcpy(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf, &e2NodeComponentInfo->componentId,\
577             componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
578    }
579   
580    if(configType == CONFIG_DEL)
581    {
582       /* We don't need to fill out the E2 Node Component Request and Response
583        * information in the case of CONFIG_DEL, therefore returning ROK from here. */
584       return ROK;
585    }
586
587    /* E2 Node Component Request Part */
588    if(e2NodeComponentInfo->componentRequestPart)
589    {
590       configuration->e2nodeComponentRequestPart.size = e2NodeComponentInfo->reqBufSize ;
591       DU_ALLOC(configuration->e2nodeComponentRequestPart.buf,\
592             configuration->e2nodeComponentRequestPart.size);
593       if(configuration->e2nodeComponentRequestPart.buf == NULLP)
594       {
595          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__);
596          return RFAILED;
597       }
598
599       memcpy(configuration->e2nodeComponentRequestPart.buf,\
600             e2NodeComponentInfo->componentRequestPart, configuration->\
601             e2nodeComponentRequestPart.size);
602    }
603    else
604    {
605       DU_LOG("\nERROR  --> E2AP: componentRequestPart is null ");
606       return RFAILED;
607    }
608
609    /* E2 Node Component Response Part */
610    if(e2NodeComponentInfo->componentResponsePart)
611    {
612       configuration->e2nodeComponentResponsePart.size = e2NodeComponentInfo->rspBufSize; 
613       DU_ALLOC(configuration->e2nodeComponentResponsePart.buf, configuration->e2nodeComponentResponsePart.size);
614       if(configuration->e2nodeComponentResponsePart.buf == NULLP)
615       {
616          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__);
617          return RFAILED;
618       }
619       memcpy(configuration->e2nodeComponentResponsePart.buf,  e2NodeComponentInfo->componentResponsePart, configuration->\
620             e2nodeComponentResponsePart.size);
621    }
622    else
623    {
624       DU_LOG("\nERROR  --> E2AP: componentResponsePart is null");
625       return RFAILED;
626    }
627    
628    return ROK;
629 }
630
631 /*******************************************************************
632  *
633  * @brief Builds E2 node config addition list 
634  *
635  * @details
636  *
637  *    Function : BuildE2NodeConfigAddList
638  *
639  *    Functionality: Building E2 node config addition list
640  *
641  * @params[in] 
642  *    E2nodeComponentConfigAddition_List_t to be filled
643  *    Procedure Code
644  *    Count of E2 node to be added in the list    
645  *    Received list of E2 node configuration
646  *
647  * @return ROK     - success
648  *         RFAILED - failure
649  *
650  ******************************************************************/
651
652 uint8_t BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAddList, uint8_t procedureCode, uint16_t count, E2NodeConfigItem *e2NodeList)
653 {
654    uint8_t arrIdx = 0;
655    CmLList         *node =NULL;
656    E2NodeComponent *e2NodeComponentInfo=NULL;
657    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItemIe=NULL;
658    E2nodeComponentConfigAddition_Item_t *e2NodeAddItem=NULL;
659    
660
661    /* For ProcedureCodeE2_id_E2setup, the number of E2 node configuration list items is
662     * equal to the number of E2 node configuration entries stored in the database.
663     * For any other procedure, the E2 node configuration list count is equal
664     * to the count of E2 node configuration obtained from the function's caller */
665
666    if(procedureCode == ProcedureCodeE2_id_E2setup)
667       e2NodeAddList->list.count = duCb.e2apDb.e2NodeComponentList.count;
668    else
669       e2NodeAddList->list.count = count;
670
671    e2NodeAddList->list.size = e2NodeAddList->list.count * sizeof(E2nodeComponentConfigAddition_ItemIEs_t *);
672    DU_ALLOC(e2NodeAddList->list.array, e2NodeAddList->list.size);
673    if(e2NodeAddList->list.array == NULLP)
674    {
675        DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
676        return RFAILED;
677    }
678
679    for(arrIdx = 0; arrIdx< e2NodeAddList->list.count; arrIdx++)
680    {
681       DU_ALLOC(e2NodeAddList->list.array[arrIdx], sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
682       if(e2NodeAddList->list.array[arrIdx] == NULLP)
683       {
684          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
685          return RFAILED;
686       }
687       
688       if(procedureCode == ProcedureCodeE2_id_E2setup)
689       {
690          /* Getting all of the E2 node configuration's information from DuCb one by one*/
691          if(arrIdx == 0)
692          {
693             CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node); 
694          }
695          else
696          {
697             node = node->next;
698          }
699          if(!node)
700          {
701             DU_LOG("\nERROR  --> E2AP : E2 node component list node is null");
702             return RFAILED;
703          }
704          e2NodeComponentInfo = (E2NodeComponent*)node->node;
705       }
706       else
707       {
708          /* Getting only those E2 node configuration from DuCb whose interface
709           * and action type is present in the received array */
710          e2NodeComponentInfo = fetchE2NodeComponentInfo(e2NodeList[arrIdx].interface, e2NodeList[arrIdx].actionType, &node);
711       }
712       
713       if(!e2NodeComponentInfo)
714       {
715          DU_LOG("\nERROR  --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__);
716          return RFAILED;
717       }
718
719       e2NodeAddItemIe = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[arrIdx];
720       e2NodeAddItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition_Item;
721       e2NodeAddItemIe->criticality = CriticalityE2_reject;
722       e2NodeAddItemIe->value.present = E2nodeComponentConfigAddition_ItemIEs__value_PR_E2nodeComponentConfigAddition_Item;
723       e2NodeAddItem = &e2NodeAddItemIe->value.choice.E2nodeComponentConfigAddition_Item;
724       if(fillE2NodeConfig((PTR)e2NodeAddItem, e2NodeComponentInfo, CONFIG_ADD) != ROK)
725       {
726          DU_LOG("\nERROR  --> E2AP : Failed to fill the E2 node configuration");
727          return RFAILED;
728       }
729    }
730    return ROK;
731 }
732
733 /*******************************************************************
734  *
735  * @brief Builds E2 node config update list 
736  *
737  * @details
738  *
739  *    Function : BuildE2NodeConfigUpdateList
740  *
741  *    Functionality: Building E2 node config update list
742  *
743  * @params[in] 
744  *    E2nodeComponentConfigUpdate_List_t to be filled
745  *    Count of E2 node to be update in the list    
746  *    Received list of E2 node configuration
747  *
748  * @return ROK     - success
749  *         RFAILED - failure
750  *
751  ******************************************************************/
752
753 uint8_t BuildE2NodeConfigUpdateList(E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList, uint16_t count,  E2NodeConfigItem *updateE2Node)
754 {
755    uint8_t arrIdx = 0;
756    CmLList         *node =NULL;
757    E2NodeComponent *e2NodeComponentInfo =NULL;
758    E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItemIe =NULL;
759    E2nodeComponentConfigUpdate_Item_t *e2NodeUpdateItem =NULL;
760
761    e2NodeUpdateList->list.count = count;
762    e2NodeUpdateList->list.size = e2NodeUpdateList->list.count * sizeof(E2nodeComponentConfigUpdate_ItemIEs_t *);
763    DU_ALLOC(e2NodeUpdateList->list.array, e2NodeUpdateList->list.size);
764    if(e2NodeUpdateList->list.array == NULLP)
765    {
766       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigUpdateList %d",__LINE__);
767       return RFAILED;
768    }
769
770    for(arrIdx = 0; arrIdx< e2NodeUpdateList->list.count; arrIdx++)
771    {
772       DU_ALLOC(e2NodeUpdateList->list.array[arrIdx], sizeof(E2nodeComponentConfigUpdate_ItemIEs_t));
773       if(e2NodeUpdateList->list.array[arrIdx] == NULLP)
774       {
775          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigUpdateList %d",__LINE__);
776          return RFAILED;
777       }
778
779       e2NodeComponentInfo= fetchE2NodeComponentInfo(updateE2Node[arrIdx].interface, updateE2Node[arrIdx].actionType, &node);
780       if(!e2NodeComponentInfo)
781       {
782          DU_LOG("\nERROR  --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__);
783          return RFAILED;
784       }
785
786       e2NodeUpdateItemIe = (E2nodeComponentConfigUpdate_ItemIEs_t *) e2NodeUpdateList->list.array[arrIdx];
787       e2NodeUpdateItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate_Item;
788       e2NodeUpdateItemIe->criticality = CriticalityE2_reject;
789       e2NodeUpdateItemIe->value.present = E2nodeComponentConfigUpdate_ItemIEs__value_PR_E2nodeComponentConfigUpdate_Item;
790       e2NodeUpdateItem = &e2NodeUpdateItemIe->value.choice.E2nodeComponentConfigUpdate_Item;
791
792       if(fillE2NodeConfig((PTR)e2NodeUpdateItem, e2NodeComponentInfo, CONFIG_MOD) != ROK)
793       {
794          DU_LOG("\nERROR  --> E2AP : Failed to fill the E2 node configuration");
795          return RFAILED;
796       }
797
798    }
799    return ROK;
800
801 }
802
803
804 /*******************************************************************
805  *
806  * @brief Builds E2 node config remove list 
807  *
808  * @details
809  *
810  *    Function :BuildE2NodeConfigRemoveList 
811  *
812  *    Functionality: Building E2 node config remove list
813  *
814  * @params[in] 
815  *    E2nodeComponentConfigRemoval_List_t to be filled
816  *    Count of E2 node to be remove in the list    
817  *    Received list of E2 node configuration
818  * @return ROK     - success
819  *         RFAILED - failure
820  *
821  ******************************************************************/
822
823 uint8_t BuildE2NodeConfigRemoveList(E2nodeComponentConfigRemoval_List_t *e2NodeRemoveList, uint16_t count,  E2NodeConfigItem *updateE2Node)
824 {
825    uint8_t arrIdx = 0;
826    CmLList         *node=NULL;
827    E2NodeComponent *e2NodeComponentInfo=NULL;
828    E2nodeComponentConfigRemoval_ItemIEs_t *e2NodeRemovalItemIe=NULL;
829    E2nodeComponentConfigRemoval_Item_t *e2NodeRemovalItem=NULL;
830
831    e2NodeRemoveList->list.count = count;
832    e2NodeRemoveList->list.size = e2NodeRemoveList->list.count * sizeof(E2nodeComponentConfigRemoval_ItemIEs_t *);
833    DU_ALLOC(e2NodeRemoveList->list.array, e2NodeRemoveList->list.size);
834    if(e2NodeRemoveList->list.array == NULLP)
835    {
836       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigRemoveList %d",__LINE__);
837       return RFAILED;
838    }
839
840    for(arrIdx = 0; arrIdx< e2NodeRemoveList->list.count; arrIdx++)
841    {
842       DU_ALLOC(e2NodeRemoveList->list.array[arrIdx], sizeof(E2nodeComponentConfigRemoval_ItemIEs_t));
843       if(e2NodeRemoveList->list.array[arrIdx] == NULLP)
844       {
845          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigRemoveList %d",__LINE__);
846          return RFAILED;
847       }
848
849       e2NodeComponentInfo= fetchE2NodeComponentInfo(updateE2Node[arrIdx].interface, updateE2Node[arrIdx].actionType, &node);
850       if(!e2NodeComponentInfo)
851       {
852          DU_LOG("\nERROR  --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__);
853          return RFAILED;
854       }
855
856       e2NodeRemovalItemIe = (E2nodeComponentConfigRemoval_ItemIEs_t *) e2NodeRemoveList->list.array[arrIdx];
857       e2NodeRemovalItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval_Item;
858       e2NodeRemovalItemIe->criticality = CriticalityE2_reject;
859       e2NodeRemovalItemIe->value.present = E2nodeComponentConfigRemoval_ItemIEs__value_PR_E2nodeComponentConfigRemoval_Item;
860       e2NodeRemovalItem = &e2NodeRemovalItemIe->value.choice.E2nodeComponentConfigRemoval_Item;
861
862       if(fillE2NodeConfig((PTR)e2NodeRemovalItem, e2NodeComponentInfo, CONFIG_DEL) != ROK)
863       {
864          DU_LOG("\nERROR  --> E2AP : Failed to fill the E2 node configuration");
865          return RFAILED;
866       }
867
868    }
869    return ROK;
870 }
871 /*******************************************************************
872  *
873  * @brief deallocation of E2SM_KPM_RANfunction_Description_t
874  *
875  * @details
876  *
877  *    Function : freeE2smKpmRanFunctionDefinition
878  *
879  *    Functionality: deallocation of E2SM_KPM_RANfunction_Description_t
880  *
881  * @params[in]  E2SM_KPM_RANfunction_Description_t *ranFunctionDefinition
882  * @return void
883  *
884  ******************************************************************/
885
886 void freeE2smKpmRanFunctionDefinition(E2SM_KPM_RANfunction_Description_t *ranFunctionDefinition)
887 {
888    MeasurementInfo_Action_Item_t *measInfoList;
889    uint8_t eventTriggerIdx, reportStyleIdx, measInfoIdx;
890    RANfunction_Name_t *ranFuncName;
891    struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle;
892    struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List *eventTriggerStyle;
893    if(ranFunctionDefinition)
894    {
895       ranFuncName = &ranFunctionDefinition->ranFunction_Name;
896       /* Free RAN function Name */     
897       DU_FREE(ranFuncName->ranFunction_ShortName.buf,  ranFuncName->ranFunction_ShortName.size);
898       DU_FREE(ranFuncName->ranFunction_E2SM_OID.buf, ranFuncName->ranFunction_E2SM_OID.size);
899       DU_FREE(ranFuncName->ranFunction_Description.buf, ranFuncName->ranFunction_Description.size);
900
901       /* Sequence of Event Trigger styles */
902       eventTriggerStyle = ranFunctionDefinition->ric_EventTriggerStyle_List;
903       if(eventTriggerStyle)
904       {
905          if(eventTriggerStyle->list.array)
906          {
907             for(eventTriggerIdx =0;eventTriggerIdx<eventTriggerStyle->list.count; eventTriggerIdx++)
908             {
909                if(eventTriggerStyle->list.array[eventTriggerIdx])
910                {
911                   DU_FREE(eventTriggerStyle->list.array[eventTriggerIdx]->ric_EventTriggerStyle_Name.buf,\
912                         eventTriggerStyle->list.array[eventTriggerIdx]->ric_EventTriggerStyle_Name.size);
913                   DU_FREE(eventTriggerStyle->list.array[eventTriggerIdx], sizeof(RIC_EventTriggerStyle_Item_t ));
914                }
915             }
916             DU_FREE(eventTriggerStyle->list.array, eventTriggerStyle->list.size)
917          }
918          DU_FREE(eventTriggerStyle, sizeof(struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List));
919       }
920       
921       /* Sequence of Report styles */
922       ricReportStyle = ranFunctionDefinition->ric_ReportStyle_List;
923       if(ricReportStyle)
924       {
925          if(ricReportStyle->list.array)
926          {
927             for(reportStyleIdx =0;reportStyleIdx<ricReportStyle->list.count; reportStyleIdx++)
928             {
929                if(ricReportStyle->list.array[reportStyleIdx])
930                {
931                   if(ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.buf)
932                   {
933                      DU_FREE(ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.buf,\
934                            ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.size);
935                   }
936                   if(ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.array)
937                   {
938                      for(measInfoIdx=0; measInfoIdx<ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.count; \
939                            measInfoIdx++)
940                      {
941                         measInfoList = ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.array[measInfoIdx];
942                         if(measInfoList)
943                         {
944                            DU_FREE(measInfoList->measID, sizeof(long));
945                            DU_FREE(measInfoList->measName.buf, measInfoList->measName.size);
946                            DU_FREE(measInfoList,sizeof(MeasurementInfo_Action_Item_t)); 
947                         }
948                      }
949                      DU_FREE(measInfoList,ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.size);
950                   }
951                   DU_FREE(ricReportStyle->list.array[reportStyleIdx], sizeof(RIC_ReportStyle_Item_t));
952                }
953             }
954             DU_FREE(ricReportStyle->list.array, ricReportStyle->list.size);
955          }
956          DU_FREE(ricReportStyle, sizeof(struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List));
957       }
958       DU_FREE(ranFunctionDefinition, sizeof(E2SM_KPM_RANfunction_Description_t)); 
959    }
960 }
961
962 /*******************************************************************
963  *
964  * @brief fill the e2sm ric report style
965  *
966  * @details
967  *
968  *    Function : fillRicReportStyle
969  *
970  *    Functionality: fill the report style
971  *
972  * @params[in]   RanFunction *ranFuncDb, struct
973  * E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle
974  * @return ROK     - success
975  *         RFAILED - failure
976  *
977  ******************************************************************/
978 uint8_t fillRicReportStyle(RanFunction *ranFuncDb, struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle)
979 {
980    uint8_t styleIdx, measInfoIdx;
981    MeasurementInfo_Action_List_t *measInfo;
982    CmLList  *node;
983    
984    ricReportStyle->list.count = ranFuncDb->numOfReportStyleSupported;
985    ricReportStyle->list.size = ricReportStyle->list.count * sizeof(RIC_ReportStyle_Item_t*);
986    DU_ALLOC(ricReportStyle->list.array, ricReportStyle->list.size);
987    if(!ricReportStyle->list.array)
988    {
989       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for ranFuncDefinition %d",__LINE__);
990       return RFAILED;
991    }
992
993    for(styleIdx =0;styleIdx<ricReportStyle->list.count; styleIdx++)
994    {
995       DU_ALLOC(ricReportStyle->list.array[styleIdx], sizeof(RIC_ReportStyle_Item_t));
996       if(!ricReportStyle->list.array[styleIdx])
997       {
998          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
999          return RFAILED;
1000       }
1001       
1002       /* RIC Report Style Type */
1003       ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Type = ranFuncDb->reportStyleList[styleIdx].reportStyle.styleType;
1004       
1005       /* RIC Report Style Format Type */
1006       ricReportStyle->list.array[styleIdx]->ric_ActionFormat_Type = ranFuncDb->reportStyleList[styleIdx].reportStyle.formatType;
1007       
1008       /* RIC Report Style Name */
1009       ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size = strlen(ranFuncDb->reportStyleList[styleIdx].reportStyle.name);
1010       DU_ALLOC(ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf,\
1011             ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size);
1012       if(!ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf)
1013       {
1014          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1015          return RFAILED;
1016       }
1017       memcpy(ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf, ranFuncDb->reportStyleList[styleIdx].reportStyle.name,\
1018             ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size);
1019
1020       /* RIC Indication Header Format Type*/
1021       ricReportStyle->list.array[styleIdx]->ric_IndicationHeaderFormat_Type = ranFuncDb->ricIndicationHeaderFormat;
1022
1023       /* RIC Indication Message Format Type*/
1024       ricReportStyle->list.array[styleIdx]->ric_IndicationMessageFormat_Type = ranFuncDb->ricIndicationMessageFormat;
1025       
1026       /* Measurement Info Action List */
1027       CmLListCp measInfoList =ranFuncDb->reportStyleList[styleIdx].measurementInfoList;
1028       if(!measInfoList.count)
1029       {
1030          continue;      
1031       }
1032
1033       CM_LLIST_FIRST_NODE(&ranFuncDb->reportStyleList[styleIdx].measurementInfoList, node);
1034       measInfo = &ricReportStyle->list.array[styleIdx]->measInfo_Action_List;
1035
1036       measInfo->list.count = measInfoList.count; 
1037       measInfo->list.size =  measInfoList.count*sizeof(MeasurementInfo_Action_Item_t*);
1038       DU_ALLOC(measInfo->list.array, measInfo->list.size);
1039       if(!measInfo->list.array)
1040       {
1041          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1042          return RFAILED;
1043       }
1044
1045       for(measInfoIdx=0; measInfoIdx<measInfo->list.count; measInfoIdx++)
1046       {
1047          if(!node)
1048          {
1049             DU_LOG("\nERROR  --> E2AP: Measurement info node is null");
1050             return RFAILED;
1051          }
1052
1053          DU_ALLOC(measInfo->list.array[measInfoIdx],sizeof(MeasurementInfo_Action_Item_t));  
1054          if(!measInfo->list.array[measInfoIdx])
1055          {
1056             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1057             return RFAILED;
1058          }
1059          MeasurementInfoForAction *measInfoForAction= (MeasurementInfoForAction*)node->node;
1060          DU_ALLOC(measInfo->list.array[measInfoIdx]->measID, sizeof(long));
1061          if(!measInfo->list.array[measInfoIdx]->measID)
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]->measID, &measInfoForAction->measurementTypeId,sizeof(long));
1068          measInfo->list.array[measInfoIdx]->measName.size= strlen(measInfoForAction->measurementTypeName);
1069          DU_ALLOC(measInfo->list.array[measInfoIdx]->measName.buf, measInfo->list.array[measInfoIdx]->measName.size);
1070          if(!measInfo->list.array[measInfoIdx]->measName.size)
1071          {
1072             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1073             return RFAILED;
1074          }
1075
1076          memcpy(measInfo->list.array[measInfoIdx]->measName.buf, \
1077                measInfoForAction->measurementTypeName,\
1078                measInfo->list.array[measInfoIdx]->measName.size);
1079          node = node->next;
1080       }
1081
1082    }
1083    return ROK;
1084 }
1085 /*******************************************************************
1086  *
1087  * @brief fill the ric event trigger style
1088  *
1089  * @details
1090  *
1091  *    Function : fillRicEventTriggerStyle
1092  *
1093  *    Functionality: fill the ric event trigger style
1094  *
1095  * @params[in]   
1096  * @return ROK     - success
1097  *         RFAILED - failure
1098  *
1099  ******************************************************************/
1100 uint8_t fillRicEventTriggerStyle(RanFunction *ranFuncDb, struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List *ricEventTriggerStyle)
1101 {
1102    uint8_t styleIdx;
1103
1104    ricEventTriggerStyle->list.count = ranFuncDb->numOfEventTriggerStyleSupported;
1105    ricEventTriggerStyle->list.size = ricEventTriggerStyle->list.count*  sizeof(RIC_EventTriggerStyle_Item_t *);
1106    DU_ALLOC(ricEventTriggerStyle->list.array, ricEventTriggerStyle->list.size);
1107    if(!ricEventTriggerStyle->list.array)
1108    {
1109       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for ric_EventTriggerStyle_List %d",__LINE__);
1110       return RFAILED;
1111    }
1112
1113    for(styleIdx =0;styleIdx<ricEventTriggerStyle->list.count; styleIdx++)
1114    {
1115       DU_ALLOC(ricEventTriggerStyle->list.array[styleIdx], sizeof(RIC_EventTriggerStyle_Item_t ));
1116       if(!ricEventTriggerStyle->list.array[styleIdx])
1117       {
1118          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1119          return RFAILED;
1120       }
1121       ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Type = ranFuncDb->eventTriggerStyleList[styleIdx].styleType;
1122
1123       ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerFormat_Type = ranFuncDb->eventTriggerStyleList[styleIdx].formatType;
1124
1125       ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.size = strlen(ranFuncDb->eventTriggerStyleList[styleIdx].name);
1126       DU_ALLOC(ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.buf,\
1127             ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.size);
1128       if(!ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.buf)
1129       {
1130          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1131          return RFAILED;
1132       }
1133       memcpy(ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.buf,ranFuncDb->eventTriggerStyleList[styleIdx].name,\
1134             ricEventTriggerStyle->list.array[styleIdx]->ric_EventTriggerStyle_Name.size);
1135    
1136    }
1137    return ROK;
1138 }
1139
1140 /*******************************************************************
1141  *
1142  * @brief Builds Ran function item
1143  *
1144  * @details
1145  *
1146  *    Function : BuildRanFunctionItem  
1147  *
1148  *    Functionality: Building RAN function item
1149  *
1150  * @params[in] 
1151  *             RAN function item that has to be filled 
1152  *             Stored RAN Function information
1153  * @return ROK     - success
1154  *         RFAILED - failure
1155  *
1156  ******************************************************************/
1157
1158 uint8_t BuildRanFunctionItem(RANfunction_Item_t *ranFuncItem, RanFunction *ranFuncDb)
1159 {
1160    uint8_t ret =RFAILED;
1161    RANfunctionDefinition_t  *ranFunctionDefinition;
1162    RANfunction_Name_t *ranFuncName;
1163    asn_enc_rval_t encRetVal;
1164    E2SM_KPM_RANfunction_Description_t *ranFuncDefinition;
1165    
1166    while(true)
1167    {
1168       /* RAN function Id*/
1169       ranFuncItem->ranFunctionID = ranFuncDb->id;
1170
1171       /* RAN Function Revision*/
1172       ranFuncItem->ranFunctionRevision = ranFuncDb->revisionCounter;
1173
1174       /* RAN function OID*/
1175       ranFuncItem->ranFunctionOID.size = strlen(ranFuncDb->name.serviceModelOID);
1176       DU_ALLOC(ranFuncItem->ranFunctionOID.buf, ranFuncItem->ranFunctionOID.size);
1177       if(!ranFuncItem->ranFunctionOID.buf)
1178       {
1179          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1180          break;
1181       }
1182       memcpy(ranFuncItem->ranFunctionOID.buf, ranFuncDb->name.serviceModelOID, ranFuncItem->ranFunctionOID.size);
1183
1184       /* RAN function Definition */
1185       DU_ALLOC(ranFuncDefinition, sizeof(E2SM_KPM_RANfunction_Description_t));
1186       if(!ranFuncDefinition)
1187       {
1188          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1189          break;
1190       }
1191
1192       /* RAN function Name */
1193       ranFuncName = &ranFuncDefinition->ranFunction_Name;
1194
1195       /* RAN function ShortName */
1196       ranFuncName->ranFunction_ShortName.size = strlen(ranFuncDb->name.shortName); 
1197       DU_ALLOC(ranFuncName->ranFunction_ShortName.buf,  ranFuncName->ranFunction_ShortName.size);
1198       if(!ranFuncName->ranFunction_ShortName.buf)
1199       {
1200          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1201          break;
1202       }
1203       memcpy(ranFuncName->ranFunction_ShortName.buf, ranFuncDb->name.shortName, strlen(ranFuncDb->name.shortName));
1204
1205       /* RAN function E2SM_OID */
1206       ranFuncName->ranFunction_E2SM_OID.size = strlen(ranFuncDb->name.serviceModelOID);
1207       DU_ALLOC(ranFuncName->ranFunction_E2SM_OID.buf, ranFuncName->ranFunction_E2SM_OID.size);
1208       if(!ranFuncName->ranFunction_E2SM_OID.buf)
1209       {
1210          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1211          break;
1212       }
1213       memcpy(ranFuncName->ranFunction_E2SM_OID.buf, ranFuncDb->name.serviceModelOID, ranFuncName->ranFunction_E2SM_OID.size);
1214
1215       /* RAN Function Name Description */
1216       ranFuncName->ranFunction_Description.size = strlen(ranFuncDb->name.description);
1217       DU_ALLOC(ranFuncName->ranFunction_Description.buf, ranFuncName->ranFunction_Description.size);
1218       if(!ranFuncName->ranFunction_Description.buf)
1219       {
1220          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1221          break;
1222       }
1223       memcpy(ranFuncName->ranFunction_Description.buf, ranFuncDb->name.description, ranFuncName->ranFunction_Description.size);
1224
1225       /* RIC Event Trigger Style List */
1226       DU_ALLOC(ranFuncDefinition->ric_EventTriggerStyle_List, sizeof(struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List));
1227       if(!ranFuncDefinition->ric_EventTriggerStyle_List)
1228       {
1229          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1230          break;
1231       }
1232
1233       if(fillRicEventTriggerStyle(ranFuncDb, ranFuncDefinition->ric_EventTriggerStyle_List)!=ROK)
1234       {
1235          DU_LOG("\nERROR  --> E2AP: failed to fill ric event trigger style");
1236          break;
1237       }
1238
1239       /* RIC Report Style List */
1240       DU_ALLOC(ranFuncDefinition->ric_ReportStyle_List, sizeof(struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List));
1241       if(!ranFuncDefinition->ric_ReportStyle_List)
1242       {
1243          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__);
1244          break;
1245       }
1246       if(fillRicReportStyle(ranFuncDb, ranFuncDefinition->ric_ReportStyle_List) != ROK)
1247       {
1248          DU_LOG("\nERROR  --> E2AP: failed to fill ric report style");
1249          break;
1250       }
1251
1252       /* Encode the F1SetupRequest type as APER */
1253       xer_fprint(stdout, &asn_DEF_E2SM_KPM_RANfunction_Description, ranFuncDefinition);
1254
1255       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1256       encBufSize = 0;
1257       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_RANfunction_Description, 0, ranFuncDefinition, PrepFinalEncBuf, encBuf);
1258
1259       /* Encode results */
1260       if(encRetVal.encoded == ENCODE_FAIL)
1261       {
1262          DU_LOG("\nERROR  -->  F1AP : Could not encode RAN function definition  (at %s)\n",\
1263                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1264          break;
1265       }
1266       else
1267       {
1268          DU_LOG("\nDEBUG   -->  F1AP : Created APER encoded buffer for RAN function definition \n");
1269          for(uint8_t measIeIdx=0; measIeIdx< encBufSize; measIeIdx++)
1270          {
1271             printf("%x",encBuf[measIeIdx]);
1272          }
1273          ranFunctionDefinition = &ranFuncItem->ranFunctionDefinition; 
1274          ranFunctionDefinition->size = encBufSize;
1275          DU_ALLOC(ranFunctionDefinition->buf, encBufSize);
1276          if(ranFunctionDefinition->buf == NULLP)
1277          {
1278             DU_LOG("\nERROR  -->  F1AP : Memory allocation failed for RAN function definition buffer");
1279             break;
1280          }
1281          memcpy(ranFunctionDefinition->buf, &encBuf, encBufSize);
1282          ret = ROK;
1283          break;
1284       }
1285    }
1286    freeE2smKpmRanFunctionDefinition(ranFuncDefinition);
1287    return ret;
1288 }
1289
1290 /*******************************************************************
1291  *
1292  * @brief Builds Ran function add list based on the procedure code
1293  *
1294  * @details
1295  *
1296  *    Function : BuildRanFunctionAddList 
1297  *
1298  *    Functionality: Building RAN addition addition list
1299  *       In case of ProcedureCodeE2_id_E2setup we add all the RAN Function list
1300  *       which is present in E2 database.
1301  *       In the case of other procedures, we just fill the RAN functions whose ID 
1302  *       is contained in recvList
1303  *
1304  * @params[in] 
1305  *       RAN Function list
1306  *       Procedure code
1307  *       Count of ran functions to be added in the list
1308  *       Received list of RAN functions
1309  *
1310  * @return ROK     - success
1311  *         RFAILED - failure
1312  *
1313  ******************************************************************/
1314
1315 uint8_t BuildRanFunctionAddList(RANfunctions_List_t *ranFunctionsList, uint8_t procedureCode, uint8_t count, RanFuncInfo *recvList)
1316 {
1317    uint16_t id;
1318    RanFunction *ranFuncDb;
1319    uint8_t ranFuncIdx;
1320    RANfunction_ItemIEs_t *ranFuncItemIe;
1321    
1322    /* For ProcedureCodeE2_id_E2setup, the number of RAN function list items is
1323     * equal to the number of ran function entries stored in the database.
1324     * For any other procedure, the RAN function list count is equal
1325     * to the count of ran functions obtained from the function's caller */
1326
1327    if(procedureCode == ProcedureCodeE2_id_E2setup)
1328       ranFunctionsList->list.count = duCb.e2apDb.numOfRanFunction;
1329    else
1330       ranFunctionsList->list.count = count;
1331
1332    ranFunctionsList->list.size = ranFunctionsList->list.count * sizeof(RANfunction_ItemIEs_t*);
1333    DU_ALLOC(ranFunctionsList->list.array, ranFunctionsList->list.size);
1334    if(ranFunctionsList->list.array == NULLP)
1335    {
1336       DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
1337       return RFAILED;
1338    }
1339
1340    for(ranFuncIdx = 0; ranFuncIdx< ranFunctionsList->list.count; ranFuncIdx++)
1341    {
1342       DU_ALLOC(ranFunctionsList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
1343       if(ranFunctionsList->list.array[ranFuncIdx] == NULLP)
1344       {
1345          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
1346          return RFAILED;
1347       }
1348       if(procedureCode == ProcedureCodeE2_id_E2setup) 
1349       {
1350          /* Getting all of the RAN function's information from DuCb one by one*/
1351          ranFuncDb = &duCb.e2apDb.ranFunction[ranFuncIdx];
1352       }
1353       else
1354       {
1355          /* Getting only the RAN function information from DuCb whose Id is
1356           * present in the received array */
1357          id =recvList[ranFuncIdx].id;
1358          ranFuncDb = &duCb.e2apDb.ranFunction[id-1];
1359       }
1360       ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncIdx];
1361       ranFuncItemIe->id = ProtocolIE_IDE2_id_RANfunction_Item;
1362       ranFuncItemIe->criticality = CriticalityE2_ignore;
1363       ranFuncItemIe->value.present = RANfunction_ItemIEs__value_PR_RANfunction_Item;
1364       BuildRanFunctionItem(&ranFuncItemIe->value.choice.RANfunction_Item, ranFuncDb);
1365    }
1366    return ROK;
1367 }   
1368
1369 /*******************************************************************
1370  *
1371  * @brief De Allocate E2 Setup Request Message
1372  *
1373  * @details
1374  *
1375  *    Function : FreeE2SetupReq
1376  *
1377  *    Functionality: De-Allocating E2 Setup request Message
1378  *
1379  * @params[in] E2AP_PDU_t *e2apMsg
1380  
1381  * @return void
1382  *
1383  * ****************************************************************/
1384
1385 void FreeE2SetupReq(E2AP_PDU_t *e2apMsg)
1386 {
1387    uint8_t arrIdx = 0;
1388    uint8_t e2NodeAddListIdx =0, ranFuncAddListIdx;
1389    E2setupRequest_t *e2SetupReq;
1390    E2nodeComponentConfigAddition_List_t *e2NodeAddList;
1391    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
1392    RANfunctions_List_t *ranFunctionsList;
1393    RANfunction_ItemIEs_t *ranFuncItemIe;
1394    RANfunction_Item_t  *ranFunItem;
1395
1396    /* De-allocating Memory */
1397    if(e2apMsg != NULLP)
1398    {
1399       if(e2apMsg->choice.initiatingMessage != NULLP)
1400       {
1401          e2SetupReq = &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest; 
1402          if(e2SetupReq->protocolIEs.list.array != NULLP)
1403          {
1404             for(arrIdx = 0; arrIdx < e2SetupReq->protocolIEs.list.count; arrIdx++)
1405             {
1406                if(e2SetupReq->protocolIEs.list.array[arrIdx] != NULLP)
1407                {
1408                   switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
1409                   {
1410                      case ProtocolIE_IDE2_id_TransactionID:
1411                           break;
1412                      case ProtocolIE_IDE2_id_GlobalE2node_ID:
1413                         {
1414                            if(e2SetupReq->protocolIEs.list.array[arrIdx]->\
1415                                  value.choice.GlobalE2node_ID.choice.gNB != NULLP)
1416                            {
1417                               GlobalE2node_gNB_ID_t *gNbId = NULLP;
1418                               gNbId = e2SetupReq->protocolIEs.list.array[arrIdx]->\
1419                                       value.choice.GlobalE2node_ID.choice.gNB;
1420                               if(gNbId->global_gNB_ID.plmn_id.buf != NULLP)
1421                               {
1422                                  DU_FREE(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf,\
1423                                        gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size);
1424                                  DU_FREE(gNbId->global_gNB_ID.plmn_id.buf,\
1425                                        gNbId->global_gNB_ID.plmn_id.size);
1426                               }
1427
1428                               if(gNbId->gNB_DU_ID != NULLP)
1429                               {
1430                                  DU_FREE( gNbId->gNB_DU_ID->buf, gNbId->gNB_DU_ID->size);
1431                                  DU_FREE(gNbId->gNB_DU_ID, sizeof(GNB_DU_ID_t));
1432                               }
1433                               DU_FREE(e2SetupReq->protocolIEs.list.array[arrIdx]->value.\
1434                                     choice.GlobalE2node_ID.choice.gNB, sizeof(GlobalE2node_gNB_ID_t));
1435                            }
1436                            break;
1437                         }
1438                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
1439                      {
1440                          e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;
1441                          if(e2NodeAddList->list.array)
1442                          {
1443                              for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
1444                              {
1445                                 e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
1446                                 
1447                                 /* Free E2 Node Component Request Part */
1448                                 DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\
1449                                       e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentRequestPart.size);
1450                                 
1451                                 /* Free E2 Node Component Response Part */
1452                                 DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.\
1453                                       e2nodeComponentResponsePart.buf, \
1454                                       e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentResponsePart.size);
1455                                  
1456                                  /* Free E2 Node Component ID */
1457                                 if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1)
1458                                 {
1459                                     DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
1460                                     e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
1461                                     e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
1462                                     e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
1463                                     DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\
1464                                     sizeof(E2nodeComponentInterfaceF1_t));
1465                                 }
1466                                 DU_FREE(e2NodeAddList->list.array[e2NodeAddListIdx], sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
1467                              }
1468                              DU_FREE(e2NodeAddList->list.array, e2NodeAddList->list.size);
1469                          }
1470                          break;
1471                      }
1472                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
1473                      {
1474                         ranFunctionsList = &(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List);  
1475                         if(ranFunctionsList->list.array)
1476                         {  
1477                            for(ranFuncAddListIdx= 0; ranFuncAddListIdx< ranFunctionsList->list.count; ranFuncAddListIdx++)
1478                            {
1479                               if(ranFunctionsList->list.array[ranFuncAddListIdx])
1480                               {
1481                                  ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncAddListIdx];
1482                                  ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
1483                                  DU_FREE(ranFunItem->ranFunctionOID.buf, ranFunItem->ranFunctionOID.size);
1484                                  DU_FREE(ranFunItem->ranFunctionDefinition.buf, ranFunItem->ranFunctionDefinition.size);
1485                                  DU_FREE(ranFunctionsList->list.array[ranFuncAddListIdx], sizeof(RANfunction_ItemIEs_t));
1486                               }
1487                            }
1488                            DU_FREE(ranFunctionsList->list.array, ranFunctionsList->list.size);
1489                         }
1490                         break;
1491                      }
1492
1493                      default:
1494                         DU_LOG("\nERROR  --> E2AP: Invalid event at e2SetupRequet %ld ",\
1495                               (e2SetupReq->protocolIEs.list.array[arrIdx]->id));
1496                         break;
1497                   }
1498                   DU_FREE(e2SetupReq->protocolIEs.list.array[arrIdx], sizeof(E2setupRequestIEs_t));
1499                }
1500             }
1501             DU_FREE(e2SetupReq->protocolIEs.list.array, e2SetupReq->protocolIEs.list.size);
1502          }
1503          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1504       }
1505       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1506    }
1507 }
1508
1509 /*******************************************************************
1510  *
1511  * @brief Builds and Send the E2SetupRequest
1512  *
1513  * @details
1514  *
1515  *    Function : BuildAndSendE2SetupReq
1516  *
1517  * Functionality:Fills the E2SetupRequest
1518  *
1519  * @return ROK     - success
1520  *         RFAILED - failure
1521  *
1522  ******************************************************************/
1523
1524 uint8_t BuildAndSendE2SetupReq()
1525 {
1526    uint8_t arrIdx = 0, elementCnt=0;
1527    uint8_t transId = 0, ret = ROK;
1528    bool memAllocFailed;
1529    E2AP_PDU_t        *e2apMsg = NULLP;
1530    E2setupRequest_t  *e2SetupReq = NULLP;
1531    asn_enc_rval_t     encRetVal;       /* Encoder return value */
1532
1533    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup Request\n");
1534    do
1535    {
1536       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1537       if(e2apMsg == NULLP)
1538       {
1539          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1540          break;
1541       }
1542       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
1543       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1544       if(e2apMsg->choice.initiatingMessage == NULLP)
1545       {
1546          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1547          break;
1548       }
1549       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
1550       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2setup;
1551       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2setupRequest;
1552       e2SetupReq = &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest;
1553
1554       elementCnt = 4;
1555       e2SetupReq->protocolIEs.list.count = elementCnt;
1556       e2SetupReq->protocolIEs.list.size = elementCnt * sizeof(E2setupRequestIEs_t*);
1557
1558       /* Initialize the E2Setup members */
1559       DU_ALLOC(e2SetupReq->protocolIEs.list.array, \
1560             e2SetupReq->protocolIEs.list.size);
1561       if(e2SetupReq->protocolIEs.list.array == NULLP)
1562       {
1563          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
1564          break;
1565       }
1566       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
1567       {
1568          DU_ALLOC(e2SetupReq->protocolIEs.list.array[arrIdx],\
1569                sizeof(E2setupRequestIEs_t));
1570          if(e2SetupReq->protocolIEs.list.array[arrIdx] == NULLP)
1571          {
1572             memAllocFailed = true;
1573             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayarrIdx [%d]", arrIdx);
1574             break;
1575          }
1576       }
1577       if(memAllocFailed == true)
1578          break;
1579
1580       arrIdx = 0;
1581
1582       /* TransactionID */
1583       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
1584       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1585       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
1586       transId = assignTransactionId();
1587       e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
1588
1589       arrIdx++;
1590       /* GlobalE2node_gNB_ID */
1591       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_GlobalE2node_ID;
1592       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1593       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_GlobalE2node_ID;
1594       e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.present = GlobalE2node_ID_PR_gNB;
1595
1596       DU_ALLOC(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.\
1597             GlobalE2node_ID.choice.gNB, sizeof(GlobalE2node_gNB_ID_t));
1598       if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.\
1599             GlobalE2node_ID.choice.gNB == NULLP)
1600       {
1601          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for gNbId");
1602          break;
1603       }
1604       else
1605       {
1606          ret = BuildGlobalgNBId(e2SetupReq->protocolIEs.list.array[arrIdx]->value.\
1607                choice.GlobalE2node_ID.choice.gNB);
1608          if(ret != ROK)
1609          {
1610              DU_LOG("\nERROR  -->  E2AP : Failed to build Global Gnb Id");
1611              break;
1612          }
1613       }
1614       
1615       /* RAN Functions Added List */
1616       arrIdx++;
1617       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAdded;
1618       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1619       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_RANfunctions_List;
1620       if(BuildRanFunctionAddList(&(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List), ProcedureCodeE2_id_E2setup, 0, NULL)!=ROK)      
1621       {
1622          DU_LOG("\nERROR  -->  E2AP : Failed to create RAN Function");
1623          break;
1624       }
1625
1626       /* E2 Node Component Configuration Addition List */
1627       arrIdx++;
1628       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition;
1629       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1630       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_E2nodeComponentConfigAddition_List;
1631       if(BuildE2NodeConfigAddList(&(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List), ProcedureCodeE2_id_E2setup, 0, NULL)!=ROK)
1632       {
1633          DU_LOG("\nERROR  -->  E2AP : Failed to create E2 Node config list");
1634          break;
1635       }
1636
1637
1638
1639       /* Prints the Msg formed */
1640       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1641
1642       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1643       encBufSize = 0;
1644       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
1645             encBuf);
1646       if(encRetVal.encoded == ENCODE_FAIL)
1647       {
1648          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupRequest structure (at %s)\n",\
1649                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1650          break;
1651       }
1652       else
1653       {
1654          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2SetupRequest\n");
1655 #ifdef DEBUG_ASN_PRINT
1656          for(int i=0; i< encBufSize; i++)
1657          {
1658             printf("%x",encBuf[i]);
1659          }
1660 #endif
1661       }
1662       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
1663       {
1664          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
1665       }
1666       break;
1667    }while(true);
1668
1669    duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
1670    duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
1671    
1672    FreeE2SetupReq(e2apMsg);
1673    return ret;
1674 }/* End of BuildAndSendE2SetupReq */
1675
1676 /*******************************************************************
1677  *
1678  * @brief Builds RIC Action Admitted List
1679  *
1680  * @details
1681  *
1682  *    Function : BuildRicActionAdmitList
1683  *
1684  *    Functionality: Builds RIC Action Admitted List
1685  *
1686  * @params[in] Pointer to RIC Action Admitted List to be filled
1687  *             Subscription Response information
1688  * @return ROK     - success
1689  *         RFAILED - failure
1690  *
1691  * ****************************************************************/
1692 uint8_t BuildRicActionAdmitList(RICaction_Admitted_List_t *admitList, PendingSubsRspInfo *subsRspInfo)
1693 {
1694    uint8_t idx = 0;
1695    uint8_t elementCnt = 0;  
1696    RICaction_Admitted_ItemIEs_t *admitItem = NULLP;
1697
1698    elementCnt = subsRspInfo->numOfAcceptedActions;
1699
1700    admitList->list.count = elementCnt;
1701    admitList->list.size  = elementCnt * sizeof(RICaction_Admitted_ItemIEs_t *);
1702
1703    DU_ALLOC(admitList->list.array, admitList->list.size);
1704    if(admitList->list.array == NULLP)
1705    {
1706       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1707       return RFAILED;
1708    }
1709
1710    for(idx=0; idx<elementCnt; idx++)
1711    {
1712       DU_ALLOC(admitList->list.array[idx], sizeof(RICaction_Admitted_ItemIEs_t));
1713       if(admitList->list.array[idx] == NULLP)
1714       {
1715          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1716          return RFAILED;
1717       }
1718
1719       admitItem = (RICaction_Admitted_ItemIEs_t *)admitList->list.array[idx];
1720       admitItem->id = ProtocolIE_IDE2_id_RICaction_Admitted_Item;
1721       admitItem->criticality = CriticalityE2_reject;
1722       admitItem->value.present = RICaction_Admitted_ItemIEs__value_PR_RICaction_Admitted_Item;
1723       admitItem->value.choice.RICaction_Admitted_Item.ricActionID = subsRspInfo->acceptedActionList[idx]; 
1724    }
1725    return ROK;
1726 }
1727
1728 /*******************************************************************
1729  *
1730  * @brief Builds RIC Action Not Admitted List
1731  *
1732  * @details
1733  *
1734  *    Function : BuildRicActionNotAdmitList
1735  *
1736  *    Functionality: Builds RIC Action Not Admitted List
1737  *
1738  * @params[in] Pointer to RIC Action Not Admitted List to be filled
1739  *             Subscription Response information
1740  * @return ROK     - success
1741  *         RFAILED - failure
1742  *
1743  * ****************************************************************/
1744 uint8_t BuildRicActionNotAdmitList(RICaction_NotAdmitted_List_t *notAdmitList, PendingSubsRspInfo *subsRspInfo)
1745 {
1746    uint8_t idx = 0;
1747    uint8_t elementCnt = 0;  
1748    RICaction_NotAdmitted_ItemIEs_t *notAdmitItem = NULLP;
1749
1750    elementCnt = subsRspInfo->numOfRejectedActions;
1751
1752    notAdmitList->list.count = elementCnt;
1753    notAdmitList->list.size  = elementCnt * sizeof(RICaction_NotAdmitted_ItemIEs_t *);
1754
1755    DU_ALLOC(notAdmitList->list.array, notAdmitList->list.size);
1756    if(notAdmitList->list.array == NULLP)
1757    {
1758       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1759       return RFAILED;
1760    }
1761
1762    for(idx=0; idx<elementCnt; idx++)
1763    {
1764       DU_ALLOC(notAdmitList->list.array[idx], sizeof(RICaction_NotAdmitted_ItemIEs_t));
1765       if(notAdmitList->list.array[idx] == NULLP)
1766       {
1767          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1768          return RFAILED;
1769       }
1770
1771       notAdmitItem = (RICaction_NotAdmitted_ItemIEs_t *)notAdmitList->list.array[idx];
1772       notAdmitItem->id = ProtocolIE_IDE2_id_RICaction_NotAdmitted_Item;
1773       notAdmitItem->criticality = CriticalityE2_reject;
1774       notAdmitItem->value.present = RICaction_NotAdmitted_ItemIEs__value_PR_RICaction_NotAdmitted_Item;
1775       notAdmitItem->value.choice.RICaction_NotAdmitted_Item.ricActionID = \
1776          subsRspInfo->rejectedActionList[idx].id; 
1777       fillE2Cause(&notAdmitItem->value.choice.RICaction_NotAdmitted_Item.cause, \
1778          subsRspInfo->rejectedActionList[idx].failureCause);
1779    }
1780    return ROK;
1781 }
1782
1783 /*******************************************************************
1784  *
1785  * @breif Deallocation of BuildAndSendRicSubscriptionRsp memory
1786  *
1787  * @details
1788  *
1789  *    Function : FreeRicSubscriptionRsp
1790  *
1791  * Functionality:Free the RicSubscriptionRsp
1792  *
1793  * @param[in] E2AP_PDU_t *e2apRicMsg
1794  *
1795  * @return void
1796  *      
1797  ******************************************************************/
1798 void FreeRicSubscriptionRsp(E2AP_PDU_t  *e2apRicMsg)
1799 {
1800    RICsubscriptionResponse_t  *ricSubscriptionRsp= NULLP;
1801    uint8_t idx=0;
1802    uint8_t listIdx=0;
1803    RICaction_Admitted_List_t *admitList = NULLP;
1804    RICaction_NotAdmitted_List_t *notAdmitList = NULLP;
1805
1806    if(e2apRicMsg != NULLP)
1807    {
1808       if(e2apRicMsg->choice.successfulOutcome != NULLP)
1809       {
1810          ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
1811          if(ricSubscriptionRsp)
1812          {
1813             if(ricSubscriptionRsp->protocolIEs.list.array != NULLP)
1814             {
1815                for(idx=0; idx<ricSubscriptionRsp->protocolIEs.list.count; idx++)
1816                {
1817                   if(ricSubscriptionRsp->protocolIEs.list.array[idx] != NULLP)
1818                   {
1819                      switch(ricSubscriptionRsp->protocolIEs.list.array[idx]->id)
1820                      {
1821                         case ProtocolIE_IDE2_id_RICactions_Admitted:
1822                            {
1823                               admitList = &ricSubscriptionRsp->protocolIEs.list.\
1824                                              array[idx]->value.choice.RICaction_Admitted_List;
1825                               if(admitList->list.array != NULLP)
1826                               {
1827                                  for(listIdx=0 ; listIdx < admitList->list.count; listIdx++)
1828                                  {
1829                                     DU_FREE(admitList->list.array[listIdx], sizeof(RICaction_Admitted_ItemIEs_t));
1830                                  }
1831                                  DU_FREE(admitList->list.array, admitList->list.size);   
1832                               }
1833                               break;
1834                            }
1835                         case ProtocolIE_IDE2_id_RICactions_NotAdmitted:
1836                            {
1837                               notAdmitList = &ricSubscriptionRsp->protocolIEs.list.\
1838                                              array[idx]->value.choice.RICaction_NotAdmitted_List;
1839                               if(notAdmitList->list.array != NULLP)
1840                               {
1841                                  for(listIdx=0 ; listIdx < notAdmitList->list.count; listIdx++)
1842                                  {
1843                                     DU_FREE(notAdmitList->list.array[listIdx], sizeof(RICaction_NotAdmitted_ItemIEs_t));
1844                                  }
1845                                  DU_FREE(notAdmitList->list.array, notAdmitList->list.size);     
1846                               }
1847                               break;
1848                            }
1849                         default:
1850                            break;
1851                      }
1852                      DU_FREE(ricSubscriptionRsp->protocolIEs.list.array[idx], sizeof(RICsubscriptionResponse_IEs_t));
1853                   }
1854                }
1855                DU_FREE(ricSubscriptionRsp->protocolIEs.list.array, ricSubscriptionRsp->protocolIEs.list.size);
1856             }
1857          }   
1858          DU_FREE(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1859       }         
1860       DU_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));        
1861    }
1862 }
1863
1864 /*******************************************************************
1865  *
1866  * @brief Fill RIC Subscription Response IEs
1867  *
1868  * @details
1869  *
1870  *    Function : fillRicSubscriptionRsp
1871  *
1872  * functionality: Fill RIC Subscription Response IEs
1873  *
1874  * @param  Pointer to RIC subscription response
1875  *         Subscription response information
1876  * @return ROK     - success
1877  *         RFAILED - failure
1878  *
1879  ******************************************************************/
1880 uint8_t fillRicSubscriptionRsp(RICsubscriptionResponse_t *ricSubscriptionRsp, PendingSubsRspInfo *subsRspInfo)
1881 {
1882    uint8_t ieIdx = 0;
1883    uint8_t elementCnt = 0;
1884    RICsubscriptionResponse_IEs_t *subsRspIe = NULLP;
1885
1886    elementCnt = 3;
1887    if(subsRspInfo->numOfRejectedActions)
1888       elementCnt++;
1889
1890    ricSubscriptionRsp->protocolIEs.list.count = elementCnt;
1891    ricSubscriptionRsp->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionResponse_IEs_t);
1892    DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array, ricSubscriptionRsp->protocolIEs.list.size);
1893    if(ricSubscriptionRsp->protocolIEs.list.array == NULLP)
1894    {
1895       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at %s : line %d", __func__, __LINE__);
1896       return RFAILED;
1897    }
1898
1899    for(ieIdx=0; ieIdx<ricSubscriptionRsp->protocolIEs.list.count; ieIdx++)
1900    {
1901       DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionResponse_IEs_t));
1902       if(ricSubscriptionRsp->protocolIEs.list.array[ieIdx] == NULLP)
1903       {
1904          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d] : ieIdx [%d]", __func__, __LINE__,ieIdx);
1905          return RFAILED;
1906       }
1907    }
1908
1909    /* RIC Request ID */
1910    ieIdx=0;
1911    subsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
1912    subsRspIe->id = ProtocolIE_IDE2_id_RICrequestID;
1913    subsRspIe->criticality = CriticalityE2_reject;
1914    subsRspIe->value.present = RICsubscriptionRequest_IEs__value_PR_RICrequestID;
1915    subsRspIe->value.choice.RICrequestID.ricRequestorID = subsRspInfo->requestId.requestorId;
1916    subsRspIe->value.choice.RICrequestID.ricInstanceID = subsRspInfo->requestId.instanceId;
1917
1918    /* RAN Function ID */
1919    ieIdx++;
1920    subsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
1921    subsRspIe->id = ProtocolIE_IDE2_id_RANfunctionID;
1922    subsRspIe->criticality = CriticalityE2_reject;
1923    subsRspIe->value.present = RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
1924    subsRspIe->value.choice.RANfunctionID = subsRspInfo->ranFuncId;
1925
1926    /* RIC Action Admitted List */
1927    ieIdx++;
1928    subsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
1929    subsRspIe->id = ProtocolIE_IDE2_id_RICactions_Admitted;
1930    subsRspIe->criticality = CriticalityE2_reject;
1931    subsRspIe->value.present = RICsubscriptionResponse_IEs__value_PR_RICaction_Admitted_List;
1932    if(BuildRicActionAdmitList(&subsRspIe->value.choice.RICaction_Admitted_List, subsRspInfo) != ROK)
1933    {
1934       DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Action Admitted List in RIC Subscription Response");
1935       return RFAILED;
1936    }
1937
1938    /* RIC Action Not Admitted List */
1939    if(subsRspInfo->numOfRejectedActions)
1940    {
1941       ieIdx++;
1942       subsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
1943       subsRspIe->id = ProtocolIE_IDE2_id_RICactions_NotAdmitted;
1944       subsRspIe->criticality = CriticalityE2_reject;
1945       subsRspIe->criticality = CriticalityE2_reject;
1946       subsRspIe->value.present = RICsubscriptionResponse_IEs__value_PR_RICaction_NotAdmitted_List;
1947       if(BuildRicActionNotAdmitList(&subsRspIe->value.choice.RICaction_NotAdmitted_List, subsRspInfo) != ROK)
1948       {
1949          DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Action Not Admitted List in RIC Subscription Response");
1950          return RFAILED;
1951       }
1952    }
1953
1954    return ROK;
1955 }
1956
1957 /*******************************************************************
1958  *
1959  * @brief Builds and Send the RicSubscriptionRsp
1960  *
1961  * @details
1962  *
1963  *    Function : BuildAndSendRicSubscriptionRsp
1964  *
1965  * Functionality:Fills the RicSubscriptionRsp
1966  *
1967  * @return ROK     - success
1968  *         RFAILED - failure
1969  *
1970  ******************************************************************/
1971
1972 uint8_t BuildAndSendRicSubscriptionRsp(PendingSubsRspInfo *subsRspInfo)
1973 {
1974    uint8_t      ret = RFAILED;
1975    E2AP_PDU_t   *e2apRicMsg = NULLP;
1976    RICsubscriptionResponse_t  *ricSubscriptionRsp=NULLP;
1977    asn_enc_rval_t encRetVal; 
1978
1979    while(true)
1980    {
1981       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Response\n");
1982
1983       DU_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t)); 
1984       if(e2apRicMsg == NULLP)
1985       {
1986          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1987          break;
1988       }
1989
1990       e2apRicMsg->present =  E2AP_PDU_PR_successfulOutcome;
1991       DU_ALLOC(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1992       if(e2apRicMsg->choice.successfulOutcome == NULLP)
1993       {
1994          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC subscription Response failed");
1995          break;
1996       }
1997
1998       e2apRicMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
1999       e2apRicMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
2000       e2apRicMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse;
2001
2002       ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
2003
2004       if(fillRicSubscriptionRsp(ricSubscriptionRsp, subsRspInfo) != ROK)
2005       {
2006          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICsubscriptionResponseIE failed");
2007          break;
2008       }
2009
2010       /* Prints the Msg formed */
2011       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
2012
2013       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2014       encBufSize = 0;
2015       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf, encBuf);
2016       if(encRetVal.encoded == ENCODE_FAIL)
2017       {
2018          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Response structure (at %s)\n",\
2019                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2020          break;
2021       }
2022       else
2023       {
2024          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RIC subscription response \n");
2025 #ifdef DEBUG_ASN_PRINT
2026          for(int i=0; i< encBufSize; i++)
2027          {
2028             printf("%x",encBuf[i]);
2029          } 
2030 #endif
2031       } 
2032
2033       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
2034       {
2035          DU_LOG("\nERROR  -->  E2AP : Sending RIC Subscription Response failed");      
2036          break;
2037       }
2038
2039       ret = ROK;
2040       break;
2041
2042    }
2043
2044    FreeRicSubscriptionRsp(e2apRicMsg);
2045    return ret;
2046 }
2047
2048 /******************************************************************
2049  *
2050  * @brief Deallocation of memory allocated by aper decoder for e2 setup response
2051  *
2052  * @details
2053  *
2054  *    Function : freeAperDecodingOfE2SetupRsp
2055  *
2056  *    Functionality: Deallocation of memory allocated by aper decoder for e2
2057  *    setup response
2058  *
2059  * @params[in] E2setupResponse_t *e2SetRspMsg;
2060  * @return void
2061  *
2062  * ****************************************************************/
2063 void freeAperDecodingOfE2SetupRsp(E2setupResponse_t *e2SetRspMsg)
2064 {
2065    uint8_t arrIdx, e2NodeConfigAddAckListIdx;
2066    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem;
2067    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAddAckList;
2068
2069    if(e2SetRspMsg)
2070    {
2071       if(e2SetRspMsg->protocolIEs.list.array)
2072       {
2073          for(arrIdx=0; arrIdx<e2SetRspMsg->protocolIEs.list.count; arrIdx++)
2074          {
2075             if(e2SetRspMsg->protocolIEs.list.array[arrIdx])
2076             {
2077                switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
2078                {
2079                   case ProtocolIE_IDE2_id_TransactionID:
2080                      break;
2081
2082                   case ProtocolIE_IDE2_id_GlobalRIC_ID:
2083                      {
2084                         free(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.pLMN_Identity.buf);
2085                         free(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID.buf);
2086                         break;
2087                      }
2088
2089                   case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
2090                      {
2091                         e2NodeConfigAddAckList = &e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
2092                         if(e2NodeConfigAddAckList->list.array )
2093                         {
2094                            for(e2NodeConfigAddAckListIdx = 0; e2NodeConfigAddAckListIdx< e2NodeConfigAddAckList->list.count; e2NodeConfigAddAckListIdx++)
2095                            {
2096                               if(e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx])
2097                               {
2098                                  e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx];
2099                                  free(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.\
2100                                        e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf);
2101                                  free(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.\
2102                                        e2nodeComponentInterfaceTypeF1);
2103                                  free(e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx]);
2104                               }
2105                            }
2106                            free(e2NodeConfigAddAckList->list.array);
2107                         }
2108                         break;
2109                      }
2110                }
2111                free(e2SetRspMsg->protocolIEs.list.array[arrIdx]);  
2112             }
2113          }
2114          free(e2SetRspMsg->protocolIEs.list.array);
2115       }
2116    }
2117 }
2118 /******************************************************************
2119  *
2120  * @brief Processes E2 Setup Response sent by RIC
2121  *
2122  * @details
2123  *
2124  *    Function : procE2SetupRsp
2125  *
2126  *    Functionality: Processes E2 Setup Response sent by RIC
2127  *
2128  * @params[in] E2AP_PDU_t ASN decoded E2AP message
2129  * @return ROK     - success
2130  *         RFAILED - failure
2131  *
2132  * ****************************************************************/
2133
2134 uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg)
2135 {
2136    uint8_t arrIdx =0, transId=0, idx=0; 
2137    uint32_t recvBufLen;             
2138    E2setupResponse_t *e2SetRspMsg=NULL;
2139    CmLList         *node=NULL;
2140    E2NodeComponent *e2NodeComponentInfo=NULL;
2141    E2nodeComponentConfigAdditionAck_List_t *e2NodeCfgAckList=NULL;
2142    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem=NULL;
2143
2144    DU_LOG("\nINFO   -->  E2AP : E2 Setup Response received"); 
2145    duCb.e2Status = TRUE; //Set E2 status as true
2146    e2SetRspMsg = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
2147
2148    for(arrIdx=0; arrIdx<e2SetRspMsg->protocolIEs.list.count; arrIdx++)
2149    {
2150       switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
2151       {
2152          case ProtocolIE_IDE2_id_TransactionID:
2153             {
2154                transId = e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
2155                if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
2156                      (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
2157                {
2158                   memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
2159                }
2160                else
2161                {
2162                   DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
2163                   return RFAILED;
2164                }
2165                break;
2166             }
2167
2168          case ProtocolIE_IDE2_id_GlobalRIC_ID:
2169             {
2170                /* To store the Ric Id Params */
2171                recvBufLen = sizeof(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value\
2172                      .choice.GlobalRIC_ID.pLMN_Identity.size);
2173                   memcpy(&duCb.e2apDb.ricId.plmnId, e2SetRspMsg->protocolIEs.list.array[arrIdx]\
2174                         ->value.choice.GlobalRIC_ID.pLMN_Identity.buf, recvBufLen);
2175                bitStringToInt(&e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID, &duCb.e2apDb.ricId);
2176                /*TODO : duCb.e2apDb.ricId.plmnId memory to be deallocated after the usage */
2177                break;
2178             }
2179
2180          case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
2181          {
2182             e2NodeCfgAckList = &e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
2183             for(idx =0; idx <e2NodeCfgAckList->list.count; idx++)
2184             {
2185                e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeCfgAckList->list.array[idx];
2186                switch(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present)
2187                {
2188                   case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
2189                      {
2190                         e2NodeComponentInfo = fetchE2NodeComponentInfo(F1, E2_NODE_COMPONENT_ADD, &node);
2191                         if(!e2NodeComponentInfo)
2192                         {
2193                            DU_LOG("\nERROR  --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__);
2194                            return RFAILED;
2195                         }
2196                         else
2197                         {
2198                            cmLListDelFrm(&duCb.e2apDb.e2NodeComponentList, node);
2199                            DU_FREE(e2NodeComponentInfo->componentRequestPart, e2NodeComponentInfo->reqBufSize);
2200                            DU_FREE(e2NodeComponentInfo->componentResponsePart, e2NodeComponentInfo->rspBufSize);
2201                            DU_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent));
2202                            DU_FREE(node, sizeof(CmLList));
2203                         }
2204                         break;
2205                      }
2206                   default:
2207                      break;
2208                }
2209             }
2210             break;
2211          }
2212
2213          default:
2214             DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2SetupRsp:%ld",
2215                   e2SetRspMsg->protocolIEs.list.array[arrIdx]->id);
2216             break;
2217       }
2218    }
2219    freeAperDecodingOfE2SetupRsp(e2SetRspMsg);
2220
2221    if(duSendE2NodeConfigurationUpdate() != ROK)
2222    {
2223       DU_LOG("\nERROR  -->  E2AP : Failed to send E2 node config update");
2224       return RFAILED;
2225    }
2226    return ROK;
2227 }
2228
2229 /*******************************************************************
2230  *
2231  * @brief Free RIC Subscription Request
2232  *
2233  * @details
2234  *
2235  *    Function : freeAperDecodingOfRicSubsReq
2236  *
2237  * Functionality : Free RIC Subscription Request
2238  *
2239  * @return void
2240  *
2241  ******************************************************************/
2242 void freeAperDecodingOfRicSubsReq(RICsubscriptionRequest_t *ricSubscriptionReq)
2243 {
2244    uint8_t idx = 0;
2245    uint8_t elementIdx = 0;
2246    RICsubscriptionDetails_t *subsDetails = NULLP;
2247    RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
2248
2249    if(ricSubscriptionReq->protocolIEs.list.array)
2250    {
2251       for(idx=0; idx < ricSubscriptionReq->protocolIEs.list.count; idx++)
2252       {
2253          switch(ricSubscriptionReq->protocolIEs.list.array[idx]->id)
2254          {
2255             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
2256                {
2257                   subsDetails = &(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails);
2258                   free(subsDetails->ricEventTriggerDefinition.buf);
2259
2260                   if(subsDetails->ricAction_ToBeSetup_List.list.array)
2261                   {
2262                      for(elementIdx = 0; elementIdx < subsDetails->ricAction_ToBeSetup_List.list.count; elementIdx++)
2263                      {
2264                         if(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
2265                         {
2266                            actionItem = (RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx];
2267                            if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
2268                            {
2269                               free(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf);
2270                               free(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition);
2271                            }
2272                            free(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx]);
2273                         }
2274                      }
2275                      free(subsDetails->ricAction_ToBeSetup_List.list.array);
2276                   }
2277                   break;
2278                }
2279          }
2280          free(ricSubscriptionReq->protocolIEs.list.array[idx]);
2281       }
2282       free(ricSubscriptionReq->protocolIEs.list.array);
2283    }
2284 }
2285
2286 /*******************************************************************
2287  *
2288  * @brief Free Event Trigger Definition
2289  *
2290  * @details
2291  *
2292  *    Function : freeAperDecodingOfEventTriggerDef
2293  *
2294  *    Functionality: Free Event Trigger Definition
2295  *
2296  * @params[in] E2SM-KPM Event Trigger Definition
2297  * @return void
2298  *
2299  * ****************************************************************/
2300 void  freeAperDecodingOfEventTriggerDef(E2SM_KPM_EventTriggerDefinition_t *eventTiggerDef)
2301 {
2302    if(eventTiggerDef)
2303    {
2304       switch(eventTiggerDef->eventDefinition_formats.present)
2305       {
2306          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING:
2307             break;
2308
2309          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1:
2310             free(eventTiggerDef->eventDefinition_formats.choice.eventDefinition_Format1);
2311             break;
2312       }
2313    }
2314 }
2315
2316 /*******************************************************************
2317  *
2318  * @brief Extract E2SM-KPM Event trigger definition
2319  *
2320  * @details
2321  *
2322  *    Function : extractEventTriggerDef
2323  *
2324  * Functionality : This function :
2325  *     - Decodes E2SM-KPM Event Trigger Definition
2326  *     - Validates that even trigger style is supported by E2 node
2327  *     - Stores event trigger details in local DB
2328  *
2329  * @params[in] RAN Function Database structure
2330  *             RIC Subscription Info to be added to RAN function
2331  *             RIC Event Trigger Definition buffer received from RIC
2332  * @return ROK     - success
2333  *         RFAILED - failure
2334  *
2335  ******************************************************************/
2336 uint8_t extractEventTriggerDef(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \
2337    RICeventTriggerDefinition_t *ricEventTriggerDef, E2FailureCause *failureCause)
2338 {
2339    uint8_t ret = RFAILED;
2340    uint8_t eventIdx = 0;
2341    asn_dec_rval_t rval ={0};
2342    E2SM_KPM_EventTriggerDefinition_t eventTiggerDef, *eventTiggerDefPtr = NULLP;
2343
2344    /* Decoding E2SM-KPM Even Trigger Definition */
2345    eventTiggerDefPtr = &eventTiggerDef;
2346    memset(eventTiggerDefPtr, 0, sizeof(E2SM_KPM_EventTriggerDefinition_t));
2347
2348    rval = aper_decode(0, &asn_DEF_E2SM_KPM_EventTriggerDefinition, (void **)&eventTiggerDefPtr, ricEventTriggerDef->buf,\
2349          ricEventTriggerDef->size, 0, 0);
2350    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
2351    {
2352       DU_LOG("\nERROR  -->  E2AP : ASN decode failed for E2SM-KPM Event Trigger Definition");
2353       failureCause->causeType = E2_PROTOCOL; 
2354       failureCause->cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE;
2355       return RFAILED;
2356    }
2357    printf("\n");
2358    xer_fprint(stdout, &asn_DEF_E2SM_KPM_EventTriggerDefinition, eventTiggerDefPtr);
2359
2360    /* Validating the received event trigger definition format */
2361    for(eventIdx = 0; eventIdx < ranFuncDb->numOfEventTriggerStyleSupported; eventIdx++)
2362    {
2363       if((eventTiggerDefPtr->eventDefinition_formats.present != \
2364          E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING) && \
2365          (eventTiggerDefPtr->eventDefinition_formats.present == ranFuncDb->eventTriggerStyleList[eventIdx].formatType))
2366       {
2367          ricSubscriptionInfo->eventTriggerDefinition.formatType = ranFuncDb->eventTriggerStyleList[eventIdx].formatType;
2368          ricSubscriptionInfo->eventTriggerDefinition.choice.format1.reportingPeriod = \
2369             eventTiggerDefPtr->eventDefinition_formats.choice.eventDefinition_Format1->reportingPeriod;
2370
2371          ret = ROK;
2372          break;
2373       }
2374    }
2375
2376    if(ret == RFAILED)
2377    {
2378       failureCause->causeType = E2_RIC_REQUEST;
2379       failureCause->cause = E2_EVENT_TRIGGER_NOT_SUPPORTED;
2380    }
2381    /* Free E2SM_KPM_EventTriggerDefinition_t */
2382    freeAperDecodingOfEventTriggerDef(eventTiggerDefPtr);
2383    return ret;
2384 }
2385
2386 /*******************************************************************
2387  *
2388  * @brief Free RIC Action Definition
2389  *
2390  * @details
2391  *
2392  *    Function :  freeAperDecodingOfRicActionDefinition
2393  *
2394  *    Functionality: Free RIC Action Definition
2395  *
2396  * @params[in] E2SM-KPM Action definition
2397  * @return void
2398  *
2399  * ****************************************************************/
2400 void  freeAperDecodingOfRicActionDefinition(E2SM_KPM_ActionDefinition_t *actionDef)
2401 {
2402    uint8_t  elementIdx = 0;
2403    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
2404    MeasurementInfoItem_t *measItem = NULLP;
2405
2406    switch(actionDef->actionDefinition_formats.present)
2407    {
2408       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
2409          {
2410             if(actionDef->actionDefinition_formats.choice.actionDefinition_Format1)
2411             {
2412                actionFormat1 = actionDef->actionDefinition_formats.choice.actionDefinition_Format1;
2413                if(actionFormat1->measInfoList.list.array)
2414                {
2415                   for(elementIdx = 0; elementIdx < actionFormat1->measInfoList.list.count; elementIdx++)
2416                   {
2417                      if(actionFormat1->measInfoList.list.array[elementIdx])
2418                      {
2419                         measItem = actionFormat1->measInfoList.list.array[elementIdx];
2420                         switch(measItem->measType.present)
2421                         {
2422                            case MeasurementType_PR_NOTHING:
2423                               break;
2424
2425                            case MeasurementType_PR_measName:
2426                            {
2427                               free(measItem->measType.choice.measName.buf);
2428                               break;
2429                            }
2430
2431                            case MeasurementType_PR_measID:
2432                               break;
2433                         }
2434                         free(measItem);
2435                      }
2436                   }
2437                   free(actionFormat1->measInfoList.list.array);
2438                }
2439                free(actionFormat1);
2440             }
2441             break;
2442          }
2443       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format2:
2444       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format3:
2445       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format4:
2446       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format5:
2447       default:
2448          break;   
2449    }
2450 }
2451
2452 /*******************************************************************
2453  *
2454  * @brief Extract Measurement Info list from action definition
2455  *
2456  * @details
2457  *
2458  *    Function : extractMeasInfoList
2459  *
2460  * Functionality : This function :
2461  *     - Traverses Measurement-to-be-subscribed list
2462  *     - Validates that each measurement in Measurement-to-be-subscribed
2463  *       list is supported in RAN-Function->Measurement-supported list.
2464  *     - If all measurements in an action is supported by RAN function,
2465  *       it is added to measurement-subscribed list in local DB
2466  *
2467  * @params[in] Measurement Info supported list by RAN function
2468  *             Measurement Info to be subscribed as requested by RIC
2469  *             Measurement Info finally subscribed
2470  *             Memory failure indicator
2471  * @return ROK     - success
2472  *         RFAILED - failure
2473  *
2474  ******************************************************************/
2475 uint8_t extractMeasInfoList(CmLListCp *measInfoSupportedList, MeasurementInfoList_t *measInfoToBeSubscribedList, \
2476    CmLListCp *measInfoSubscribedList, bool *memFailure)
2477 {
2478    uint8_t elementIdx = 0;
2479    MeasurementInfoForAction *measInfoSupportedDb = NULLP;
2480    MeasurementInfo *measInfoSubscribedDb = NULLP, *measInfoToDel = NULLP;
2481    CmLList *supportedMeasNode = NULLP, *measToAddNode = NULLP, *measToDelNode = NULLP;;
2482    MeasurementInfoItem_t *measItem = NULLP;
2483
2484    /* Validate Measurement list is supported by E2 node. 
2485     *
2486     * Traverse and compare the Measurement-Supported List in E2
2487     * node with Measurement-to-be-subscribed list received from RIC.
2488     * If a match is found, add it to measurement-subscription list.
2489     */
2490    for(elementIdx = 0; elementIdx < measInfoToBeSubscribedList->list.count; elementIdx++)
2491    {
2492       measInfoSubscribedDb = NULLP;
2493       measToAddNode = NULLP;
2494       measItem = measInfoToBeSubscribedList->list.array[elementIdx];
2495
2496       CM_LLIST_FIRST_NODE(measInfoSupportedList, supportedMeasNode);
2497       while(supportedMeasNode)
2498       {
2499          measInfoSupportedDb = (MeasurementInfoForAction*)supportedMeasNode->node;
2500          switch(measItem->measType.present)
2501          {
2502             case MeasurementType_PR_measName:
2503                {
2504                   if(!strcmp(measInfoSupportedDb->measurementTypeName, (char *)measItem->measType.choice.measName.buf))
2505                   {
2506                      DU_ALLOC(measInfoSubscribedDb, sizeof(MeasurementInfo));
2507                   }
2508                   break;
2509                }
2510
2511             case MeasurementType_PR_measID:
2512                {
2513                   if(measInfoSupportedDb->measurementTypeId == measItem->measType.choice.measID)
2514                   {
2515                      DU_ALLOC(measInfoSubscribedDb, sizeof(MeasurementInfo));
2516                   }
2517                   break;
2518                }
2519
2520             default:
2521                {
2522                   DU_LOG("\nERROR  ->  DUAPP: Invalid Measurement-type identifier in \
2523                         E2SM-KPM Action Definition Format");
2524                   break;
2525                }
2526          } /* End of switch, for measurement type identifier */
2527
2528          /* If measurement type is supported, add to measurement-subscription list */
2529          if(measInfoSubscribedDb)
2530          {
2531             measInfoSubscribedDb->measurementTypeId = measInfoSupportedDb->measurementTypeId;
2532             memcpy(measInfoSubscribedDb->measurementTypeName, measInfoSupportedDb->measurementTypeName, \
2533                   strlen(measInfoSupportedDb->measurementTypeName));
2534
2535             DU_ALLOC(measToAddNode, sizeof(CmLList));
2536             if(measToAddNode)
2537             {
2538                measToAddNode->node = (PTR) measInfoSubscribedDb;
2539                cmLListAdd2Tail(measInfoSubscribedList, measToAddNode);
2540
2541                /* Break out of while loop if measurement info is found in measurement-supported list  */
2542                break;
2543             }
2544             else
2545             {
2546                DU_FREE(measInfoSubscribedDb, sizeof(MeasurementInfo));
2547                measInfoSubscribedDb = NULLP;
2548                *memFailure = true;
2549                break;
2550             }
2551          }
2552
2553          supportedMeasNode = supportedMeasNode->next;  
2554
2555       } /* End of while for traversing measurement-supported list in a report style */
2556
2557       /* If a measurement-to-be-subscribed is not found in measurement-supported list in this report style
2558        * Then :
2559        * Delete all entries from measurement-subscription list and
2560        * Break out of for loop to search in next report style */
2561       if(!measInfoSubscribedDb)
2562       {
2563          deleteMeasurementInfoList(measInfoSubscribedList);
2564          break;
2565       }
2566
2567    } /* End of for loop , traversing measurement-to-be-subscribed list */
2568
2569    /* If all measurement-to-be-subscribed was found in measurement-supported list and 
2570     * was added to measurement-subscription list successfully, return from here */
2571    if(measInfoToBeSubscribedList->list.count == measInfoSubscribedList->count)
2572       return ROK;
2573
2574    return RFAILED;
2575 }
2576
2577 /*******************************************************************
2578  *
2579  * @brief Extract E2SM-KPM Action definition
2580  *
2581  * @details
2582  *
2583  *    Function : extractRicActionDef
2584  *
2585  * Functionality : This function :
2586  *     - Decodes E2SM-KPM Action Definition
2587  *     - Validates that action is supported by E2 node
2588  *     - Stores action details in local DB
2589  *
2590  * @params[in] RAN Function Database structure
2591  *             RIC subscription's Action definition to be added to 
2592  *                RAN function
2593  *             RIC Action Definition buffer received from RIC
2594  * @return ROK     - success
2595  *         RFAILED - failure
2596  *
2597  ******************************************************************/
2598 uint8_t extractRicActionDef(RanFunction *ranFuncDb, ActionDefinition *actionDefDb, RICactionDefinition_t *ricActionDef,\
2599    E2FailureCause *failureCause)
2600 {
2601    bool memFailure = false;
2602    uint8_t styleIdx = 0;
2603    asn_dec_rval_t rval ={0};
2604
2605    E2SM_KPM_ActionDefinition_t actionDef, *actionDefPtr = NULLP;
2606    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
2607    CmLListCp *measInfoSupportedList = NULLP;
2608    CmLListCp *measInfoSubscribedList = NULLP;
2609
2610    /* Decoding E2SM-KPM Action Definition */
2611    actionDefPtr = &actionDef;
2612    memset(actionDefPtr, 0, sizeof(E2SM_KPM_EventTriggerDefinition_t));
2613
2614    rval = aper_decode(0, &asn_DEF_E2SM_KPM_ActionDefinition, (void **)&actionDefPtr, ricActionDef->buf,\
2615          ricActionDef->size, 0, 0);
2616    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
2617    {
2618       DU_LOG("\nERROR  -->  E2AP : ASN decode failed for E2SM-KPM Action Definition");
2619       failureCause->causeType = E2_PROTOCOL;
2620       failureCause->cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE;
2621       return RFAILED;
2622    }
2623    printf("\n");
2624    xer_fprint(stdout, &asn_DEF_E2SM_KPM_ActionDefinition, actionDefPtr);
2625
2626
2627    /* Validate if Report style to subscribe is supported by E2 Node */
2628    for(styleIdx= 0; styleIdx < ranFuncDb->numOfReportStyleSupported; styleIdx++)
2629    {
2630       /* Validate Report style type and report style format type is supported by E2 Node */
2631       if((ranFuncDb->reportStyleList[styleIdx].reportStyle.styleType == actionDefPtr->ric_Style_Type) &&
2632             (ranFuncDb->reportStyleList[styleIdx].reportStyle.formatType == actionDefPtr->actionDefinition_formats.present))
2633       {
2634          /* Fetch Report stype type and format type */
2635          actionDefDb->styleType = actionDefPtr->ric_Style_Type;
2636          actionDefDb->formatType = actionDefPtr->actionDefinition_formats.present;
2637
2638          switch(actionDefPtr->actionDefinition_formats.present)
2639          {
2640             case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
2641                {
2642                   actionFormat1 = actionDefPtr->actionDefinition_formats.choice.actionDefinition_Format1; 
2643
2644                   /* Fetch granularity period */
2645                   actionDefDb->choice.format1.granularityPeriod = actionFormat1->granulPeriod;
2646
2647                   /* Validate and add the Measurement to subscription list */
2648                   measInfoSupportedList = &ranFuncDb->reportStyleList[styleIdx].measurementInfoList;
2649                   measInfoSubscribedList = &actionDefDb->choice.format1.measurementInfoList;
2650                   if(extractMeasInfoList(measInfoSupportedList, &actionFormat1->measInfoList, \
2651                      measInfoSubscribedList, &memFailure) == ROK)
2652                   {
2653                      if(!memFailure)
2654                      {
2655                         /* Free E2SM_KPM_ActionDefinition_t */
2656                         freeAperDecodingOfRicActionDefinition(actionDefPtr);
2657                         return ROK;
2658                      }
2659                   }
2660
2661                   break;  /* End of E2SM-KPM Action definition format 1 case */
2662                }
2663
2664             default :
2665                {
2666                   DU_LOG("\nERROR  ->  DUAPP: Only E2SM-KPM Action Definition Format 1 is supported");
2667                   break;
2668                }
2669          } /* End of switch for E2SM-KPM Action definition formats */
2670       }
2671
2672       if(memFailure)
2673       {
2674          failureCause->causeType = E2_MISCELLANEOUS;
2675          failureCause->cause = E2_MISCELLANEOUS_CAUSE_UNSPECIFIED; 
2676          break;
2677       }
2678    } /* End of for loop, traversing Report-styles-supported list in E2 node */
2679
2680    /* Memset action Db and Free E2SM_KPM_ActionDefinition_t */
2681    memset(actionDefDb, 0, sizeof(ActionDefinition));
2682    freeAperDecodingOfRicActionDefinition(actionDefPtr);
2683
2684    if(failureCause->causeType == E2_NOTHING)
2685    {
2686       failureCause->causeType = E2_RIC_REQUEST;
2687       failureCause->cause = E2_ACTION_NOT_SUPPORTED;
2688    }
2689    return RFAILED;
2690 }
2691
2692 /*******************************************************************
2693  *
2694  * @brief Extract RIC Action to be setup
2695  *
2696  * @details
2697  *
2698  *    Function : extractRicActionToBeSetup
2699  *
2700  * Functionality : This function :
2701  *     - Validates that each action-to-be-setup is supported by E2 node
2702  *     - Stores event trigger details in local DB
2703  *
2704  * @params[in] RAN Function Database structure
2705  *             RIC Subscription Info to be added to RAN function
2706  *             RIC Action To Be Setup List received from RIC
2707  * @return ROK     - success
2708  *         RFAILED - failure
2709  *
2710  ******************************************************************/
2711 uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \
2712    RICactions_ToBeSetup_List_t *actionList, E2FailureCause *failureCause, PendingSubsRspInfo *subsRsp)
2713 {
2714    uint8_t actionIdx = 0;
2715    uint8_t ricActionId = 0;
2716    RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
2717
2718    if(actionList->list.array)
2719    {
2720       for(actionIdx = 0; actionIdx < actionList->list.count; actionIdx++)
2721       {
2722          actionItem =(RICaction_ToBeSetup_ItemIEs_t *)actionList->list.array[actionIdx];
2723          switch(actionItem->id)
2724          {
2725             case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item:
2726                {
2727                   /* If Action type is REPORT and 
2728                    * If RIC action definition's extraction and validation passes, 
2729                    * Then : 
2730                    * This action is added to action sequence list of subscription info */
2731                   ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
2732
2733                   if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType == RICactionType_report)
2734                   {
2735                      ricSubscriptionInfo->actionSequence[ricActionId].actionId = ricActionId;
2736                      ricSubscriptionInfo->actionSequence[ricActionId].type = REPORT;
2737
2738                      if(extractRicActionDef(ranFuncDb, &ricSubscriptionInfo->actionSequence[ricActionId].definition, \
2739                         actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, failureCause) == ROK)
2740                      {
2741                         ricSubscriptionInfo->actionSequence[ricActionId].action = CONFIG_ADD;
2742                         ricSubscriptionInfo->numOfActions++;
2743                         break;
2744                      }
2745                   }
2746
2747                   /* In case of any failure, action is rejected
2748                    * Added to rejected-action-list in subscription response */
2749                   deleteActionSequence(&ricSubscriptionInfo->actionSequence[ricActionId]);
2750
2751                   subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].id = ricActionId;
2752                   if(failureCause->causeType == E2_NOTHING)
2753                   {
2754                      failureCause->causeType = E2_RIC_REQUEST;
2755                      failureCause->cause = E2_ACTION_NOT_SUPPORTED;
2756                   }
2757                   memcpy(&subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].failureCause, \
2758                         failureCause, sizeof(E2FailureCause));
2759                   subsRsp->numOfRejectedActions++;
2760                   break;
2761                }
2762             default:
2763                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id);
2764                break;
2765          }
2766       }
2767    }
2768
2769    /* If there is even 1 action that can be added, return ROK */
2770    if(ricSubscriptionInfo->numOfActions)
2771       return ROK;
2772
2773    if(failureCause->causeType == E2_NOTHING)
2774    {
2775       failureCause->causeType = E2_RIC_REQUEST;
2776       failureCause->cause = E2_ACTION_NOT_SUPPORTED;
2777    }
2778    return RFAILED;
2779 }
2780
2781 /******************************************************************
2782  *
2783  * @brief Processes RIC Subscription Req sent by RIC
2784  *
2785  * @details
2786  *
2787  *    Function : procRicSubscriptionRequest
2788  *
2789  *    Functionality: Processes RIC Subscription Request from RIC
2790  *
2791  * @params[in] E2AP_PDU_t ASN decoded E2AP message
2792  * @return ROK     - success
2793  *         RFAILED - failure
2794  *
2795  * ****************************************************************/
2796 uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg)
2797 {
2798    uint8_t idx = 0, actionIdx = 0; 
2799    uint8_t ret = ROK;
2800    uint16_t ranFuncId = 0;
2801    RicRequestId ricReqId;
2802    CmLList  *ricSubscriptionNode = NULLP;
2803    RanFunction *ranFuncDb = NULLP;
2804    RICsubscriptionRequest_t *ricSubsReq = NULLP;
2805    RICsubscriptionDetails_t *subsDetails = NULLP;
2806    RicSubscription *ricSubscriptionInfo = NULLP;
2807    E2FailureCause failureCause;
2808
2809    DU_LOG("\nINFO   -->  E2AP : RIC Subscription request received"); 
2810
2811    memset(&failureCause, 0, sizeof(E2FailureCause));
2812    memset(&ricReqId, 0, sizeof(RicRequestId));
2813
2814    ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
2815    for(idx=0; idx<ricSubsReq->protocolIEs.list.count; idx++)
2816    {
2817       if(ricSubsReq->protocolIEs.list.array[idx])
2818       {
2819          switch(ricSubsReq->protocolIEs.list.array[idx]->id)
2820          {
2821             case ProtocolIE_IDE2_id_RICrequestID:
2822                {
2823                   ricReqId.requestorId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID;
2824                   ricReqId.instanceId  = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID;
2825
2826                   break;
2827                }
2828
2829             case ProtocolIE_IDE2_id_RANfunctionID:
2830                {
2831                   ranFuncId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID; 
2832
2833                   /* Validating RAN Function id */
2834                   ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
2835
2836                   if(!ranFuncDb)
2837                   {
2838                      failureCause.causeType = E2_RIC_REQUEST;
2839                      failureCause.cause = E2_RAN_FUNCTION_ID_INVALID;
2840                      ret = RFAILED;
2841                      break;
2842                   }
2843
2844                   if(ranFuncDb->numPendingSubsRsp >= MAX_PENDING_SUBSCRIPTION_RSP)
2845                   {
2846                      failureCause.causeType = E2_RIC_REQUEST;
2847                      failureCause.cause = E2_FUNCTION_RESOURCE_LIMIT; 
2848                      ret = RFAILED;
2849                      break;
2850                   }
2851
2852                   DU_ALLOC(ricSubscriptionInfo, sizeof(RicSubscription));
2853                   if(!ricSubscriptionInfo)
2854                   {
2855                      DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for ricSubscriptionInfo");
2856                      failureCause.causeType = E2_MISCELLANEOUS;
2857                      failureCause.cause = E2_MISCELLANEOUS_CAUSE_UNSPECIFIED;
2858                      ret = RFAILED;
2859                      break;
2860                   }
2861                   ricSubscriptionInfo->requestId.requestorId = ricReqId.requestorId;
2862                   ricSubscriptionInfo->requestId.instanceId = ricReqId.instanceId;
2863                   ricSubscriptionInfo->ranFuncId = ranFuncId;
2864
2865                   for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
2866                   {
2867                      ricSubscriptionInfo->actionSequence[actionIdx].actionId = -1;
2868                   }
2869
2870                   memset(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp], 0, sizeof(PendingSubsRspInfo));
2871                   memcpy(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp].requestId, 
2872                         &ricReqId, sizeof(RicRequestId));
2873                   ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp].ranFuncId = ranFuncId;
2874                   break;
2875                }
2876
2877             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
2878                {
2879                   subsDetails = &ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails;
2880
2881                   /* Decode, Validate and record Event Trigger Definition */
2882                   if(extractEventTriggerDef(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricEventTriggerDefinition, \
2883                      &failureCause) != ROK)
2884                   {
2885                      ret = RFAILED;
2886                      break;
2887                   }
2888
2889                   /* Decode, Validate and record RIC actions */
2890                   if(extractRicActionToBeSetup(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricAction_ToBeSetup_List, \
2891                      &failureCause, &ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp]) != ROK)
2892                   {
2893                      ret = RFAILED;
2894                      break;
2895                   }
2896                }
2897                break;
2898
2899             default:
2900                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RIC SubsReq:%ld",
2901                      ricSubsReq->protocolIEs.list.array[idx]->id);
2902                break;
2903          }
2904
2905          if(ret == RFAILED)
2906             break;
2907       }
2908    }
2909
2910    freeAperDecodingOfRicSubsReq(ricSubsReq);
2911
2912    if(ret == ROK)
2913    {
2914       cmInitTimers(&(ricSubscriptionInfo->ricSubsReportTimer), 1);
2915
2916       /* Add RAN subcription detail to RAN function */
2917       DU_ALLOC(ricSubscriptionNode, sizeof(CmLList));
2918       if(ricSubscriptionNode)
2919       {
2920          ricSubscriptionNode->node = (PTR) ricSubscriptionInfo;
2921          cmLListAdd2Tail(&ranFuncDb->subscriptionList, ricSubscriptionNode);
2922       }
2923
2924       ranFuncDb->numPendingSubsRsp++;
2925
2926 #ifdef KPI_CALCULATION
2927       /* Send statistics request to other DU entities */
2928       BuildAndSendStatsReq(ricSubscriptionInfo);
2929 #endif      
2930    }
2931    else
2932    {
2933       DU_FREE(ricSubscriptionInfo, sizeof(RicSubscription));
2934
2935       if(ranFuncDb)
2936       {
2937          memset(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp], 0, sizeof(PendingSubsRspInfo));
2938       }
2939
2940       /* Send RIC Subcription Failure */
2941       BuildAndSendRicSubscriptionFailure(ricReqId, ranFuncId, failureCause);
2942    }
2943
2944    return ret;
2945 }
2946
2947 /******************************************************************
2948  *
2949  * @brief Free RIC Subscription Failure
2950  *
2951  * @details
2952  *
2953  *    Function : FreeRicSubscriptionFailure
2954  *
2955  *    Functionality: Free RIC Subscription Failure
2956  *
2957  * @params[in] E2AP PDU
2958  * @return void
2959  *
2960  * ****************************************************************/
2961 void FreeRicSubscriptionFailure(E2AP_PDU_t *e2apMsg)
2962 {
2963    uint8_t elemIdx = 0;
2964    RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP;
2965
2966    if(e2apMsg)
2967    {
2968       if(e2apMsg->choice.unsuccessfulOutcome)
2969       {
2970          ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
2971          if(ricSubscriptionFailure->protocolIEs.list.array)
2972          {
2973             for(elemIdx = 0; elemIdx < ricSubscriptionFailure->protocolIEs.list.count; elemIdx++)
2974             {
2975                DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t));
2976             }
2977             DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size);
2978          }
2979          DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
2980       }
2981       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2982    }
2983 }
2984
2985 /******************************************************************
2986  *
2987  * @brief Fill and Send RIC Subscription Failure to RIC
2988  *
2989  * @details
2990  *
2991  *    Function : BuildAndSendRicSubscriptionFailure
2992  *
2993  *    Functionality: Fill and Send RIC Subscription Failure to RIC
2994  *
2995  * @params[in] RIC Request ID
2996  *             RAN Function ID
2997  *             Cause of Failure
2998  * @return ROK     - success
2999  *         RFAILED - failure
3000  *
3001  * ****************************************************************/
3002 uint8_t BuildAndSendRicSubscriptionFailure(RicRequestId ricReqId, uint16_t ranFuncId, E2FailureCause failureCause)
3003 {
3004    uint8_t          ret = RFAILED;
3005    uint8_t          elementCnt = 0, elemIdx = 0;
3006    E2AP_PDU_t       *e2apMsg = NULLP;
3007    asn_enc_rval_t   encRetVal;        /* Encoder return value */
3008    RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP;
3009    RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
3010
3011    while(true)
3012    {
3013       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Failure\n");
3014
3015       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3016       if(e2apMsg == NULLP)
3017       {
3018          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
3019          break;
3020       }
3021
3022       e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome;
3023       DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
3024       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
3025       {
3026          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
3027          break;
3028       }
3029       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
3030       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
3031       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure;
3032
3033       ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
3034
3035       elementCnt = 3;
3036       ricSubscriptionFailure->protocolIEs.list.count = elementCnt;
3037       ricSubscriptionFailure->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionFailure_IEs_t *);
3038       DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size);
3039       if(!ricSubscriptionFailure->protocolIEs.list.array)
3040       {
3041          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
3042          break;
3043       }
3044
3045       for(elemIdx = 0; elemIdx < elementCnt; elemIdx++)
3046       {
3047          DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t));
3048          if(!ricSubscriptionFailure->protocolIEs.list.array[elemIdx])
3049          {
3050             DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d] for IE at index [%d]", \
3051                __func__, __LINE__, elemIdx);
3052             break;
3053          }
3054       }
3055       if(elemIdx < elementCnt)
3056          break;
3057
3058       elemIdx = 0;
3059
3060       /* RIC Request ID */
3061       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
3062       ricSubsFailIe->id = ProtocolIE_IDE2_id_RICrequestID;
3063       ricSubsFailIe->criticality = CriticalityE2_reject;
3064       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RICrequestID;
3065       ricSubsFailIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
3066       ricSubsFailIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
3067
3068       /* RAN Function ID */
3069       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
3070       ricSubsFailIe->id = ProtocolIE_IDE2_id_RANfunctionID;
3071       ricSubsFailIe->criticality = CriticalityE2_reject;
3072       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RANfunctionID;
3073       ricSubsFailIe->value.choice.RANfunctionID = ranFuncId;
3074
3075       /* Cause */
3076       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
3077       ricSubsFailIe->id = ProtocolIE_IDE2_id_CauseE2;
3078       ricSubsFailIe->criticality = CriticalityE2_reject;
3079       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_CauseE2;
3080       fillE2Cause(&ricSubsFailIe->value.choice.CauseE2, failureCause);
3081
3082       /* Prints the Msg formed */
3083       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3084       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3085       encBufSize = 0;
3086       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3087       if(encRetVal.encoded == ENCODE_FAIL)
3088       {
3089          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Failure Message (at %s)\n",\
3090                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3091          break;
3092       }
3093       else
3094       {
3095          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Failure Message \n");
3096 #ifdef DEBUG_ASN_PRINT
3097          for(int i=0; i< encBufSize; i++)
3098          {
3099             printf("%x",encBuf[i]);
3100          }
3101 #endif
3102       }
3103
3104       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
3105       {
3106          DU_LOG("\nINFO   -->  E2AP : Sending RIC Subscription Failure");
3107
3108       }
3109       ret = ROK;
3110       break;
3111    }
3112    FreeRicSubscriptionFailure(e2apMsg);
3113    return ret;
3114 }
3115
3116 /*******************************************************************
3117  *
3118  * @brief Free the RicIndication Message
3119  *
3120  * @details
3121  *
3122  *    Function : FreeRicIndication
3123  *
3124  * Functionality: Free the RicIndication Message
3125  *
3126  * @return void
3127  *         
3128  *
3129  ******************************************************************/
3130 void FreeRicIndication(E2AP_PDU_t  *e2apMsg) 
3131 {
3132    uint8_t idx = 0;
3133    RICindication_t *ricIndicationMsg= NULLP;
3134
3135    if(e2apMsg != NULLP)
3136    {
3137       if(e2apMsg->choice.initiatingMessage != NULLP)
3138       {
3139          ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
3140          if(ricIndicationMsg!= NULLP)
3141          {
3142             if(ricIndicationMsg->protocolIEs.list.array != NULLP)
3143             {
3144                for(idx=0; idx<ricIndicationMsg->protocolIEs.list.count; idx++)
3145                {
3146                   if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP)
3147                   {
3148                      switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
3149                      {
3150                         case ProtocolIE_IDE2_id_RICrequestID:
3151                         case ProtocolIE_IDE2_id_RANfunctionID:
3152                         case ProtocolIE_IDE2_id_RICactionID:
3153                         case ProtocolIE_IDE2_id_RICindicationType:
3154                            break;
3155
3156                         case ProtocolIE_IDE2_id_RICindicationHeader:
3157                            {
3158                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\
3159                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
3160                               break;
3161                            }
3162                         case ProtocolIE_IDE2_id_RICindicationMessage:
3163                            {
3164                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\
3165                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
3166                               break;
3167                            }
3168                         default:
3169                            break;
3170                      }
3171                      DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t));
3172                   }
3173                }
3174                DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size);
3175             }
3176          }
3177          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3178       }
3179       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3180    }
3181 }
3182
3183 /*******************************************************************
3184  *
3185  * @brief Free measurement record
3186  *
3187  * @details
3188  *
3189  *    Function : freeMeasRecord
3190  *
3191  * Functionality: Free all measurement recorded for a measurement
3192  *    within an action in a RIC subscription
3193  *
3194  * @param  Measurement data to be freed
3195  * @return void
3196  *
3197  ******************************************************************/
3198 void freeMeasData(MeasurementData_t *measData)
3199 {
3200    uint8_t measIdx = 0, measRecIdx = 0;
3201    MeasurementRecord_t *measRecord = NULLP;
3202
3203    if(measData->list.array)
3204    {
3205       for(measIdx = 0; measIdx < measData->list.count; measIdx++)
3206       {
3207          if(measData->list.array[measIdx])
3208          {
3209             measRecord = &measData->list.array[measIdx]->measRecord;
3210             if(measRecord->list.array)
3211             {
3212                for(measRecIdx = 0; measRecIdx < measRecord->list.count; measRecIdx++)
3213                {
3214                   DU_FREE(measRecord->list.array[measRecIdx], sizeof(MeasurementRecordItem_t));
3215                }
3216                DU_FREE(measRecord->list.array, measRecord->list.size);
3217             }
3218             DU_FREE(measData->list.array[measIdx], sizeof(MeasurementDataItem_t));
3219          }
3220       }
3221       DU_FREE(measData->list.array, measData->list.size);
3222    }
3223 }
3224
3225 /*******************************************************************
3226  *
3227  * @brief Fill measurement info list
3228  *
3229  * @details
3230  *
3231  *    Function : freeMeasInfoList
3232  *
3233  * Functionality: Fills all measurement info within an action 
3234  *    in a RIC subscription
3235  *
3236  * @param  Measurement Info list to be freed
3237  * @return void
3238  *
3239  ******************************************************************/
3240 void freeMeasInfoList(MeasurementInfoList_t *measInfoList)
3241 {
3242    uint8_t measInfoIdx = 0;
3243
3244    if(measInfoList->list.array)
3245    {
3246       for(measInfoIdx = 0; measInfoIdx < measInfoList->list.count; measInfoIdx++)
3247       {
3248          if(measInfoList->list.array[measInfoIdx])
3249          {
3250             DU_FREE(measInfoList->list.array[measInfoIdx]->measType.choice.measName.buf, \
3251                   measInfoList->list.array[measInfoIdx]->measType.choice.measName.size);
3252
3253             DU_FREE(measInfoList->list.array[measInfoIdx], measInfoList->list.size);
3254          }
3255       }
3256       DU_FREE(measInfoList->list.array, measInfoList->list.size);
3257    }
3258 }
3259
3260 /*******************************************************************
3261  *
3262  * @brief Free E2SM-KPM Indication Message
3263  *
3264  * @details
3265  *
3266  *    Function : FreeE2smKpmIndicationMessage
3267  *
3268  * Functionality: Free E2SM-KPM Indication Message
3269  *
3270  * @param  E2SM-KPM Indication message to be freed
3271  * @return void
3272  *
3273  ******************************************************************/
3274 void FreeE2smKpmIndicationMessage(E2SM_KPM_IndicationMessage_t *e2smKpmIndMsg)
3275 {
3276    E2SM_KPM_IndicationMessage_Format1_t *format1Msg = NULLP;
3277
3278    switch(e2smKpmIndMsg->indicationMessage_formats.present)
3279    {
3280       case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format1:
3281          {
3282             if(e2smKpmIndMsg->indicationMessage_formats.choice.indicationMessage_Format1)
3283             {
3284                format1Msg = e2smKpmIndMsg->indicationMessage_formats.choice.indicationMessage_Format1;
3285                
3286                /* Measurement Data */
3287                freeMeasData(&format1Msg->measData);
3288
3289                /* Measurement Info List */
3290                if(format1Msg->measInfoList)
3291                {
3292                   freeMeasInfoList(format1Msg->measInfoList);
3293                   DU_FREE(format1Msg->measInfoList, sizeof(MeasurementInfoList_t));
3294                }
3295
3296                /* Granularity Period */
3297                DU_FREE(format1Msg->granulPeriod, sizeof(GranularityPeriod_t));
3298
3299                DU_FREE(format1Msg, sizeof(E2SM_KPM_IndicationMessage_Format1_t));
3300             }
3301             break;
3302          }
3303
3304       case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_NOTHING:
3305       case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format2:
3306       default:
3307          break;
3308    }
3309 }
3310
3311 /*******************************************************************
3312  *
3313  * @brief Fill measurement record
3314  *
3315  * @details
3316  *
3317  *    Function : fillMeasRecord
3318  *
3319  * Functionality: Fills all measurement value for a measurement
3320  *    within an action in a RIC subscription
3321  *
3322  * @param  Measurement record to be filled
3323  *         Measurement database with measurement records
3324  * @return ROK     - success
3325  *         RFAILED - failure
3326  *
3327  ******************************************************************/
3328 uint8_t fillMeasRecord(MeasurementRecord_t *measRecord, MeasurementInfo *measInfoDb)
3329 {
3330    uint8_t measRecIdx = 0;
3331    CmLList *measValNode = NULLP;
3332    double  measVal = 0;
3333
3334    measRecord->list.count = measInfoDb->measuredValue.count;
3335    measRecord->list.size = measRecord->list.count * sizeof(MeasurementRecordItem_t *);
3336
3337    DU_ALLOC(measRecord->list.array, measRecord->list.size);
3338    if(!measRecord->list.array)
3339    {
3340       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3341       return RFAILED;
3342    }
3343
3344    for(measRecIdx = 0; measRecIdx < measRecord->list.count; measRecIdx++)
3345    {
3346       DU_ALLOC(measRecord->list.array[measRecIdx], sizeof(MeasurementRecordItem_t));
3347       if(!measRecord->list.array[measRecIdx])
3348       {
3349          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3350          return RFAILED;
3351       }
3352    }
3353
3354    measRecIdx = 0;
3355    CM_LLIST_FIRST_NODE(&measInfoDb->measuredValue, measValNode);
3356    while(measValNode)
3357    {
3358      measVal = *(double *)measValNode->node;
3359      if(measVal == (int)measVal)
3360      {
3361         measRecord->list.array[measRecIdx]->present = MeasurementRecordItem_PR_integer;
3362         measRecord->list.array[measRecIdx]->choice.integer = (int)measVal;
3363      }
3364      else
3365      {
3366          measRecord->list.array[measRecIdx]->present = MeasurementRecordItem_PR_real;
3367          measRecord->list.array[measRecIdx]->choice.real = measVal;
3368      }
3369      measRecIdx++;
3370      measValNode= measValNode->next;  
3371      /* Once the measurement record is added to the message, delete it from DB */
3372      measVal = 0;
3373    }
3374    deleteMeasuredValueList(&measInfoDb->measuredValue);
3375    return ROK;
3376 }
3377
3378 /*******************************************************************
3379  *
3380  * @brief Fills measuerement data
3381  *
3382  * @details
3383  *
3384  *    Function : fillMeasData
3385  *
3386  * Functionality: Fill all measurement recorded for all measurements
3387  *    in an action in a RIC subscription
3388  *
3389  * @param  Measurement data to be filled
3390  *         Measurement info list from an action DB
3391  * @return ROK     - success
3392  *         RFAILED - failure
3393  *
3394  ******************************************************************/
3395 uint8_t fillMeasData(MeasurementData_t *measData, CmLListCp *measInfoListDb)
3396 {
3397   uint8_t measIdx = 0;
3398   CmLList *measInfoNode = NULLP;
3399   MeasurementInfo *measInfoDb = NULLP;
3400   MeasurementRecord_t *measRecord = NULLP;
3401
3402   measData->list.count = measInfoListDb->count;
3403   measData->list.size = measData->list.count * sizeof(MeasurementDataItem_t *);
3404
3405   DU_ALLOC(measData->list.array, measData->list.size);
3406   if(!measData->list.array)
3407   {
3408      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3409      return RFAILED;
3410   }
3411
3412   measIdx = 0;
3413   CM_LLIST_FIRST_NODE(measInfoListDb, measInfoNode);
3414   while(measInfoNode)
3415   {
3416      measInfoDb = (MeasurementInfo *)measInfoNode->node;
3417      if(measInfoDb)
3418      {
3419         DU_ALLOC(measData->list.array[measIdx], sizeof(MeasurementDataItem_t));
3420         if(!measData->list.array[measIdx])
3421         {
3422            DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3423            return RFAILED;
3424         }
3425
3426         measRecord = &measData->list.array[measIdx]->measRecord;
3427         if(fillMeasRecord(measRecord, measInfoDb) != ROK)
3428         {
3429            DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement record");
3430            return RFAILED;
3431         }
3432         measIdx++;
3433      }
3434      measInfoNode = measInfoNode->next;
3435   }
3436
3437   return ROK;
3438 }
3439
3440 /*******************************************************************
3441  *
3442  * @brief Fill all measurement info
3443  *
3444  * @details
3445  *
3446  *    Function : fillMeasInfoList
3447  *
3448  * Functionality: Fills all measurement info belonging to an action
3449  *  in a RIC subscription
3450  *
3451  * @param   Measurement Info list to be filled
3452  *          Measurement Info list from E2AP DB
3453  * @return ROK     - success
3454  *         RFAILED - failure
3455  *
3456  ******************************************************************/
3457 uint8_t fillMeasInfoList(MeasurementInfoList_t *measInfoList, CmLListCp *measInfoListDb)
3458 {
3459    uint8_t measInfoIdx = 0;
3460    CmLList *measInfoNode = NULLP;
3461    MeasurementInfo *measInfoDb = NULLP;
3462    MeasurementInfoItem_t *measInfoItem = NULLP;
3463
3464    measInfoList->list.count = measInfoListDb->count;
3465    measInfoList->list.size = measInfoList->list.count * sizeof(MeasurementInfoItem_t *);
3466
3467    DU_ALLOC(measInfoList->list.array, measInfoList->list.size);
3468    if(!measInfoList->list.array)
3469    {
3470       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3471       return RFAILED;
3472    }
3473
3474    measInfoIdx = 0;
3475    CM_LLIST_FIRST_NODE(measInfoListDb, measInfoNode);
3476    while(measInfoNode)
3477    {
3478       DU_ALLOC(measInfoList->list.array[measInfoIdx], sizeof(MeasurementInfoItem_t));
3479       if(!measInfoList->list.array[measInfoIdx])
3480       {
3481          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3482          return RFAILED;
3483       }
3484
3485       measInfoItem = measInfoList->list.array[measInfoIdx];
3486       measInfoDb = (MeasurementInfo *)measInfoNode->node;
3487       if(measInfoDb)
3488       {
3489          /* Measurement Type */
3490          measInfoItem->measType.present = MeasurementType_PR_measName;
3491          measInfoItem->measType.choice.measName.size = strlen(measInfoDb->measurementTypeName);
3492
3493          DU_ALLOC(measInfoItem->measType.choice.measName.buf, measInfoItem->measType.choice.measName.size);
3494          if(!measInfoItem->measType.choice.measName.buf)
3495          {
3496             DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3497             return RFAILED;
3498          }
3499
3500          memcpy(measInfoItem->measType.choice.measName.buf, measInfoDb->measurementTypeName,\
3501             measInfoItem->measType.choice.measName.size);
3502
3503          measInfoIdx++;
3504       }
3505       measInfoNode = measInfoNode->next;
3506       measInfoDb = NULLP;
3507    }
3508
3509    return ROK;
3510 }
3511
3512  /*******************************************************************
3513  *
3514  * @brief Fill E2SM-KPM Indication Message Format 1
3515  *
3516  * @details
3517  *
3518  *    Function : fillE2smKpmIndMsgFormat1
3519  *
3520  * Functionality: Fill E2SM-KPM Indication Message Format 1
3521  *
3522  * @param  Format 1 Message to be filled
3523  *         Action Definition format 1 from E2AP DB
3524  * @return ROK     - success
3525  *         RFAILED - failure
3526  *
3527  ******************************************************************/
3528 uint8_t fillE2smKpmIndMsgFormat1(E2SM_KPM_IndicationMessage_Format1_t *format1Msg, ActionDefFormat1 *format1)
3529 {
3530   /* Measurement Data */
3531   if(fillMeasData(&format1Msg->measData, &format1->measurementInfoList) != ROK)
3532   {
3533      DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement data");
3534      return RFAILED;
3535   }
3536
3537   /* Measurement Information */
3538   DU_ALLOC(format1Msg->measInfoList, sizeof(MeasurementInfoList_t));
3539   if(!format1Msg->measInfoList)
3540   {
3541      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3542      return RFAILED;
3543   }
3544
3545   if(fillMeasInfoList(format1Msg->measInfoList, &format1->measurementInfoList) != ROK)
3546   {
3547      DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement information list");
3548      return RFAILED;
3549   }
3550
3551   /* Granularity Period */
3552   DU_ALLOC(format1Msg->granulPeriod, sizeof(GranularityPeriod_t));
3553   if(!format1Msg->granulPeriod)
3554   {
3555      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3556      return RFAILED;
3557   }
3558   *(format1Msg->granulPeriod) = format1->granularityPeriod;
3559
3560   return ROK;
3561 }
3562
3563 /*******************************************************************
3564  *
3565  * @brief Fill RIC Indication Message buffer
3566  *
3567  * @details
3568  *
3569  *    Function : fillRicIndMsgBuf
3570  *
3571  * Functionality: Fill E2SM-KPM Indication Message
3572  *    Encode this message and copy to RIC Indication Message buffer
3573  * 
3574  * @param  RIC Indication Message buffer to be filled
3575  *         Source action info from E2AP DB
3576  * @return ROK     - success
3577  *         RFAILED - failure
3578  *
3579  ******************************************************************/
3580 uint8_t fillRicIndMsgBuf(RICindicationMessage_t *ricIndMsgBuf, ActionInfo *actionInfo)
3581 {
3582    uint8_t ret = RFAILED;
3583    bool failedInFormat = false;
3584    E2SM_KPM_IndicationMessage_t e2smKpmIndMsg;
3585    asn_enc_rval_t   encRetVal;        /* Encoder return value */
3586
3587    memset(&e2smKpmIndMsg, 0, sizeof(E2SM_KPM_IndicationMessage_t));
3588
3589    while(true)
3590    {
3591       /* E2SM-KPM Indication message format type */
3592       e2smKpmIndMsg.indicationMessage_formats.present = actionInfo->definition.formatType;
3593       switch(e2smKpmIndMsg.indicationMessage_formats.present)
3594       {
3595          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format1:
3596             {
3597                /* E2SM-KPM Indication message format 1 */
3598                DU_ALLOC(e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1, \
3599                      sizeof(E2SM_KPM_IndicationMessage_Format1_t));
3600                if(!e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1)
3601                {
3602                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3603                   failedInFormat = true;
3604                   break;
3605                }
3606
3607                if(fillE2smKpmIndMsgFormat1(e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1, \
3608                   &actionInfo->definition.choice.format1) != ROK)
3609                {
3610                   DU_LOG("\nERROR  -->  E2AP : Failed to fill E2SM-KPM Indication message format 1");
3611                   failedInFormat = true;
3612                   break;
3613                }
3614                break;
3615             }
3616
3617          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_NOTHING:
3618          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format2:
3619          default:
3620             {
3621                DU_LOG("\nERROR  -->  E2AP : fillRicIndMsgBuf: Only Format 1 supported");
3622                failedInFormat = true;
3623                break;
3624             }
3625       }
3626
3627       if(failedInFormat)
3628          break;
3629
3630       /* Encode E2SM-KPM Indication Message */
3631       xer_fprint(stdout, &asn_DEF_E2SM_KPM_IndicationMessage, &e2smKpmIndMsg);
3632       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3633       encBufSize = 0;
3634       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_IndicationMessage, 0, &e2smKpmIndMsg, PrepFinalEncBuf, encBuf);
3635       if(encRetVal.encoded == ENCODE_FAIL)
3636       {
3637          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM Indication Message (at %s)\n",\
3638                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3639          break;
3640       }
3641       else
3642       {
3643          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SM-KPM Indication Message \n");
3644 #ifdef DEBUG_ASN_PRINT
3645          for(int i=0; i< encBufSize; i++)
3646          {
3647             printf("%x",encBuf[i]);
3648          } 
3649 #endif
3650       }
3651
3652       /* Copy encoded string to RIC Indication Message buffer */
3653       ricIndMsgBuf->size = encBufSize;
3654       DU_ALLOC(ricIndMsgBuf->buf, ricIndMsgBuf->size);
3655       if(!ricIndMsgBuf->buf)
3656       {
3657          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3658          break;
3659       }
3660       memset(ricIndMsgBuf->buf, 0, ricIndMsgBuf->size);
3661       memcpy(ricIndMsgBuf->buf, encBuf, encBufSize);
3662
3663       ret = ROK;
3664       break;
3665    }
3666
3667    /* Free E2SM-KPM Indication Message */
3668    FreeE2smKpmIndicationMessage(&e2smKpmIndMsg);
3669
3670    return ret;
3671 }
3672
3673 /*******************************************************************
3674  *
3675  * @brief Free E2SM-KPM Indication Header
3676  *
3677  * @details
3678  *
3679  *    Function : FreeE2smKpmIndicationHeader
3680  *
3681  * Functionality: Free E2SM-KPM Indication Header
3682  * 
3683  * @param  E2SM-KPM Indication Header to be free
3684  * @return void
3685  *
3686  ******************************************************************/
3687 void FreeE2smKpmIndicationHeader(E2SM_KPM_IndicationHeader_t *e2smKpmIndHdr)
3688 {
3689    E2SM_KPM_IndicationHeader_Format1_t *format1 = NULLP;
3690
3691    if(e2smKpmIndHdr)
3692    {
3693       switch(e2smKpmIndHdr->indicationHeader_formats.present)
3694       {
3695          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_indicationHeader_Format1:
3696             {
3697                if(e2smKpmIndHdr->indicationHeader_formats.choice.indicationHeader_Format1)
3698                {
3699                   format1 = e2smKpmIndHdr->indicationHeader_formats.choice.indicationHeader_Format1;
3700
3701                   DU_FREE(format1->colletStartTime.buf, format1->colletStartTime.size);
3702                   DU_FREE(format1, sizeof(E2SM_KPM_IndicationHeader_Format1_t));
3703                }
3704                break;
3705             }
3706          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_NOTHING:
3707          default:
3708             break;
3709       }
3710    }
3711 }
3712
3713 /*******************************************************************
3714  *
3715  * @brief Fill RIC Indication Header buffer
3716  *
3717  * @details
3718  *
3719  *    Function : fillRicIndHeader
3720  *
3721  * Functionality: Fill E2SM-KPM Indication Header
3722  *    Encode this message and copy to RIC Indication Header buffer
3723  * 
3724  * @param  RIC Indication Header buffer to be filled
3725  *         Source RIC subscription info from E2AP DB
3726  * @return ROK     - success
3727  *         RFAILED - failure
3728  *
3729  ******************************************************************/
3730 uint8_t fillRicIndHeader(RICindicationHeader_t *ricIndHdr, RicSubscription *ricSubsInfo)
3731 {
3732    uint8_t ret = RFAILED;
3733    uint8_t secBufIdx = 0, milliSecBufIdx = 0;
3734    int8_t byteIdx = 0;
3735    bool formatFailure = false;
3736    RanFunction *ranFunc = NULLP;
3737    ReportStartTime *startTime = NULLP;
3738    E2SM_KPM_IndicationHeader_t e2smKpmIndHdr;
3739    E2SM_KPM_IndicationHeader_Format1_t *format1 = NULLP;
3740    asn_enc_rval_t   encRetVal;        /* Encoder return value */
3741
3742    while(true)
3743    {
3744       ranFunc = fetchRanFuncFromRanFuncId(ricSubsInfo->ranFuncId);
3745       if(ranFunc == NULLP)
3746       {
3747          DU_LOG("\nERROR  -->  E2AP : RAN Function ID [%d] not found", ricSubsInfo->ranFuncId);
3748          break;
3749       }
3750
3751       memset(&e2smKpmIndHdr, 0, sizeof(E2SM_KPM_IndicationHeader_t));
3752
3753       e2smKpmIndHdr.indicationHeader_formats.present = ranFunc->ricIndicationHeaderFormat;
3754       switch(e2smKpmIndHdr.indicationHeader_formats.present)
3755       {
3756          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_indicationHeader_Format1:
3757             {
3758                DU_ALLOC(e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1, \
3759                      sizeof(E2SM_KPM_IndicationHeader_Format1_t));
3760                if(!e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1)
3761                {
3762                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3763                   formatFailure = true;
3764                   break;
3765                }
3766                format1 = e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1;
3767
3768                /* Fetch reporting period start time from DB */
3769                switch(ricSubsInfo->eventTriggerDefinition.formatType)
3770                {
3771                   case 1:
3772                   {
3773                      startTime = &ricSubsInfo->eventTriggerDefinition.choice.format1.startTime;
3774                   }
3775                }
3776
3777                format1->colletStartTime.size = 8 * sizeof(uint8_t);
3778                DU_ALLOC(format1->colletStartTime.buf, format1->colletStartTime.size);
3779                if(!format1->colletStartTime.buf)
3780                {
3781                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3782                   formatFailure = true;
3783                   break;
3784                }
3785
3786                /* As per O-RAN.WG3.E2SM-KPM-R003-v03.00, section 8.3.12 and
3787                 * RFC 5905, section 6 :
3788                 * Time stamp has a 64-bit format where first 32-bit is seconds
3789                 * and next 32-bit is fraction in picosecond-level.
3790                 * This fraction has been rounded in microseconds.
3791                 *
3792                 * Hence,
3793                 * Storing 32-bit seconds at MSB 0-3 and
3794                 * 32-bit milliseconds at next 4 bytes i.e. bytes 4-7
3795                 */
3796                secBufIdx = 0;
3797                milliSecBufIdx = 4;
3798                for(byteIdx = 3; byteIdx >= 0; byteIdx--)
3799                {
3800                   format1->colletStartTime.buf[secBufIdx++] = startTime->timeInSec >> (8*byteIdx);
3801                   format1->colletStartTime.buf[milliSecBufIdx++] = startTime->timeInMilliSec >> (8*byteIdx);
3802                }
3803                break;
3804             }
3805
3806          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_NOTHING:
3807          default:
3808          {
3809              DU_LOG("\nERROR  -->  E2AP : Only E2SM-KPM Indication Header Format 1 supported");
3810              formatFailure = true;
3811              break;
3812          }
3813       }
3814
3815       if(formatFailure)
3816          break;
3817
3818       /* Encode E2SM-KPM Indication Header */
3819       xer_fprint(stdout, &asn_DEF_E2SM_KPM_IndicationHeader, &e2smKpmIndHdr);
3820       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3821       encBufSize = 0;
3822       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_IndicationHeader, 0, &e2smKpmIndHdr, PrepFinalEncBuf, encBuf);
3823       if(encRetVal.encoded == ENCODE_FAIL)
3824       {
3825          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM Indication Header (at %s)\n",\
3826                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3827          break;
3828       }
3829       else
3830       {
3831          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SM-KPM Indication Header \n");
3832 #ifdef DEBUG_ASN_PRINT
3833          for(int i=0; i< encBufSize; i++)
3834          {
3835             printf("%x",encBuf[i]);
3836          } 
3837 #endif
3838       }
3839
3840       /* Copy encoded string to RIC Indication Header buffer */
3841       ricIndHdr->size = encBufSize;
3842       DU_ALLOC(ricIndHdr->buf, ricIndHdr->size);
3843       if(!ricIndHdr->buf)
3844       {
3845          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3846          break;
3847       }
3848       memset(ricIndHdr->buf, 0, ricIndHdr->size);
3849       memcpy(ricIndHdr->buf, encBuf, encBufSize);
3850       ret = ROK;
3851       break;
3852    }
3853
3854    /* Free E2SM-KPM Indication Header */
3855    FreeE2smKpmIndicationHeader(&e2smKpmIndHdr);
3856
3857    return ret;
3858 }
3859
3860 /*******************************************************************
3861  *
3862  * brief Fill the RIC Indication Message
3863  *
3864  * @details
3865  *
3866  *    Function : fillRicIndication
3867  *
3868  * Functionality: Fills the RIC Indication Message
3869  *
3870  * @param  RIC Indication Message to be filled
3871  *         RIC Subscription DB
3872  *         Action DB
3873  * @return ROK     - success
3874  *         RFAILED - failure
3875  *
3876  ******************************************************************/
3877 uint8_t fillRicIndication(RICindication_t *ricIndicationMsg, RicSubscription *ricSubscriptionInfo, ActionInfo *actionInfo)
3878 {
3879    uint8_t elementCnt = 0, idx = 0;
3880    uint8_t ret = ROK;
3881
3882    elementCnt = 6;
3883
3884    ricIndicationMsg->protocolIEs.list.count = elementCnt;
3885    ricIndicationMsg->protocolIEs.list.size  = elementCnt * sizeof(RICindication_IEs_t *);
3886
3887    /* Initialize the Ric Indication members */
3888    DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, ricIndicationMsg->protocolIEs.list.size);
3889    if(ricIndicationMsg->protocolIEs.list.array == NULLP)
3890    {
3891       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3892       return RFAILED;
3893    }
3894
3895    for(idx=0; idx<elementCnt; idx++)
3896    {
3897       DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx], sizeof(RICindication_IEs_t));
3898       if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
3899       {
3900          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3901          return RFAILED;
3902       }
3903    }
3904
3905    /* RIC Request ID */
3906    idx = 0;
3907    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
3908    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
3909    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICrequestID;
3910    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID = \
3911       ricSubscriptionInfo->requestId.requestorId;
3912    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID = \
3913       ricSubscriptionInfo->requestId.instanceId;
3914
3915    /* RAN Function ID */
3916    idx++;
3917    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
3918    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
3919    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RANfunctionID;
3920    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ricSubscriptionInfo->ranFuncId;
3921
3922    /* RIC Action ID */
3923    idx++;
3924    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
3925    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
3926    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICactionID;
3927    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = actionInfo->actionId;
3928
3929    /* RIC Indication Type */
3930    idx++;
3931    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
3932    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
3933    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationType;
3934    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = actionInfo->type;
3935
3936    /* RIC Indication Header */
3937    idx++;
3938    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
3939    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
3940    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationHeader;
3941    if(fillRicIndHeader(&ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader, \
3942       ricSubscriptionInfo) != ROK)
3943    {
3944       DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication header");
3945       return RFAILED;
3946    }
3947
3948    /* RIC Indication Message */
3949    idx++;
3950    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
3951    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
3952    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationMessage;
3953    if(fillRicIndMsgBuf(&ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage, \
3954       actionInfo) != ROK)
3955    {
3956       DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication Message");
3957       return RFAILED;
3958    }
3959
3960    return ret;
3961 }
3962
3963 /*******************************************************************
3964  *
3965  * @brief Builds and Send the RicIndication Message
3966  *
3967  * @details
3968  *
3969  *    Function : BuildAndSendRicIndication
3970  *
3971  * Functionality:Fills the RicIndication Message
3972  *
3973  * @return ROK     - success
3974  *         RFAILED - failure
3975  *
3976  ******************************************************************/
3977
3978 uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo, ActionInfo *actionInfo)
3979 {
3980    uint8_t          ret = RFAILED; 
3981    E2AP_PDU_t       *e2apMsg = NULLP;
3982    RICindication_t  *ricIndicationMsg = NULLP;
3983    asn_enc_rval_t   encRetVal;        /* Encoder return value */
3984
3985    while(true)
3986    {
3987       DU_LOG("\nINFO   -->  E2AP : Building RIC Indication Message\n");
3988
3989       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3990       if(e2apMsg == NULLP)
3991       {
3992          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
3993          break;
3994       }
3995
3996       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
3997       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3998       if(e2apMsg->choice.initiatingMessage == NULLP)
3999       {
4000          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4001          break;
4002       }
4003       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
4004       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4005       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication;
4006
4007       ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
4008
4009       if(fillRicIndication(ricIndicationMsg, ricSubscriptionInfo, actionInfo) != ROK)
4010       {
4011          DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication message");
4012          break;
4013       }
4014
4015       /* Prints the Msg formed */
4016       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4017       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4018       encBufSize = 0;
4019       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4020             encBuf);
4021       if(encRetVal.encoded == ENCODE_FAIL)
4022       {
4023          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Indication Message (at %s)\n",\
4024                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4025          break;
4026       }
4027       else
4028       {
4029          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Indication Message \n");
4030 #ifdef DEBUG_ASN_PRINT
4031          for(int i=0; i< encBufSize; i++)
4032          {
4033             printf("%x",encBuf[i]);
4034          } 
4035 #endif
4036       }
4037
4038       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
4039       {
4040          DU_LOG("\nINFO   -->  E2AP : Sending RIC Indication Message");      
4041
4042       }
4043       ret = ROK;
4044       break;
4045    }
4046    FreeRicIndication(e2apMsg);  
4047    return ret;
4048 }
4049
4050 /*******************************************************************
4051  *
4052  * @brief free e2 node component configuration req and rsp
4053  *
4054  * @details
4055  *
4056  *    Function : freeE2NodeComponentConfiguration 
4057  *
4058  *    Functionality:
4059  *       - free e2 node component configuration req and rsp
4060  *
4061  * @params[in] E2nodeComponentConfiguration_t *e2nodeComponentConfiguration
4062  * @return ROK     - success
4063  *         RFAILED - failure
4064  *
4065  * ****************************************************************/
4066
4067 void freeE2NodeComponentConfiguration(E2nodeComponentConfiguration_t *e2nodeComponentConfiguration)
4068 {
4069    /* Free E2 Node Component Request Part */
4070    DU_FREE(e2nodeComponentConfiguration->e2nodeComponentRequestPart.buf, e2nodeComponentConfiguration->e2nodeComponentRequestPart.size);
4071
4072    /* Free E2 Node Component Response Part */
4073    DU_FREE(e2nodeComponentConfiguration->e2nodeComponentResponsePart.buf, e2nodeComponentConfiguration->e2nodeComponentResponsePart.size);
4074                                  
4075 }
4076
4077 /*******************************************************************
4078  *
4079  * @brief free e2 node component component identifier
4080  *
4081  * @details
4082  *
4083  *    Function : freeE2NodeComponentIdentifier
4084  *
4085  *    Functionality:
4086  *       - free e2 node component component identifier
4087  *
4088  * @params[in] E2nodeComponentID_t  *componentID 
4089  * @return ROK     - success
4090  *         RFAILED - failure
4091  *
4092  * ****************************************************************/
4093
4094 void freeE2NodeComponentIdentifier(E2nodeComponentID_t *componentID)
4095 {
4096    if(componentID->choice.e2nodeComponentInterfaceTypeF1)
4097    {
4098       DU_FREE(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf, componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
4099       DU_FREE(componentID->choice.e2nodeComponentInterfaceTypeF1, sizeof(E2nodeComponentInterfaceF1_t));
4100    }
4101                                  
4102 }
4103
4104 /*******************************************************************
4105  *
4106  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
4107  *
4108  * @details
4109  *
4110  *    Function : FreeE2NodeConfigUpdate 
4111  *
4112  *    Functionality:
4113  *       - freeing the memory allocated for E2nodeConfigurationUpdate
4114  *
4115  * @params[in] E2AP_PDU_t *e2apMsg 
4116  * @return ROK     - success
4117  *         RFAILED - failure
4118  *
4119  * ****************************************************************/
4120
4121 void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg)
4122 {
4123    uint8_t arrIdx =0, e2NodeUpdateListIdx=0, e2NodeRemovalListIdx=0, e2NodeAddListIdx=0;
4124    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate =NULL;
4125    E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList  =NULL;
4126    E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItem =NULL;
4127    E2nodeComponentConfigRemoval_List_t *e2NodeRemovalList =NULL;
4128    E2nodeComponentConfigRemoval_ItemIEs_t *e2NodeRemovalItem =NULL;
4129    E2nodeComponentConfigAddition_List_t *e2NodeAddList =NULL;
4130    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem =NULL;
4131
4132    if(e2apMsg != NULLP)
4133    {
4134       if(e2apMsg->choice.initiatingMessage != NULLP)
4135       {
4136          e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
4137          if(e2NodeConfigUpdate->protocolIEs.list.array != NULLP)
4138          {
4139             for(arrIdx = 0; arrIdx < e2NodeConfigUpdate->protocolIEs.list.count; arrIdx++)
4140             {
4141                if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx])
4142                {
4143
4144                   switch(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id)
4145                   {
4146                      case ProtocolIE_IDE2_id_TransactionID:
4147                         break;
4148
4149                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
4150                      {
4151                          e2NodeAddList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;
4152                          if(e2NodeAddList->list.array)
4153                          {
4154                              for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
4155                              {
4156                                 e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
4157                                  
4158                                 freeE2NodeComponentConfiguration(&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration);
4159                                 freeE2NodeComponentIdentifier(&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID);
4160                                 DU_FREE(e2NodeAddItem, sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
4161                              }
4162                              DU_FREE(e2NodeAddList->list.array, e2NodeAddList->list.size);
4163                          }
4164                          break;
4165                      }
4166                      case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate:
4167                         {
4168                            e2NodeUpdateList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdate_List;
4169                            if(e2NodeUpdateList->list.array)
4170                            {
4171                               for(e2NodeUpdateListIdx = 0; e2NodeUpdateListIdx< e2NodeUpdateList->list.count; e2NodeUpdateListIdx++)
4172                               {
4173                                  e2NodeUpdateItem = (E2nodeComponentConfigUpdate_ItemIEs_t *) e2NodeUpdateList->list.array[e2NodeUpdateListIdx];
4174                                  
4175                                  freeE2NodeComponentConfiguration(&e2NodeUpdateItem->value.choice.E2nodeComponentConfigUpdate_Item.e2nodeComponentConfiguration);
4176                                  freeE2NodeComponentIdentifier(&e2NodeUpdateItem->value.choice.E2nodeComponentConfigUpdate_Item.e2nodeComponentID);
4177                                  DU_FREE(e2NodeUpdateItem, sizeof(E2nodeComponentConfigUpdate_ItemIEs_t));
4178                               }
4179                               DU_FREE(e2NodeUpdateList->list.array, e2NodeUpdateList->list.size);
4180                            }
4181                            break;
4182                         }
4183                      case ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval:
4184                         {
4185                            e2NodeRemovalList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemoval_List;
4186                            if(e2NodeRemovalList->list.array)
4187                            {
4188                               for(e2NodeRemovalListIdx = 0; e2NodeRemovalListIdx< e2NodeRemovalList->list.count; e2NodeRemovalListIdx++)
4189                               {
4190                                  e2NodeRemovalItem = (E2nodeComponentConfigRemoval_ItemIEs_t *) e2NodeRemovalList->list.array[e2NodeRemovalListIdx];
4191
4192                                  freeE2NodeComponentIdentifier(&e2NodeRemovalItem->value.choice.E2nodeComponentConfigRemoval_Item.e2nodeComponentID);
4193                                  DU_FREE(e2NodeRemovalItem, sizeof(E2nodeComponentConfigRemoval_ItemIEs_t));
4194                               }
4195                               DU_FREE(e2NodeRemovalList->list.array, e2NodeRemovalList->list.size);
4196                            }
4197                            break;
4198                         }
4199                            
4200                      default:
4201                         break;
4202                   }
4203                   DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
4204                }
4205             }
4206             DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
4207          }
4208          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4209       }
4210       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4211    }
4212 }
4213
4214 /*******************************************************************
4215  *
4216  * @brief Buld and send the E2 node config update msg 
4217  *
4218  * @details
4219  *
4220  *    Function : BuildAndSendE2NodeConfigUpdate
4221  *
4222  *    Functionality:
4223  *         - Buld and send the E2 node config update msg
4224  *
4225  * @params[in] 
4226  * @return ROK     - success
4227  *         RFAILED - failure
4228  *
4229  * ****************************************************************/
4230
4231 uint8_t BuildAndSendE2NodeConfigUpdate(E2NodeConfigList *e2NodeList)
4232 {
4233    uint8_t ret = RFAILED;
4234    uint8_t arrIdx = 0,elementCnt = 0, transId=0;
4235    E2AP_PDU_t  *e2apMsg = NULLP;
4236    asn_enc_rval_t     encRetVal;       /* Encoder return value */
4237    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate = NULLP;
4238
4239    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update\n");
4240    do
4241    {
4242       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4243       if(e2apMsg == NULLP)
4244       {
4245          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4246          break;
4247       }
4248
4249       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4250       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4251       if(e2apMsg->choice.initiatingMessage == NULLP)
4252       {
4253          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4254          break;
4255       }
4256       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4257       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
4258       e2apMsg->choice.initiatingMessage->value.present = \
4259       InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate;
4260       e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
4261       
4262       elementCnt =1;
4263       if(e2NodeList->addE2NodeCount)
4264          elementCnt++;
4265       if(e2NodeList->updateE2NodeCount)
4266          elementCnt++;
4267       if(e2NodeList->removeE2NodeCount)
4268          elementCnt++;
4269
4270       e2NodeConfigUpdate->protocolIEs.list.count = elementCnt;
4271       e2NodeConfigUpdate->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdate_IEs_t*);
4272       DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
4273       if(e2NodeConfigUpdate->protocolIEs.list.array == NULLP)
4274       {
4275          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
4276          break;
4277       }
4278       
4279       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
4280       {
4281          DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
4282          if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx] == NULLP)
4283          {
4284             
4285             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
4286             break;
4287          }
4288       }
4289       
4290       if(arrIdx<elementCnt)
4291          break;
4292
4293       arrIdx = 0;
4294       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4295       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4296       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_TransactionID;
4297       transId = assignTransactionId();
4298       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
4299
4300       if(e2NodeList->addE2NodeCount)
4301       {
4302          arrIdx++;
4303          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition;
4304          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4305          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigAddition_List;
4306          if(BuildE2NodeConfigAddList(&(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List),\
4307          ProcedureCodeE2_id_E2nodeConfigurationUpdate, e2NodeList->addE2NodeCount, e2NodeList->addE2Node)!=ROK)
4308          {
4309             DU_LOG("\nERROR  -->  E2AP : Failed to create E2 Node config list");
4310             break;
4311          }
4312       }
4313       
4314       if(e2NodeList->updateE2NodeCount)
4315       {
4316          arrIdx++;
4317          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate;
4318          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4319          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigUpdate_List;
4320          if(BuildE2NodeConfigUpdateList(&e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdate_List,\
4321          e2NodeList->updateE2NodeCount, e2NodeList->updateE2Node) != ROK)
4322          {
4323
4324             DU_LOG("\nERROR  -->  E2AP : Failed to update the E2 node configuration");
4325             break;
4326          }
4327       }
4328       
4329       if(e2NodeList->removeE2NodeCount)
4330       {
4331          arrIdx++;
4332          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval;
4333          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4334          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigRemoval_List;
4335          if(BuildE2NodeConfigRemoveList(&e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemoval_List,\
4336          e2NodeList->removeE2NodeCount, e2NodeList->removeE2Node) != ROK)
4337          {
4338
4339             DU_LOG("\nERROR  -->  E2AP : Failed to remove the E2 node configuration");
4340             break;
4341          }
4342       }
4343
4344       /* Prints the Msg formed */
4345       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4346
4347       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4348       encBufSize = 0;
4349       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
4350       if(encRetVal.encoded == ENCODE_FAIL)
4351       {
4352          DU_LOG("\nERROR  -->  E2AP : Could not encode E2nodeConfigurationUpdate structure (at %s)\n",\
4353                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4354          break;
4355       }
4356       else
4357       {
4358          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2nodeConfigurationUpdate\n");
4359 #ifdef DEBUG_ASN_PRINT
4360          for(int i=0; i< encBufSize; i++)
4361          {
4362             printf("%x",encBuf[i]);
4363          }
4364 #endif
4365       }
4366       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize))
4367       {
4368          DU_LOG("\nERROR  -->  E2AP : Sending E2 node config update failed");
4369          break;
4370       }
4371
4372       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
4373       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
4374       memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.e2NodeConfigUpdate.configList, e2NodeList, sizeof(E2NodeConfigList));
4375       ret = ROK;
4376       break;
4377    }while(true);
4378    
4379    FreeE2NodeConfigUpdate(e2apMsg);
4380    return ret;
4381 }
4382
4383 /*******************************************************************
4384  *
4385  * @brief Deallocate the memory allocated for E2ResetRequest msg
4386  *
4387  * @details
4388  *
4389  *    Function : FreeE2ResetRequest
4390  *
4391  *    Functionality:
4392  *       - freeing the memory allocated for E2ResetRequest
4393  *
4394  * @params[in] E2AP_PDU_t *e2apMsg
4395  * @return ROK     - success
4396  *         RFAILED - failure
4397  *
4398  * ****************************************************************/
4399 void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg)
4400 {
4401    uint8_t ieIdx =0;
4402    ResetRequestE2_t  *resetReq = NULLP;
4403
4404    if(e2apMsg != NULLP)
4405    {
4406       if(e2apMsg->choice.initiatingMessage != NULLP)
4407       {
4408          resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4409          if(resetReq->protocolIEs.list.array)
4410          {
4411             for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
4412             {
4413                DU_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4414             }
4415             DU_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4416          }
4417          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4418       }
4419       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4420    }
4421 }
4422
4423 /*******************************************************************
4424  *
4425  * @brief Build and send the E2 reset request msg
4426  *
4427  * @details
4428  *
4429  *    Function : BuildAndSendE2ResetRequest
4430  *
4431  *    Functionality:
4432  *         - Buld and send the E2 reset request msg to RIC
4433  *
4434  * @params[in]
4435  * @return ROK     - success
4436  *         RFAILED - failure
4437  *
4438  * ****************************************************************/
4439 uint8_t BuildAndSendE2ResetRequest(E2FailureCause resetCause)
4440 {
4441    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
4442    uint8_t ret = RFAILED;
4443    E2AP_PDU_t        *e2apMsg = NULLP;
4444    ResetRequestE2_t  *resetReq = NULLP;
4445    asn_enc_rval_t     encRetVal;       /* Encoder return value */
4446
4447    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Request\n");
4448
4449    do
4450    {
4451       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4452       if(e2apMsg == NULLP)
4453       {
4454          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for E2AP-PDU failed");
4455          break;
4456       }
4457
4458       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4459       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4460       if(e2apMsg->choice.initiatingMessage == NULLP)
4461       {
4462          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for initiatingMessage");
4463          break;
4464       }
4465
4466       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
4467       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4468       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
4469       resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4470
4471       elementCnt = 2;
4472       resetReq->protocolIEs.list.count = elementCnt;
4473       resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
4474
4475       DU_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4476       if(!resetReq->protocolIEs.list.array)
4477       {
4478          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
4479             Reset Request IE array");
4480          break;
4481       }
4482
4483       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
4484       {
4485          DU_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4486          if(!resetReq->protocolIEs.list.array[ieIdx])
4487          {
4488             DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
4489             Reset Request IE array element");
4490             break;
4491          }
4492       }
4493
4494       /* In case of failure */
4495       if(ieIdx < elementCnt)
4496          break;
4497
4498       ieIdx = 0;
4499       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4500       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
4501       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
4502       transId = assignTransactionId();
4503       resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
4504
4505       ieIdx++;
4506       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
4507       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
4508       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
4509       fillE2Cause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, resetCause);
4510
4511       /* Prints the Msg formed */
4512       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4513
4514       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4515       encBufSize = 0;
4516       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4517             encBuf);
4518       if(encRetVal.encoded == ENCODE_FAIL)
4519       {
4520          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupRequest structure (at %s)\n",\
4521                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4522          break;
4523       }
4524       else
4525       {
4526          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2SetupRequest\n");
4527 #ifdef DEBUG_ASN_PRINT
4528          for(int i=0; i< encBufSize; i++)
4529          {
4530             printf("%x",encBuf[i]);
4531          }
4532 #endif
4533       }
4534       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
4535       {
4536          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
4537          break;
4538       }
4539
4540       /* In case the message is sent successfully, store the transaction info to
4541        * be used when response is received */
4542       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
4543       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
4544
4545       ret = ROK;
4546       break;
4547    }while(true);
4548
4549    /* Free all memory */
4550    FreeE2ResetRequest(e2apMsg);
4551    return ret;
4552 }
4553
4554 /*******************************************************************
4555  *
4556  * @brief Deallocate the memory allocated for Reset Response msg
4557  *
4558  * @details
4559  *
4560  *    Function : freeAperDecodingOfE2ResetRsp
4561  *
4562  *    Functionality:
4563  *       - freeing the memory allocated for Reset response
4564  *
4565  * @params[in] ResetResponseE2_t *resetResponse
4566  * @return void
4567  *
4568  * ****************************************************************/
4569 void freeAperDecodingOfE2ResetRsp(ResetResponseE2_t *resetResponse)
4570 {
4571    uint8_t ieIdx;
4572
4573    if(resetResponse)
4574    {
4575       if(resetResponse->protocolIEs.list.array)
4576       {
4577          for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
4578          {
4579             if(resetResponse->protocolIEs.list.array[ieIdx])
4580             {
4581                switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
4582                {
4583                   case ProtocolIE_IDE2_id_TransactionID:
4584                      break;
4585
4586                   case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
4587                      break;
4588                }
4589                free(resetResponse->protocolIEs.list.array[ieIdx]);
4590             }
4591          }
4592          free(resetResponse->protocolIEs.list.array);
4593       }
4594    }
4595 }
4596
4597 /******************************************************************
4598  *
4599  * @brief Processes E2 Reset Response sent by RIC
4600  *
4601  * @details
4602  *
4603  *    Function : procResetResponse
4604  *
4605  *    Functionality: Processes E2 Reset Response sent by RIC
4606  *
4607  * @params[in] E2AP_PDU_t ASN decoded E2AP message
4608  * @return ROK     - success
4609  *         RFAILED - failure
4610  *
4611  * ****************************************************************/
4612 uint8_t procResetResponse(E2AP_PDU_t *e2apMsg)
4613 {
4614    uint8_t ieIdx =0, transId;
4615    ResetResponseE2_t *resetResponse;
4616
4617    DU_LOG("\nINFO   -->  E2AP : E2 Reset Response received");
4618    resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;;
4619
4620    for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
4621    {
4622       switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
4623       {
4624          case ProtocolIE_IDE2_id_TransactionID:
4625             transId = resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
4626             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) && \
4627                   (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
4628             {
4629                memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
4630             }
4631             else
4632             {
4633                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
4634                return RFAILED;
4635             }
4636             break;
4637          case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
4638             /* As per ORAN WG3 E2AP spec v3.0, section 9.2.2
4639                Criticality Diagnostics IE is sent by Near-RT RIC when parts of a received message i.e. 
4640                Reset Request in this case, have not been comprehended or were missing, or if the message 
4641                contained logical errors.
4642
4643                Processing of this ID should be implemented when negative call flows are to be supported.
4644              */
4645             break;
4646          default:
4647             DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2 Reset Response : %ld",
4648                   resetResponse->protocolIEs.list.array[ieIdx]->id);
4649             break;
4650       }
4651    }
4652
4653    freeAperDecodingOfE2ResetRsp(resetResponse);
4654    return ROK;
4655 }
4656
4657 /******************************************************************
4658  *
4659  * @brief Deallocation of memory allocated by aper decoder for e2 setup Failure
4660  *
4661  * @details
4662  *
4663  *    Function : freeAperDecodingOfE2SetupFailure
4664  *
4665  *    Functionality: Deallocation of memory allocated by aper decoder for e2
4666  *    setup Failure
4667  *
4668  * @params[in] E2setupFailure_t *e2SetupFailure;
4669  * @return void
4670  *
4671  * ****************************************************************/
4672 void freeAperDecodingOfE2SetupFailure(E2setupFailure_t *e2SetupFailure)
4673 {
4674    uint8_t arrIdx;
4675
4676    if(e2SetupFailure)
4677    {
4678       if(e2SetupFailure->protocolIEs.list.array)
4679       {
4680          for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
4681          {
4682             if(e2SetupFailure->protocolIEs.list.array[arrIdx])
4683             {
4684                free(e2SetupFailure->protocolIEs.list.array[arrIdx]);  
4685             }
4686          }
4687          free(e2SetupFailure->protocolIEs.list.array);
4688       }
4689    }
4690 }
4691 /******************************************************************
4692  *
4693  * @brief Processes E2 Setup Failure sent by RIC
4694  *
4695  * @details
4696  *
4697  *    Function : procE2SetupFailure
4698  *
4699  *    Functionality: Processes E2 Setup failure sent by RIC
4700  *
4701  * @params[in] E2AP_PDU_t ASN decoded E2AP message
4702  * @return ROK     - success
4703  *         RFAILED - failure
4704  *
4705  * ****************************************************************/
4706 void procE2SetupFailure(E2AP_PDU_t *e2apMsg)
4707 {
4708    uint8_t arrIdx =0, transId =0, timerValue=0; 
4709    E2setupFailure_t *e2SetupFailure;
4710
4711    DU_LOG("\nINFO   -->  E2AP : E2 Setup failure received"); 
4712    e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
4713
4714    for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
4715    {
4716       switch(e2SetupFailure->protocolIEs.list.array[arrIdx]->id)
4717       {
4718          case ProtocolIE_IDE2_id_TransactionID:
4719          {
4720             transId = e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
4721             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
4722                   (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
4723             {
4724                memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
4725             }
4726             else
4727             {
4728                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
4729                return ;
4730             }
4731             break;
4732          }
4733          case ProtocolIE_IDE2_id_TimeToWaitE2:
4734             {
4735                timerValue = convertE2WaitTimerEnumToValue(e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
4736                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR)) == FALSE)
4737                {
4738                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR, timerValue);
4739                }
4740                else
4741                {
4742                   DU_LOG("\nERROR   -->  E2AP : EVENT_E2_SETUP_TMR timer is already running");
4743                   return;
4744                }
4745                break; 
4746             }
4747       }
4748    }
4749
4750    freeAperDecodingOfE2SetupFailure(e2SetupFailure);
4751 }
4752 /******************************************************************
4753  *
4754  * @brief Deallocation of memory allocated by aper decoder for RIC service Query
4755  *
4756  * @details
4757  *
4758  *    Function : freeAperDecodingOfRicServiceQuery
4759  *
4760  *    Functionality: Deallocation of memory allocated by aper decoder for RIC
4761  *    service Query
4762  *
4763  * @params[in] RICserviceQuery_t *ricServiceQuery;
4764  * @return void
4765  *
4766  * ****************************************************************/
4767
4768 void freeAperDecodingOfRicServiceQuery(RICserviceQuery_t *ricServiceQuery)
4769 {
4770    uint8_t arrIdx,ranFuncIdx;
4771     RANfunctionsID_List_t *ranFuncAddedList;
4772
4773    if(ricServiceQuery)
4774    {
4775       if(ricServiceQuery->protocolIEs.list.array)
4776       {
4777          for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
4778          {
4779             if(ricServiceQuery->protocolIEs.list.array[arrIdx])
4780             {
4781                switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
4782                {
4783                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
4784                   {
4785                      ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
4786                      if(ranFuncAddedList->list.array)
4787                      {
4788                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
4789                         {
4790                            free(ranFuncAddedList->list.array[ranFuncIdx]);
4791                         }
4792                         free(ranFuncAddedList->list.array);;
4793                      }
4794                      break;
4795                   }
4796                   default:
4797                      break;
4798                }
4799                free(ricServiceQuery->protocolIEs.list.array[arrIdx]);
4800             }
4801          }
4802          free(ricServiceQuery->protocolIEs.list.array);
4803       }
4804    }
4805 }
4806 /*******************************************************************
4807  *
4808  * @brief Build RanFunction Delete List
4809  *
4810  * @details
4811  *
4812  *    Function : BuildRanFunctionDeleteList
4813  *
4814  * Functionality:  Build RanFunction Delete List
4815  *
4816  * @params[in]
4817  *    RANfunctionsID List
4818  *    Count of the RAN function
4819  *    Received RAN function list
4820  *
4821  * @return ROK     - success
4822  *         RFAILED - failure
4823  *
4824  ******************************************************************/
4825
4826 uint8_t BuildRanFunctionDeleteList(RANfunctionsID_List_t *deleteList, uint8_t count, RanFuncInfo *recvdRanFunc)
4827 {
4828    uint8_t ranFuncIdx=0;
4829    RANfunctionID_ItemIEs_t *delRanFuncItem;
4830
4831    if(count)
4832    {
4833       deleteList->list.count = count;
4834       deleteList->list.size = deleteList->list.count * sizeof(RANfunctionID_ItemIEs_t*);
4835       DU_ALLOC(deleteList->list.array, deleteList->list.size);
4836       if(deleteList->list.array == NULLP)
4837       {
4838          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
4839          return RFAILED;
4840       }
4841       for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
4842       {
4843          DU_ALLOC(deleteList->list.array[ranFuncIdx], sizeof(RANfunctionID_ItemIEs_t));
4844          if(deleteList->list.array[ranFuncIdx] == NULLP)
4845          {
4846             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
4847             return RFAILED;
4848          }
4849          delRanFuncItem= (RANfunctionID_ItemIEs_t *) deleteList->list.array[ranFuncIdx];
4850          delRanFuncItem->id = ProtocolIE_IDE2_id_RANfunctionID_Item;
4851          delRanFuncItem->criticality = CriticalityE2_ignore;
4852          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionID = recvdRanFunc[ranFuncIdx].id;
4853          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionRevision = recvdRanFunc[ranFuncIdx].revisionCounter;
4854
4855       }
4856    }
4857    return ROK;
4858 }
4859 /*******************************************************************
4860  *
4861  * @brief De Allocate  Ric Service Update message
4862  *
4863  * @details
4864  *
4865  *    Function : FreeRicServiceUpdate
4866  *
4867  *    Functionality: De-Allocating Ric Service Update message
4868  *
4869  * @params[in] E2AP_PDU_t *e2apMsg
4870
4871  * @return void
4872  *
4873  * ****************************************************************/
4874
4875 void FreeRicServiceUpdate(E2AP_PDU_t *e2apMsg)
4876 {
4877    uint8_t arrIdx = 0;
4878    uint8_t ranFuncAddListIdx=0, ranFuncDelIdx=0;
4879    RICserviceUpdate_t *ricServiceUpdate;
4880    RANfunctions_List_t *ranFunctionsList;
4881    RANfunction_ItemIEs_t *ranFuncItemIe;
4882    RANfunction_Item_t  *ranFunItem;
4883    RANfunctionsID_List_t *deleteList;
4884
4885    /* De-allocating Memory */
4886    if(e2apMsg != NULLP)
4887    {
4888       if(e2apMsg->choice.initiatingMessage != NULLP)
4889       {
4890          ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
4891          if(ricServiceUpdate->protocolIEs.list.array != NULLP)
4892          {
4893             for(arrIdx = 0; arrIdx < ricServiceUpdate->protocolIEs.list.count; arrIdx++)
4894             {
4895                if(ricServiceUpdate->protocolIEs.list.array[arrIdx] != NULLP)
4896                {
4897                   switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
4898                   {
4899                      case ProtocolIE_IDE2_id_TransactionID:
4900                         break;
4901
4902                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
4903                      case ProtocolIE_IDE2_id_RANfunctionsModified:
4904                         {
4905                            ranFunctionsList = &(ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List);
4906                            if(ranFunctionsList->list.array)
4907                            {
4908                               for(ranFuncAddListIdx= 0; ranFuncAddListIdx< ranFunctionsList->list.count; ranFuncAddListIdx++)
4909                               {
4910                                  if(ranFunctionsList->list.array[ranFuncAddListIdx])
4911                                  {
4912                                     ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncAddListIdx];
4913                                     ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
4914                                     DU_FREE(ranFunItem->ranFunctionOID.buf, ranFunItem->ranFunctionOID.size);
4915                                     DU_FREE(ranFunItem->ranFunctionDefinition.buf, ranFunItem->ranFunctionDefinition.size);
4916                                     DU_FREE(ranFunctionsList->list.array[ranFuncAddListIdx], sizeof(RANfunction_ItemIEs_t));
4917                                  }
4918                               }
4919                               DU_FREE(ranFunctionsList->list.array, ranFunctionsList->list.size);
4920                            }
4921                            break;
4922                         }
4923                      case ProtocolIE_IDE2_id_RANfunctionsDeleted:
4924                         {
4925                            deleteList= &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
4926                            if(deleteList->list.array)
4927                            {
4928                               for(ranFuncDelIdx = 0; ranFuncDelIdx< deleteList->list.count; ranFuncDelIdx++)
4929                               {
4930                                  DU_FREE(deleteList->list.array[ranFuncDelIdx], sizeof(RANfunctionID_ItemIEs_t));
4931                               }
4932                               DU_FREE(deleteList->list.array, deleteList->list.size);
4933   
4934                            }
4935                            break;
4936                         }
4937                      default:
4938                         DU_LOG("\nERROR  --> E2AP: Invalid event at ricServiceUpdate %ld ",\
4939                               (ricServiceUpdate->protocolIEs.list.array[arrIdx]->id));
4940                         break;
4941                   }
4942                   DU_FREE(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
4943                }
4944             }
4945             DU_FREE(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
4946          }
4947          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4948       }
4949       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4950    }
4951 }
4952
4953 /*******************************************************************
4954  *
4955  * @brief Builds and Send the RicServiceUpdateuest
4956  *
4957  * @details
4958  *
4959  *    Function : BuildAndSendRicServiceUpdate
4960  *
4961  * Functionality:Fills the RicServiceUpdateuest
4962  *
4963  * @return ROK     - success
4964  *         RFAILED - failure
4965  *
4966  ******************************************************************/
4967
4968 uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate)
4969 {
4970    uint8_t arrIdx = 0, elementCnt=0;
4971    uint8_t transId = 0, ret = RFAILED;
4972    bool memAllocFailed =false;
4973    E2AP_PDU_t        *e2apMsg = NULLP;
4974    RICserviceUpdate_t  *ricServiceUpdate = NULLP;
4975    asn_enc_rval_t     encRetVal;       /* Encoder return value */
4976
4977    DU_LOG("\nINFO   -->  E2AP : Building Ric Service Update\n");
4978    do
4979    {
4980       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4981       if(e2apMsg == NULLP)
4982       {
4983          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4984          break;
4985       }
4986       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4987       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4988       if(e2apMsg->choice.initiatingMessage == NULLP)
4989       {
4990          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4991          break;
4992       }
4993       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4994       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
4995       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceUpdate;
4996       ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
4997       
4998       /* For TransId IE, set elementCnt to 1.
4999       If there is any item in the RAN function add list, RAN function modification list, or RAN function delete list, increment the elementCnt.*/
5000
5001       elementCnt =1;
5002       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5003         elementCnt++;
5004       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
5005          elementCnt++;
5006       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
5007          elementCnt++;
5008        
5009       ricServiceUpdate->protocolIEs.list.count = elementCnt;
5010       ricServiceUpdate->protocolIEs.list.size = elementCnt * sizeof(RICserviceUpdate_IEs_t*);
5011
5012       /* Initialize the E2Setup members */
5013       DU_ALLOC(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
5014       if(ricServiceUpdate->protocolIEs.list.array == NULLP)
5015       {
5016          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
5017          break;
5018       }
5019       
5020       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
5021       {
5022          DU_ALLOC(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
5023          if(ricServiceUpdate->protocolIEs.list.array[arrIdx] == NULLP)
5024          {
5025             memAllocFailed = true;
5026             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayIdx [%d]", arrIdx);
5027             break;
5028          }
5029       }
5030       if(memAllocFailed == true)
5031          break;
5032
5033       arrIdx = 0;
5034
5035       /* TransactionID */
5036       ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
5037       ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5038       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
5039       if(serviceUpdate.dir == E2_NODE_INITIATED)
5040          transId = assignTransactionId();
5041       else
5042         transId = serviceUpdate.transId;
5043       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
5044
5045       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5046       {
5047          arrIdx++;
5048          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAdded;
5049          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5050          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
5051          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,\
5052          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded, serviceUpdate.recvRanFuncList.ranFunToBeAdded) !=ROK)
5053          {
5054             break;
5055          }
5056       }
5057
5058       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
5059       {
5060          arrIdx++;
5061          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsModified;
5062          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5063          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
5064          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,
5065          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeModified, serviceUpdate.recvRanFuncList.ranFunToBeModified) !=ROK)
5066          {
5067             break;
5068          }
5069       }
5070
5071       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
5072       {
5073          arrIdx++;
5074          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsDeleted;
5075          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5076          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctionsID_List;
5077          if(BuildRanFunctionDeleteList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List,\
5078          serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted, serviceUpdate.recvRanFuncList.ranFunToBeDeleted) != ROK)
5079          {
5080             break;
5081          }
5082       }
5083       /* Prints the Msg formed */
5084       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5085
5086       memset(encBuf, 0, ENC_BUF_MAX_LEN);
5087       encBufSize = 0;
5088       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
5089       if(encRetVal.encoded == ENCODE_FAIL)
5090       {
5091          DU_LOG("\nERROR  -->  E2AP : Could not encode RicServiceUpdateuest structure (at %s)\n",\
5092                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
5093          break;
5094       }
5095       else
5096       {
5097          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RicServiceUpdateuest\n");
5098 #ifdef DEBUG_ASN_PRINT
5099          for(int i=0; i< encBufSize; i++)
5100          {
5101             printf("%x",encBuf[i]);
5102          }
5103 #endif
5104       }
5105       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
5106       {
5107          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
5108          break;
5109       }
5110       ret = ROK;
5111       break;
5112    }while(true);
5113    
5114    if(ret == ROK)
5115    {
5116       if(serviceUpdate.dir == E2_NODE_INITIATED)
5117       {
5118          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
5119          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5120       }
5121       else
5122       {
5123          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId = transId;
5124          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5125       }
5126       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.dir = serviceUpdate.dir;
5127       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.transId =transId;
5128       memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.recvRanFuncList, &serviceUpdate.recvRanFuncList, sizeof(E2TmpRanFunList));
5129    }
5130    FreeRicServiceUpdate(e2apMsg);
5131    return ret;
5132 }
5133 /******************************************************************
5134  *
5135  * @brief Processes RIC service Query sent by RIC
5136  *
5137  * @details
5138  *
5139  *    Function : procRicServiceQuery
5140  *
5141  *    Functionality: Processes RIC service Query sent by RIC
5142  *
5143  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5144  * @return ROK     - success
5145  *         RFAILED - failure
5146  *
5147  * ****************************************************************/
5148
5149 void procRicServiceQuery(E2AP_PDU_t *e2apMsg)
5150 {
5151    ConfigType action;
5152    uint16_t arrIdx =0, ranFuncIdx=0,tmpIdx=0;
5153    uint16_t id,revisionCcounter;
5154    bool tmpArray[MAX_RAN_FUNCTION] = {false};
5155    RICserviceQuery_t *ricServiceQuery=NULL;
5156    RicServiceUpdate ricUpdate;
5157    RANfunctionID_ItemIEs_t *ranFuncAddedItemIe;
5158    RANfunctionsID_List_t *ranFuncAddedList;
5159
5160    DU_LOG("\nINFO   -->  E2AP : RIC Service Query received");
5161    memset(&ricUpdate, 0, sizeof(RicServiceUpdate));
5162    ricUpdate.dir = RIC_INITIATED;
5163    ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
5164
5165    for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
5166    {
5167       switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
5168       {
5169          /* TODO completing in next patch/gerrit */
5170          case ProtocolIE_IDE2_id_TransactionID:
5171          {
5172             ricUpdate.transId = ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
5173             break;
5174          }
5175
5176          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5177          {
5178             ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5179             if(ranFuncAddedList->list.array)
5180             {
5181                for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
5182                {
5183                   if(ranFuncAddedList->list.array[ranFuncIdx])
5184                   {
5185                      /* Using the RAN function Id, identify the RAN function to be modified or deleted.  */
5186                      
5187                      ranFuncAddedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAddedList->list.array[ranFuncIdx];
5188                      id = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionID;
5189                      revisionCcounter = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision;
5190                      
5191                      if((id != duCb.e2apDb.ranFunction[id-1].id))
5192                      {
5193                         action = CONFIG_DEL;
5194                      }
5195                      else if((id == duCb.e2apDb.ranFunction[id-1].id)&&(revisionCcounter!=duCb.e2apDb.ranFunction[id-1].revisionCounter))
5196                      {
5197                         action = CONFIG_MOD;
5198                      }
5199
5200                      if(action == CONFIG_DEL)
5201                      {
5202                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].id = id;
5203                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].revisionCounter = revisionCcounter;
5204                         ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted++;
5205                      }
5206                      else if(action == CONFIG_MOD)
5207                      {
5208                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].id = id;
5209                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].revisionCounter = revisionCcounter;
5210                         ricUpdate.recvRanFuncList.numOfRanFunToBeModified++;
5211                      }
5212
5213                      /* If any ID is set to true, it means that the ID has been used in either modification or deletion list. 
5214                       * Else we will add the IDs into the added list */
5215                      tmpArray[id-1] = true;
5216                   }
5217                }
5218             }
5219             break;
5220          }
5221       }
5222    }
5223
5224    /*  Traversing the whole RAN function list in ducb to check if any new Ran function ids have been added. */
5225    for(arrIdx =0; arrIdx<MAX_RAN_FUNCTION; arrIdx++)
5226    {
5227       tmpIdx= ricUpdate.recvRanFuncList.numOfRanFunToBeAdded;
5228       if((duCb.e2apDb.ranFunction[arrIdx].id >0)&&(!tmpArray[arrIdx]))
5229       {
5230          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[arrIdx].id;
5231          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[arrIdx].revisionCounter;
5232          ricUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
5233       }
5234    }
5235
5236    if(BuildAndSendRicServiceUpdate(ricUpdate)!= ROK)
5237    {
5238       DU_LOG("\nERROR  -->  E2AP : Failed to build and send ric service update message");
5239    }
5240
5241    freeAperDecodingOfRicServiceQuery(ricServiceQuery);
5242 }
5243
5244 /******************************************************************
5245  *
5246  * @brief Deallocation of memory allocated by aper decoder for 
5247  *    RIC service update ack
5248  *
5249  * @details
5250  *
5251  *    Function : freeAperDecodingOfRicServiceUpdateAck
5252  *
5253  *    Functionality: Deallocation of memory allocated by aper decoder 
5254  *    for RIC service update ack
5255  *
5256  * @params[in] RICserviceUpdateAck_t *ricServiceAck;
5257  * @return void
5258  *
5259  * ****************************************************************/
5260
5261 void freeAperDecodingOfRicServiceUpdateAck(RICserviceUpdateAcknowledge_t *ricServiceAck)
5262 {
5263    uint8_t arrIdx=0,ranFuncIdx=0;
5264    RANfunctionsID_List_t *ranFuncAddedList=NULL;
5265
5266    if(ricServiceAck)
5267    {
5268       if(ricServiceAck->protocolIEs.list.array)
5269       {
5270          for(arrIdx=0; arrIdx<ricServiceAck->protocolIEs.list.count; arrIdx++)
5271          {
5272             if(ricServiceAck->protocolIEs.list.array[arrIdx])
5273             {
5274                switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id)
5275                {
5276                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5277                   {
5278                      ranFuncAddedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5279                      if(ranFuncAddedList->list.array)
5280                      {
5281                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
5282                         {
5283                            free(ranFuncAddedList->list.array[ranFuncIdx]);
5284                         }
5285                         free(ranFuncAddedList->list.array);
5286                      }
5287                      break;
5288                   }
5289                   default:
5290                      break;
5291                }
5292                free(ricServiceAck->protocolIEs.list.array[arrIdx]);  
5293             }
5294          }
5295          free(ricServiceAck->protocolIEs.list.array);
5296       }
5297    }
5298 }
5299
5300 /******************************************************************
5301  *
5302  * @brief Processes RIC service update ack sent by RIC
5303  *
5304  * @details
5305  *
5306  *    Function : procRicServiceUpdateAck
5307  *
5308  *    Functionality: Processes RIC service update ack sent by RIC
5309  *
5310  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5311  * @return ROK     - success
5312  *         RFAILED - failure
5313  *
5314  * ****************************************************************/
5315
5316 void procRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
5317 {
5318    uint8_t arrIdx =0, transId =0; 
5319    uint16_t id =0, tmpIdx=0, ranFuncIdx=0;
5320    RicServiceUpdate serviceUpdate;
5321    RANfunctionsIDcause_List_t *rejectedList=NULL;
5322    RICserviceUpdateAcknowledge_t *ricServiceAck=NULL;
5323    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
5324    
5325    DU_LOG("\nINFO   -->  E2AP : RIC service update ack received"); 
5326    memset(&serviceUpdate, 0, sizeof(RicServiceUpdate));
5327    ricServiceAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
5328    
5329    for(arrIdx=0; arrIdx<ricServiceAck->protocolIEs.list.count; arrIdx++)
5330    {
5331       switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id)
5332       {
5333          case ProtocolIE_IDE2_id_TransactionID:
5334          {
5335             transId = ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
5336             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
5337             (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
5338             {
5339               memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
5340             }
5341             else if((duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId == transId) &&\
5342             (duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
5343             {
5344               memset(&duCb.e2apDb.e2TransInfo.ricInitTransaction[transId], 0, sizeof(E2TransInfo));
5345             }
5346             else
5347             {
5348                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
5349                return ;
5350             }
5351             break;
5352          }
5353          
5354          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5355             break;
5356
5357          case ProtocolIE_IDE2_id_RANfunctionsRejected:
5358          {
5359             rejectedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
5360             if(rejectedList->list.array)
5361             {
5362                for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
5363                {
5364                   ranFuncRejectedItemIe =  (RANfunctionIDcause_ItemIEs_t*)rejectedList->list.array[ranFuncIdx];
5365                   id = ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID;
5366                   tmpIdx= serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded;
5367                   serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[id-1].id;
5368                   serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[id-1].revisionCounter;
5369                   serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
5370                }
5371             }
5372             break;
5373          }
5374
5375       }
5376    }
5377
5378    if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5379    {
5380       serviceUpdate.dir = E2_NODE_INITIATED;
5381       BuildAndSendRicServiceUpdate(serviceUpdate);
5382    }
5383    freeAperDecodingOfRicServiceUpdateAck(ricServiceAck);
5384 }
5385
5386 /******************************************************************
5387  *
5388  * @brief Deallocation of memory allocated by aper decoder for 
5389  *       RIC service update failure
5390  *
5391  * @details
5392  *
5393  *    Function : freeAperDecodingOfRicServiceUpdateFailure
5394  *
5395  *    Functionality: Deallocation of memory allocated by aper decoder 
5396  *    for RIC service update failure
5397  *
5398  * @params[in] RICserviceUpdateFailure_t *ricServiceFailure;
5399  * @return void
5400  *
5401  * ****************************************************************/
5402
5403 void freeAperDecodingOfRicServiceUpdateFailure(RICserviceUpdateFailure_t *ricServiceFailure)
5404 {
5405    uint8_t arrIdx=0;
5406
5407    if(ricServiceFailure)
5408    {
5409       if(ricServiceFailure->protocolIEs.list.array)
5410       {
5411          for(arrIdx=0; arrIdx<ricServiceFailure->protocolIEs.list.count; arrIdx++)
5412          {
5413             if(ricServiceFailure->protocolIEs.list.array[arrIdx])
5414             {
5415                free(ricServiceFailure->protocolIEs.list.array[arrIdx]);  
5416             }
5417          }
5418          free(ricServiceFailure->protocolIEs.list.array);
5419       }
5420    }
5421 }
5422
5423 /******************************************************************
5424  *
5425  * @brief Processes RIC service update failure sent by RIC
5426  *
5427  * @details
5428  *
5429  *    Function : procRicServiceUpdateFailure
5430  *
5431  *    Functionality: Processes RIC service update failure sent by RIC
5432  *
5433  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5434  * @return ROK     - success
5435  *         RFAILED - failure
5436  *
5437  * ****************************************************************/
5438
5439 void procRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
5440 {
5441    uint8_t arrIdx =0, timerValue=0; 
5442    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
5443
5444    DU_LOG("\nINFO   -->  E2AP : RIC service update failure received"); 
5445    ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
5446
5447    for(arrIdx=0; arrIdx<ricServiceFailure->protocolIEs.list.count; arrIdx++)
5448    {
5449       switch(ricServiceFailure->protocolIEs.list.array[arrIdx]->id)
5450       {
5451          case ProtocolIE_IDE2_id_TransactionID:
5452             {
5453                break;
5454             }
5455          case ProtocolIE_IDE2_id_TimeToWaitE2:
5456             {
5457                timerValue = convertE2WaitTimerEnumToValue(ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
5458                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR)) == FALSE)
5459                {
5460                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR, timerValue);
5461                }
5462                else
5463                {
5464                   DU_LOG("\nERROR   -->  E2AP : EVENT_RIC_SERVICE_UPDATE_TMR  timer is already running");
5465                   return;
5466                }
5467                break; 
5468             }
5469          case ProtocolIE_IDE2_id_CauseE2:
5470             {
5471                break;
5472             }
5473       }
5474    }
5475
5476    freeAperDecodingOfRicServiceUpdateFailure(ricServiceFailure);
5477 }
5478
5479 /******************************************************************
5480  *
5481  * @brief DU Send E2 Node Configuration Update
5482  *
5483  * @details
5484  *
5485  *    Function : duSendE2NodeConfigurationUpdate 
5486  *
5487  *    Functionality: DU Send E2 Node Configuration Update
5488  *
5489  * @return ROK     - success
5490  *         RFAILED - failure
5491  *
5492  * ****************************************************************/
5493
5494 uint8_t duSendE2NodeConfigurationUpdate()
5495 {
5496    E2NodeConfigList e2NodeList;
5497    CmLList *node =NULL;
5498    E2NodeComponent *e2NodeComponentInfo=NULL;
5499
5500    memset(&e2NodeList, 0, sizeof(E2NodeConfigList));
5501    CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node);
5502    while(node)
5503    {
5504       e2NodeComponentInfo = (E2NodeComponent*)node->node;
5505
5506       if(e2NodeComponentInfo->componentRequestPart && e2NodeComponentInfo->componentResponsePart)
5507       {
5508          switch(e2NodeComponentInfo->componentActionType)
5509          {
5510             case E2_NODE_COMPONENT_ADD:
5511                {
5512                   e2NodeList.addE2Node[e2NodeList.addE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
5513                   e2NodeList.addE2Node[e2NodeList.addE2NodeCount].actionType = e2NodeComponentInfo->componentActionType;
5514                   e2NodeList.removeE2NodeCount++;
5515                   break;
5516                }
5517             case E2_NODE_COMPONENT_UPDATE:
5518                {
5519                   e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
5520                   e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].actionType = e2NodeComponentInfo->componentActionType;
5521                   e2NodeList.updateE2NodeCount++;
5522                   break;
5523
5524                }
5525             case E2_NODE_COMPONENT_DEL:
5526                {
5527                   e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
5528                   e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].actionType = e2NodeComponentInfo->componentActionType;
5529                   e2NodeList.removeE2NodeCount++;
5530                   break;
5531                }
5532          }
5533       }
5534       node = node->next;
5535    }
5536
5537    if(BuildAndSendE2NodeConfigUpdate(&e2NodeList) !=ROK)
5538    {
5539       DU_LOG("\nERROR  -->  E2AP : Failed to build and send e2 node config update message to RIC_stub");
5540       return RFAILED;
5541    }
5542    return ROK;
5543 }
5544
5545 /*******************************************************************
5546  *
5547  * @brief Free RIC Subscription Modification Required
5548  *
5549  * @details
5550  *
5551  *    Function : FreeRicSubsModRequired
5552  *
5553  * Functionality: Freqq RIC Subscription Modification required
5554  *
5555  * @param  E2AP Message PDU to be freed
5556  * @return void
5557  *
5558  ******************************************************************/
5559 void FreeRicSubsModRequired(E2AP_PDU_t *e2apMsg)
5560 {
5561    uint8_t ieIdx = 0, arrIdx = 0;
5562    RICsubscriptionModificationRequired_t  *ricSubsModReqd = NULLP;
5563    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
5564    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
5565    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
5566
5567    if(e2apMsg)
5568    {
5569       if(e2apMsg->choice.initiatingMessage)
5570       {
5571          ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired;
5572          if(ricSubsModReqd->protocolIEs.list.array)
5573          {
5574             for(ieIdx = 0; ieIdx < ricSubsModReqd->protocolIEs.list.count; ieIdx++)
5575             {
5576                if(ricSubsModReqd->protocolIEs.list.array[ieIdx])
5577                {
5578                   ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
5579                   switch(ricSubsModReqdIe->id)
5580                   {
5581                      case ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List:
5582                         {
5583                            actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
5584                            if(actionToBeModList->list.array)
5585                            {
5586                               for(arrIdx = 0; arrIdx < actionToBeModList->list.count; arrIdx++)
5587                               { 
5588                                  DU_FREE(actionToBeModList->list.array[arrIdx], \
5589                                     sizeof(RICaction_RequiredToBeModified_ItemIEs_t));
5590                               }
5591                               DU_FREE(actionToBeModList->list.array, actionToBeModList->list.size);
5592                            }
5593                            break;
5594                         }
5595
5596                      case ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List:
5597                         {
5598                            actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
5599                            if(actionToBeRmvList->list.array)
5600                            {
5601                               for(arrIdx = 0; arrIdx < actionToBeRmvList->list.count; arrIdx++)
5602                               { 
5603                                  DU_FREE(actionToBeRmvList->list.array[arrIdx], \
5604                                     sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t));
5605                               }
5606                               DU_FREE(actionToBeRmvList->list.array, actionToBeRmvList->list.size);
5607                            }
5608                            break;
5609                         }
5610
5611                      default:
5612                         break;
5613                   }
5614                   DU_FREE(ricSubsModReqd->protocolIEs.list.array[ieIdx], \
5615                         sizeof(RICsubscriptionModificationRequired_IEs_t));
5616                }
5617             }
5618             DU_FREE(ricSubsModReqd->protocolIEs.list.array, ricSubsModReqd->protocolIEs.list.size);
5619          }
5620          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5621       }
5622       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
5623    }
5624 }
5625
5626 /* A RIC Subscription includes RIC subsequent action only for RIC Insert service.
5627  * However, E2SM-KPM supports only RIC Report service.
5628  * Hence there is no subsequent action in RIC subscription that may require modification.
5629  * So commenting the action-modification IEs for the time being
5630  */
5631 #if 0
5632 /*******************************************************************
5633  *
5634  * @brief Fill Action required to be modified list
5635  *
5636  * @details
5637  *
5638  *    Function : FillActionReqdToBeModList
5639  *
5640  * Functionality: Fill Action required to be modified list
5641  *
5642  * @param  RIC Actions Required To Be Modified List to be filled
5643  *         Number of actions to be modified
5644  *         RIC Subscription DB
5645  * @return ROK     - success
5646  *         RFAILED - failure
5647  *
5648  ******************************************************************/
5649 uint8_t FillActionReqdToBeModList(RICactions_RequiredToBeModified_List_t *actionToBeModList, uint8_t numActionsMod, \
5650    RicSubscription *ricSubscription)
5651 {
5652    uint8_t arrIdx = 0, actionIdx = 0;
5653    RICaction_RequiredToBeModified_ItemIEs_t *actionToBeMod = NULL;
5654
5655    actionToBeModList->list.count = numActionsMod;
5656    actionToBeModList->list.size = numActionsMod * sizeof(RICaction_RequiredToBeModified_ItemIEs_t *);
5657    DU_ALLOC(actionToBeModList->list.array, actionToBeModList->list.size);
5658    if(!actionToBeModList->list.array)
5659    {
5660       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
5661       return RFAILED;
5662    }
5663
5664    arrIdx = 0;
5665    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
5666    {
5667       if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD)
5668       {
5669          DU_ALLOC(actionToBeModList->list.array[arrIdx], sizeof(RICaction_RequiredToBeModified_ItemIEs_t));
5670          if(!actionToBeModList->list.array[arrIdx])
5671          {
5672             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
5673             return RFAILED;
5674          }
5675          actionToBeMod = (RICaction_RequiredToBeModified_ItemIEs_t *)actionToBeModList->list.array[arrIdx];
5676
5677          actionToBeMod->id = ProtocolIE_IDE2_id_RICaction_RequiredToBeModified_Item;
5678          actionToBeMod->criticality = CriticalityE2_reject;
5679          actionToBeMod->value.present = \
5680             RICaction_RequiredToBeModified_ItemIEs__value_PR_RICaction_RequiredToBeModified_Item;
5681          actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricActionID = \
5682             ricSubscription->actionSequence[actionIdx].actionId;
5683          actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricTimeToWait = RICtimeToWait_w5ms;
5684
5685          arrIdx++;
5686       }
5687    }
5688
5689    return ROK;
5690 }
5691 #endif
5692
5693 /*******************************************************************
5694  *
5695  * @brief Fill Action required to be removed list
5696  *
5697  * @details
5698  *
5699  *    Function : FillActionReqdToBeRmvList
5700  *
5701  * Functionality: Fill Action required to be removed list
5702  *
5703  * @param  RIC Actions Required To Be Removed List to be filled
5704  *         Number of actions to be removed
5705  *         RIC Subscription DB
5706  * @return ROK     - success
5707  *         RFAILED - failure
5708  *
5709  ******************************************************************/
5710 uint8_t FillActionReqdToBeRmvList(RICactions_RequiredToBeRemoved_List_t *actionToBeRmvList, uint8_t numActionsRmv, \
5711    RicSubscription *ricSubscription)
5712 {
5713    uint8_t arrIdx = 0, actionIdx = 0;
5714    RICaction_RequiredToBeRemoved_ItemIEs_t *actionToBeRmv = NULL;
5715
5716    actionToBeRmvList->list.count = numActionsRmv;
5717    actionToBeRmvList->list.size = numActionsRmv * sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t *);
5718    DU_ALLOC(actionToBeRmvList->list.array, actionToBeRmvList->list.size);
5719    if(!actionToBeRmvList->list.array)
5720    {
5721       DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
5722       return RFAILED;
5723    }
5724
5725    arrIdx = 0;
5726    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
5727    {
5728       if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL)
5729       {
5730          DU_ALLOC(actionToBeRmvList->list.array[arrIdx], sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t));
5731          if(!actionToBeRmvList->list.array[arrIdx])
5732          {
5733             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
5734             return RFAILED;
5735          }
5736          actionToBeRmv = (RICaction_RequiredToBeRemoved_ItemIEs_t *)actionToBeRmvList->list.array[arrIdx];
5737
5738          actionToBeRmv->id = ProtocolIE_IDE2_id_RICaction_RequiredToBeRemoved_Item;
5739          actionToBeRmv->criticality = CriticalityE2_reject;
5740          actionToBeRmv->value.present = \
5741             RICaction_RequiredToBeRemoved_ItemIEs__value_PR_RICaction_RequiredToBeRemoved_Item;
5742          actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.ricActionID = \
5743             ricSubscription->actionSequence[actionIdx].actionId;
5744          fillE2Cause(&actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.cause, \
5745             ricSubscription->actionSequence[actionIdx].failureCause);
5746
5747          arrIdx++;
5748       }
5749    }
5750
5751    return ROK;
5752 }
5753
5754 /*******************************************************************
5755  *
5756  * @brief Fill RIC Subscription Modification Required IEs
5757  *
5758  * @details
5759  *
5760  *    Function : FillRicSubsModRequired
5761  *
5762  * Functionality: Fill RIC Subscription Modification Required IEs
5763  *
5764  * @param  RIC Subscription Modification Required IEs to be filled
5765  *         RIC Subscription DB
5766  * @return ROK     - success
5767  *         RFAILED - failure
5768  *
5769  ******************************************************************/
5770 uint8_t FillRicSubsModRequired(RICsubscriptionModificationRequired_t *ricSubsModReqd, RicSubscription *ricSubscription)
5771 {
5772    uint8_t ieIdx = 0, elementCnt=0, actionIdx = 0;
5773    uint8_t numActionsMod = 0, numActionsRmv = 0;
5774    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
5775    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
5776    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
5777
5778    /* Count number of Actions to be modified or deleted */
5779    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
5780    {
5781       if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD)
5782          numActionsMod++;
5783       else if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL)
5784          numActionsRmv++;
5785    }
5786
5787    /* Count number of IEs to be added to messages */
5788    elementCnt = 2;
5789    if(numActionsMod)
5790       elementCnt++;
5791    if(numActionsRmv)
5792       elementCnt++;
5793
5794    ricSubsModReqd->protocolIEs.list.count = elementCnt;
5795    ricSubsModReqd->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationRequired_IEs_t *);
5796    DU_ALLOC(ricSubsModReqd->protocolIEs.list.array, ricSubsModReqd->protocolIEs.list.size);
5797    if(!ricSubsModReqd->protocolIEs.list.array)
5798    {
5799       DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
5800       return RFAILED;
5801    }
5802
5803    for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
5804    {
5805       DU_ALLOC(ricSubsModReqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRequired_IEs_t));
5806       if(!ricSubsModReqd->protocolIEs.list.array[ieIdx])
5807       {
5808          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
5809          return RFAILED;
5810       }
5811    }
5812
5813    /* RIC Request ID */
5814    ieIdx = 0;
5815    ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
5816    ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICrequestID;
5817    ricSubsModReqdIe->criticality = CriticalityE2_reject;
5818    ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RICrequestID;
5819    ricSubsModReqdIe->value.choice.RICrequestID.ricRequestorID = ricSubscription->requestId.requestorId;
5820    ricSubsModReqdIe->value.choice.RICrequestID.ricInstanceID = ricSubscription->requestId.instanceId;
5821
5822    /* RAN Function ID */
5823    ieIdx++;
5824    ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
5825    ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RANfunctionID;
5826    ricSubsModReqdIe->criticality = CriticalityE2_reject;
5827    ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RANfunctionID;
5828    ricSubsModReqdIe->value.choice.RANfunctionID = ricSubscription->ranFuncId;
5829
5830 /* A RIC Subscription includes RIC subsequent action only for RIC Insert service.
5831  * However, E2SM-KPM supports only RIC Report service.
5832  * Hence there is no subsequent action in RIC subscription that may require modification.
5833  * So commenting the action-modification IEs for the time being
5834  */
5835 #if 0
5836    /* RIC Actions Required to be Modified */
5837    if(numActionsMod)
5838    {
5839       ieIdx++;
5840       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
5841       ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List;
5842       ricSubsModReqdIe->criticality = CriticalityE2_reject;
5843       ricSubsModReqdIe->value.present = \
5844          RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeModified_List;
5845       actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
5846
5847       if(FillActionReqdToBeModList(actionToBeModList, numActionsMod, ricSubscription) != ROK)
5848       {
5849          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill actions required to be modified list", __func__);
5850          return RFAILED;
5851       }
5852    }
5853 #endif
5854
5855    /* RIC Actions Required to be removed */
5856    if(numActionsRmv)
5857    {
5858       ieIdx++;
5859       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
5860       ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List;
5861       ricSubsModReqdIe->criticality = CriticalityE2_reject;
5862       ricSubsModReqdIe->value.present = \
5863          RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeRemoved_List;
5864       actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
5865
5866       if(FillActionReqdToBeRmvList(actionToBeRmvList, numActionsRmv, ricSubscription) != ROK)
5867       {
5868          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill actions required to be removed list", __func__);
5869          return RFAILED;
5870       }
5871    }
5872
5873    return ROK;
5874 }
5875
5876 /*******************************************************************
5877  *
5878  * @brief Builds and Send RIC Subscription Modification Required
5879  *        message
5880  *
5881  * @details
5882  *
5883  *    Function : BuildAndSendRicSubsModRequired
5884  *
5885  * Functionality:  Builds and Send RIC Subscription Modification 
5886  *    Required message
5887  *
5888  * @param  RIC Subscription DB
5889  * @return ROK     - success
5890  *         RFAILED - failure
5891  *
5892  ******************************************************************/
5893 uint8_t BuildAndSendRicSubsModRequired(RicSubscription *ricSubscription)
5894 {
5895    uint8_t ret = RFAILED;
5896    E2AP_PDU_t        *e2apMsg = NULLP;
5897    RICsubscriptionModificationRequired_t  *ricSubsModReqd = NULLP;
5898    asn_enc_rval_t     encRetVal;       /* Encoder return value */
5899
5900    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Required \n");
5901    while(true)
5902    {
5903       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
5904       if(e2apMsg == NULLP)
5905       {
5906          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
5907          break;
5908       }
5909
5910       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
5911       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5912       if(e2apMsg->choice.initiatingMessage == NULLP)
5913       {
5914          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
5915          break;
5916       }
5917       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
5918       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired;
5919       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionModificationRequired;
5920
5921       ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired;
5922
5923       if(FillRicSubsModRequired(ricSubsModReqd, ricSubscription) != ROK)
5924       {
5925          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Subscription Modification Required IEs", __func__);
5926          break;
5927       }
5928       
5929       /* Encode */
5930       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5931
5932       memset(encBuf, 0, ENC_BUF_MAX_LEN);
5933       encBufSize = 0;
5934       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
5935       if(encRetVal.encoded == ENCODE_FAIL)
5936       {
5937          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Modifiction Required structure (at %s)\n",\
5938                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
5939          break;
5940       }
5941       else
5942       {
5943          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RIC Subscription Modification Required \n");
5944 #ifdef DEBUG_ASN_PRINT
5945          for(int i=0; i< encBufSize; i++)
5946          {
5947             printf("%x",encBuf[i]);
5948          }
5949 #endif
5950       }
5951       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
5952       {
5953          DU_LOG("\nERROR  -->  E2AP : Sending RIC Subscription Modification Required failed");
5954       }
5955
5956       ret = ROK;
5957       break;
5958    }
5959
5960    /* Free RIC Subscription modification required */
5961    FreeRicSubsModRequired(e2apMsg);
5962    return ret;
5963 }
5964
5965 /*******************************************************************
5966  *
5967  * @brief Free APER decoding of RIC Subscription Modification Confirm
5968  *
5969  * @details
5970  *
5971  *    Function : freeAperDecodingOfRicSubsModConfirm
5972  *
5973  * Functionality:  Free APER decoding of RIC Subscription 
5974  *   Modification Confirm
5975  *
5976  * @param  E2AP Message PDU
5977  * @return void
5978  *
5979  ******************************************************************/
5980 void freeAperDecodingOfRicSubsModConfirm(E2AP_PDU_t *e2apMsg)
5981 {
5982    uint8_t ieIdx = 0, arrIdx=0;
5983    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
5984    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
5985    RICactions_ConfirmedForModification_List_t *modCfmList = NULLP;
5986    RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP;
5987    RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP;
5988    RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP;
5989
5990    if(e2apMsg && e2apMsg->choice.successfulOutcome)
5991    {
5992       ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
5993       if(ricSubsModCfm->protocolIEs.list.array)
5994       {
5995          for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++)
5996          {
5997             if(ricSubsModCfm->protocolIEs.list.array[ieIdx])
5998             {
5999                ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
6000                switch(ricSubsModCfmIe->id)
6001                {
6002                   case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List:
6003                      {
6004                         modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List;
6005                         if(modCfmList->list.array)
6006                         {
6007                            for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
6008                            {
6009                               if(modCfmList->list.array[arrIdx])
6010                                  free(modCfmList->list.array[arrIdx]);
6011                            }
6012                            free(modCfmList->list.array);
6013                         }
6014                         break;
6015                      }
6016
6017                   case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List:
6018                      {
6019                         modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List;
6020                         if(modRefusedList->list.array)
6021                         {
6022                            for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
6023                            {
6024                               if(modRefusedList->list.array[arrIdx])
6025                                  free(modRefusedList->list.array[arrIdx]);
6026                            }
6027                            free(modRefusedList->list.array);
6028                         }
6029                         break;
6030                      }
6031
6032                   case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List:
6033                      {
6034                         rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List;
6035                         if(rmvCfmList->list.array)
6036                         {
6037                            for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
6038                            {
6039                               if(rmvCfmList->list.array[arrIdx])
6040                                  free(rmvCfmList->list.array[arrIdx]);
6041                            }
6042                            free(rmvCfmList->list.array);
6043                         }
6044                         break;
6045                      }
6046
6047                   case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List:
6048                      {
6049                         rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List;
6050                         if(rmvFailList->list.array)
6051                         {
6052                            for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
6053                            {
6054                               if(rmvFailList->list.array[arrIdx])
6055                                  free(rmvFailList->list.array[arrIdx]);
6056                            }
6057                            free(rmvFailList->list.array);
6058                         }
6059                         break;
6060                      }
6061
6062                   default:
6063                      break;
6064
6065                }
6066                free(ricSubsModCfmIe);
6067             }
6068          }
6069          free(ricSubsModCfm->protocolIEs.list.array);
6070       }
6071    }
6072 }
6073
6074 /*******************************************************************
6075  *
6076  * @brief Process RIC Subscription Modification Confirm Message
6077  *
6078  * @details
6079  *
6080  *    Function : procRicSubscriptionModificationConfirm
6081  *
6082  * Functionality:  Process RIC Subscription Modification Confirm
6083  *    Message received from RIC. 
6084  *
6085  * @param  E2AP Message PDU
6086  * @return void
6087  *
6088  ******************************************************************/
6089 void procRicSubscriptionModificationConfirm(E2AP_PDU_t *e2apMsg)
6090 {
6091    uint8_t actionId = 0, ieIdx = 0, arrIdx = 0;
6092    uint16_t ranFuncId = 0;
6093    bool procFailure = false;
6094    RicRequestId ricReqId;
6095    RanFunction *ranFuncDb = NULLP;
6096    CmLList *ricSubsNode = NULLP;
6097    RicSubscription *ricSubsDb = NULLP;
6098    ActionInfo *actionDb = NULLP;
6099
6100    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
6101    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
6102
6103    RICactions_ConfirmedForModification_List_t *modCfmList = NULLP;
6104    RICaction_ConfirmedForModification_ItemIEs_t *modCfmListItem = NULLP;
6105
6106    RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP;
6107    RICaction_RefusedToBeModified_ItemIEs_t *modRefusedListItem = NULLP;
6108
6109    RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP;
6110    RICaction_ConfirmedForRemoval_ItemIEs_t *rmvCfmListItem = NULLP;
6111
6112    RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP;
6113    RICaction_RefusedToBeRemoved_ItemIEs_t *rmvFailListItem = NULLP;
6114
6115    DU_LOG("\nINFO   -->  E2AP : %s: Received RIC Subscription Modification Confirm", __func__);
6116
6117    do{
6118       if(!e2apMsg)
6119       {
6120          DU_LOG("\nERROR  -->  E2AP : %s: E2AP Message is NULL", __func__);
6121          break;
6122       }
6123
6124       if(!e2apMsg->choice.successfulOutcome)
6125       {
6126          DU_LOG("\nERROR  -->  E2AP : %s: Successful Outcome in E2AP message is NULL", __func__);
6127          break;
6128       }
6129
6130       ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
6131       if(!ricSubsModCfm->protocolIEs.list.array)
6132       {
6133          DU_LOG("\nERROR  -->  E2AP : %s: Array conatining E2AP message IEs is null", __func__);
6134          break;
6135       }
6136
6137       for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++)
6138       {
6139          if(!ricSubsModCfm->protocolIEs.list.array[ieIdx])
6140          {
6141             DU_LOG("\nERROR  -->  E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx);
6142             break;
6143          }
6144
6145          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
6146          switch(ricSubsModCfmIe->id)
6147          {
6148             case ProtocolIE_IDE2_id_RICrequestID:
6149                {
6150                   memset(&ricReqId, 0, sizeof(RicRequestId));
6151                   ricReqId.requestorId = ricSubsModCfmIe->value.choice.RICrequestID.ricRequestorID;
6152                   ricReqId.instanceId = ricSubsModCfmIe->value.choice.RICrequestID.ricInstanceID;
6153                   break;
6154                }
6155
6156             case ProtocolIE_IDE2_id_RANfunctionID:
6157                {
6158                   ranFuncId = ricSubsModCfmIe->value.choice.RANfunctionID;
6159                   ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
6160                   if(!ranFuncDb)
6161                   {
6162                      DU_LOG("\nERROR  -->  E2AP : %s: RAN Function ID [%d] not found", __func__, ranFuncId);
6163                      procFailure = true;
6164                      break;
6165                   }
6166
6167                   ricSubsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode); 
6168                   if(!ricSubsDb)
6169                   {
6170                      DU_LOG("\nERROR  -->  E2AP : %s: RIC Subscription not found for Requestor_ID [%d] Instance_ID [%d]",\
6171                            __func__, ricReqId.requestorId, ricReqId.instanceId);
6172                      procFailure = true;
6173                      break;
6174                   }
6175
6176                   break;
6177                }
6178
6179 /* A RIC Subscription includes RIC subsequent action only for RIC Insert service. 
6180  * However, E2SM-KPM supports only RIC Report service. 
6181  * Hence there is no subsequent action in RIC subscription that may require modification. 
6182  * So commenting the action-modification IEs for the time being 
6183  */
6184 #if 0
6185             case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List:
6186                {
6187                   modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List;
6188                   for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
6189                   {
6190                      modCfmListItem = (RICaction_ConfirmedForModification_ItemIEs_t *)modCfmList->list.array[arrIdx];
6191                      actionId = modCfmListItem->value.choice.RICaction_ConfirmedForModification_Item.ricActionID;
6192
6193                      actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6194                      if(!actionDb)
6195                      {
6196                         DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6197                      }
6198                      else
6199                      {
6200                         actionDb->action = CONFIG_UNKNOWN;
6201                         /* Further handling can be added here in future once the
6202                          * use case of this procedure is identified */
6203                      }
6204                      actionDb = NULLP;
6205                   }
6206                   break;
6207                }
6208
6209             case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List:
6210                {
6211                   modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List;
6212                   for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
6213                   {
6214                     modRefusedListItem = (RICaction_RefusedToBeModified_ItemIEs_t *)modRefusedList->list.array[arrIdx];
6215                     actionId = modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.ricActionID;
6216                     actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6217                     if(!actionDb)
6218                     {
6219                        DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6220                     }
6221                     else
6222                     {
6223                        /* Spec doesnt mention if in case of failure, DU should retry for modify action 
6224                         * Hence, chaging the action from CONFIG_MOD to CONFIG_UNKNOWN
6225                         */
6226                         actionDb->action = CONFIG_UNKNOWN;
6227                     }
6228                     actionDb = NULLP;
6229                   }
6230                   break;
6231                }
6232 #endif
6233
6234             case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List:
6235                {
6236                   rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List;
6237                   for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
6238                   {
6239                      rmvCfmListItem = (RICaction_ConfirmedForRemoval_ItemIEs_t *)rmvCfmList->list.array[arrIdx];
6240                      actionId = rmvCfmListItem->value.choice.RICaction_ConfirmedForRemoval_Item.ricActionID;
6241                      actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6242                      if(!actionDb)
6243                      {
6244                         DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6245                      }
6246                      else
6247                      {
6248                         deleteActionSequence(actionDb);
6249                         actionDb =NULLP;
6250                         ricSubsDb->numOfActions--;
6251                         /* Further handling can include :
6252                          * Deletion of this action from all DU layers 
6253                          */
6254                      }
6255                      actionDb = NULLP;
6256                   }
6257                   break;
6258                }
6259
6260             case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List:
6261                {
6262                   rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List;
6263                   for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
6264                   {
6265                      rmvFailListItem = (RICaction_RefusedToBeRemoved_ItemIEs_t *)rmvFailList->list.array[arrIdx];
6266                      actionId = rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.ricActionID;
6267                      actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6268                      if(!actionDb)
6269                      {
6270                         DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6271                      }
6272                      else
6273                      {
6274                         actionDb->action = CONFIG_UNKNOWN;
6275                      }
6276                      actionDb = NULLP;
6277                   }
6278                   break;
6279                }
6280
6281             default:
6282                break;
6283          } /* End of switch for Protocol IE Id */
6284
6285          if(procFailure)
6286             break;
6287       } /* End of for loop for Protocol IE list */
6288
6289       break;
6290    }while(true);
6291
6292    freeAperDecodingOfRicSubsModConfirm(e2apMsg);
6293    return;
6294 }
6295
6296 /******************************************************************
6297 * @brief Deallocate the memory allocated for E2 Reset Response
6298 *
6299 * @details
6300 *
6301 *    Function : FreeE2ResetResponse
6302 *
6303 *    Functionality:
6304 *       - freeing the memory allocated for E2ResetResponse
6305 *
6306 * @params[in] E2AP_PDU_t *e2apMsg
6307 * @return ROK     - success
6308 *         RFAILED - failure
6309 *
6310 * ****************************************************************/
6311 void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg)
6312 {
6313    uint8_t ieIdx =0;
6314    ResetResponseE2_t *resetResponse;
6315
6316    if(e2apMsg != NULLP)
6317    {
6318       if(e2apMsg->choice.successfulOutcome != NULLP)
6319       {
6320          resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
6321          if(resetResponse->protocolIEs.list.array)
6322          {
6323             for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
6324             {
6325                if(resetResponse->protocolIEs.list.array[ieIdx])
6326                {
6327                   DU_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
6328                }
6329             }
6330             DU_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
6331          }
6332
6333          DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
6334       }
6335       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
6336    }
6337 }
6338
6339 /*******************************************************************
6340  *
6341  * @brief Buld and send the E2 Reset Response msg
6342  *
6343  * @details
6344  *
6345  *    Function : BuildAndSendE2ResetResponse
6346  *
6347  *    Functionality:
6348  *         - Buld and send the E2 Reset Response Message
6349  *
6350  * @params[in] Trans Id
6351  * @return ROK     - success
6352  *         RFAILED - failure
6353  *
6354  * ****************************************************************/
6355 uint8_t BuildAndSendResetResponse(uint8_t transId)
6356 {
6357    uint8_t           ieIdx = 0, elementCnt = 0;
6358    uint8_t           ret = RFAILED;
6359    E2AP_PDU_t        *e2apMsg = NULLP;
6360    ResetResponseE2_t *resetResponse;
6361    asn_enc_rval_t    encRetVal;       /* Encoder return value */
6362
6363    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
6364    do
6365    {
6366       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
6367       if(e2apMsg == NULLP)
6368       {
6369          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
6370          break;
6371       }
6372       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
6373
6374       DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
6375       if(e2apMsg->choice.successfulOutcome == NULLP)
6376       {
6377          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
6378          break;
6379       }
6380
6381       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
6382       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
6383       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
6384       resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
6385
6386       elementCnt = 1;
6387       resetResponse->protocolIEs.list.count = elementCnt;
6388       resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
6389       DU_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
6390       if(!resetResponse->protocolIEs.list.array)
6391       {
6392          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
6393          break;
6394       }
6395
6396       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
6397       {
6398          DU_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
6399          if(!resetResponse->protocolIEs.list.array[ieIdx])
6400          {
6401             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
6402             break;
6403          }
6404       }
6405       if(ieIdx < elementCnt)
6406          break;
6407
6408       ieIdx = 0;
6409       resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
6410       resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6411       resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
6412       resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
6413
6414       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6415
6416       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6417       encBufSize = 0;
6418       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6419       if(encRetVal.encoded == ENCODE_FAIL)
6420       {
6421          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
6422                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6423          break;
6424       }
6425       else
6426       {
6427          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
6428          for(int i=0; i< encBufSize; i++)
6429          {
6430             DU_LOG("%x",encBuf[i]);
6431          }
6432       }
6433
6434       /* Sending msg */
6435       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
6436       {
6437          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
6438          break;
6439       }
6440
6441       ret = ROK;
6442       break;
6443    }while(true);
6444
6445    FreeE2ResetResponse(e2apMsg);
6446    return ret;
6447 }
6448
6449 /******************************************************************
6450  *
6451  * @brief Deallocation of memory allocated by aper decoder for reset req
6452  *
6453  * @details
6454  *
6455  *    Function : freeAperDecodingOfE2ResetReq
6456  *
6457  *    Functionality: Deallocation of memory allocated by aper decoder for
6458  *    reset req
6459  *
6460  * @params[in] Pointer to resetReq
6461  * @return void
6462  *
6463  * ****************************************************************/
6464 void freeAperDecodingOfE2ResetReq(ResetRequestE2_t *resetReq)
6465 {
6466    uint8_t arrIdx=0;
6467
6468    if(resetReq)
6469    {
6470       if(resetReq->protocolIEs.list.array)
6471       {
6472          for(arrIdx=0; arrIdx<resetReq->protocolIEs.list.count; arrIdx++)
6473          {
6474             if(resetReq->protocolIEs.list.array[arrIdx])
6475             {
6476                free(resetReq->protocolIEs.list.array[arrIdx]);
6477             }
6478          }
6479          free(resetReq->protocolIEs.list.array);
6480       }
6481    }
6482 }
6483
6484 /*******************************************************************
6485  *
6486  * @brief Process reset req received from RIC
6487  *
6488  * @details
6489  *
6490  *    Function : procE2ResetRequest
6491  *
6492  * Functionality: Process reset req received from RIC
6493  *
6494  * @param  E2AP_PDU_t  *e2apMsg
6495  * @return void
6496  *
6497  ******************************************************************/
6498
6499 void procE2ResetRequest(E2AP_PDU_t  *e2apMsg)
6500 {
6501    uint16_t ranFuncIdx=0;
6502    uint8_t arrIdx =0, transId =0;
6503    ResetRequestE2_t *resetReq;
6504
6505    DU_LOG("\nINFO   -->  E2AP : E2 Reset request received");
6506    resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
6507
6508    for(arrIdx=0; arrIdx<resetReq->protocolIEs.list.count; arrIdx++)
6509    {
6510       switch(resetReq->protocolIEs.list.array[arrIdx]->id)
6511       {
6512          case ProtocolIE_IDE2_id_TransactionID:
6513             {
6514                transId = resetReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
6515                break;
6516             }
6517
6518          case ProtocolIE_IDE2_id_CauseE2:
6519             {
6520                for(ranFuncIdx=0; ranFuncIdx<MAX_RAN_FUNCTION; ranFuncIdx++)
6521                {
6522                   if(duCb.e2apDb.ranFunction[ranFuncIdx].id >0)
6523                   {
6524                      deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList));
6525                      memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo));
6526                   }
6527                }
6528                break;
6529             }
6530       }
6531    }
6532    if(BuildAndSendResetResponse(transId) != ROK)
6533    {
6534       DU_LOG("\nERROR  -->  E2AP : Failed to build and send reset response");
6535    }
6536    freeAperDecodingOfE2ResetReq(resetReq);
6537 }
6538
6539 /*******************************************************************
6540  *
6541  * @brief Handles received E2AP message and sends back response  
6542  *
6543  * @details
6544  *
6545  *    Function : E2APMsgHdlr
6546  *
6547  *    Functionality:
6548  *         - Decodes received E2AP control message
6549  *         - Prepares response message, encodes and sends to SCTP
6550  *
6551  * @params[in] 
6552  * @return ROK     - success
6553  *         RFAILED - failure
6554  *
6555  * ****************************************************************/
6556 void E2APMsgHdlr(Buffer *mBuf)
6557 {
6558    int i =0;
6559    char *recvBuf = NULLP;
6560    MsgLen copyCnt =0;
6561    MsgLen recvBufLen =0;
6562    E2AP_PDU_t *e2apMsg = NULLP;
6563    asn_dec_rval_t rval ={0}; /* Decoder return value */
6564    E2AP_PDU_t e2apasnmsg={0} ;
6565
6566    DU_LOG("\nDEBUG   -->  E2AP : Received E2AP message buffer");
6567    ODU_PRINT_MSG(mBuf, 0,0);
6568
6569    /* Copy mBuf into char array to decode it */
6570    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
6571    DU_ALLOC(recvBuf, (Size)recvBufLen);
6572
6573    if(recvBuf == NULLP)
6574    {
6575       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
6576       return;
6577    }
6578    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
6579    {
6580       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
6581       return;
6582    }
6583
6584 #ifdef DEBUG_ASN_PRINT
6585    printf("\nDEBUG   -->  E2AP : Received flat buffer to be decoded : ");
6586    for(i=0; i< recvBufLen; i++)
6587    {
6588       printf("%x",recvBuf[i]);
6589    }
6590 #endif
6591
6592    /* Decoding flat buffer into E2AP messsage */
6593    e2apMsg = &e2apasnmsg;
6594    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
6595
6596    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
6597    DU_FREE(recvBuf, (Size)recvBufLen);
6598
6599    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
6600    {
6601       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
6602       return;
6603    }
6604    printf("\n");
6605    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6606
6607    switch(e2apMsg->present)
6608    {
6609       case E2AP_PDU_PR_unsuccessfulOutcome:
6610          {
6611             switch(e2apMsg->choice.unsuccessfulOutcome->value.present)
6612             {
6613                case UnsuccessfulOutcomeE2__value_PR_E2setupFailure:
6614                   {
6615                      procE2SetupFailure(e2apMsg);
6616                      break;
6617                   }
6618                case UnsuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateFailure:
6619                   {
6620                      procE2NodeConfigUpdateFailure(e2apMsg);
6621                      break;
6622                   }
6623                case UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure:
6624                   {
6625                      procRicServiceUpdateFailure(e2apMsg);
6626                      break;
6627                   }
6628                default:
6629                   {
6630                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome  [%d]",\
6631                            e2apMsg->choice.unsuccessfulOutcome->value.present);
6632                      return;
6633                   }
6634             }
6635             free(e2apMsg->choice.unsuccessfulOutcome);
6636             break;
6637          }
6638       case E2AP_PDU_PR_successfulOutcome:
6639          {
6640             switch(e2apMsg->choice.successfulOutcome->value.present)
6641             {
6642                case SuccessfulOutcomeE2__value_PR_E2setupResponse:
6643                   {
6644                      if(!duCb.e2Status)
6645                      {
6646                         procE2SetupRsp(e2apMsg);
6647                      }
6648                      break;
6649                   }
6650                case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge:
6651                   {
6652                      DU_LOG("\nDEBUG   -->  E2AP : E2 node Config update ack message recevied");
6653                      break;
6654                   }
6655                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
6656                   {
6657                      procResetResponse(e2apMsg);
6658                      break;
6659                   }
6660                case SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge:
6661                   {
6662                      procRicServiceUpdateAck(e2apMsg);
6663                      break;
6664                   }
6665                case SuccessfulOutcomeE2__value_PR_RICsubscriptionModificationConfirm:
6666                   {
6667                      procRicSubscriptionModificationConfirm(e2apMsg);
6668                      break;
6669                   }
6670
6671                default:
6672                   {
6673                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome  [%d]",\
6674                            e2apMsg->choice.successfulOutcome->value.present);
6675                      return;
6676                   }
6677             }/* End of switch(successfulOutcome) */
6678             free(e2apMsg->choice.successfulOutcome);
6679             break;
6680          }
6681
6682       case E2AP_PDU_PR_initiatingMessage:
6683          {
6684             switch(e2apMsg->choice.initiatingMessage->value.present)
6685             {
6686                case InitiatingMessageE2__value_PR_RICsubscriptionRequest: 
6687                   {
6688                      procRicSubscriptionRequest(e2apMsg);
6689                      break;
6690                   }
6691                case InitiatingMessageE2__value_PR_RICserviceQuery:
6692                   {
6693                      procRicServiceQuery(e2apMsg);
6694                      break;
6695                   }
6696                case InitiatingMessageE2__value_PR_ErrorIndicationE2:
6697                   {
6698                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
6699                      break;
6700                   }
6701                case InitiatingMessageE2__value_PR_ResetRequestE2:
6702                   {
6703                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
6704                      procE2ResetRequest(e2apMsg);
6705                      break;
6706                   }
6707                default:
6708                   {
6709                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\
6710                            e2apMsg->choice.initiatingMessage->value.present);
6711                      return;
6712                   }
6713             }/* End of switch(initiatingMessage) */
6714             free(e2apMsg->choice.initiatingMessage);
6715             break;
6716          }
6717       default:
6718          {
6719             DU_LOG("\nERROR  -->  E2AP : Invalid type of e2apMsg->present [%d]",e2apMsg->present);
6720             return;
6721          }
6722          free(e2apMsg);
6723
6724    }/* End of switch(e2apMsg->present) */
6725
6726 } /* End of E2APMsgHdlr */
6727
6728 /**********************************************************************
6729   End of file
6730  **********************************************************************/