291fbe52cbf708bc19d8a596a551ef7606fdd3bf
[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          while(measInfoSubscribedList->count)
2564          {
2565             measToDelNode = cmLListDelFrm(measInfoSubscribedList, measInfoSubscribedList->first);
2566             measInfoToDel = (MeasurementInfo*)measToDelNode->node;
2567             DU_FREE(measInfoToDel, sizeof(MeasurementInfo));
2568             DU_FREE(measToDelNode, sizeof(CmLList));
2569          }
2570          break;
2571       }
2572
2573    } /* End of for loop , traversing measurement-to-be-subscribed list */
2574
2575    /* If all measurement-to-be-subscribed was found in measurement-supported list and 
2576     * was added to measurement-subscription list successfully, return from here */
2577    if(measInfoToBeSubscribedList->list.count == measInfoSubscribedList->count)
2578       return ROK;
2579
2580    return RFAILED;
2581 }
2582
2583 /*******************************************************************
2584  *
2585  * @brief Extract E2SM-KPM Action definition
2586  *
2587  * @details
2588  *
2589  *    Function : extractRicActionDef
2590  *
2591  * Functionality : This function :
2592  *     - Decodes E2SM-KPM Action Definition
2593  *     - Validates that action is supported by E2 node
2594  *     - Stores action details in local DB
2595  *
2596  * @params[in] RAN Function Database structure
2597  *             RIC subscription's Action definition to be added to 
2598  *                RAN function
2599  *             RIC Action Definition buffer received from RIC
2600  * @return ROK     - success
2601  *         RFAILED - failure
2602  *
2603  ******************************************************************/
2604 uint8_t extractRicActionDef(RanFunction *ranFuncDb, ActionDefinition *actionDefDb, RICactionDefinition_t *ricActionDef,\
2605    E2FailureCause *failureCause)
2606 {
2607    bool memFailure = false;
2608    uint8_t styleIdx = 0;
2609    asn_dec_rval_t rval ={0};
2610
2611    E2SM_KPM_ActionDefinition_t actionDef, *actionDefPtr = NULLP;
2612    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
2613    CmLListCp *measInfoSupportedList = NULLP;
2614    CmLListCp *measInfoSubscribedList = NULLP;
2615
2616    /* Decoding E2SM-KPM Action Definition */
2617    actionDefPtr = &actionDef;
2618    memset(actionDefPtr, 0, sizeof(E2SM_KPM_EventTriggerDefinition_t));
2619
2620    rval = aper_decode(0, &asn_DEF_E2SM_KPM_ActionDefinition, (void **)&actionDefPtr, ricActionDef->buf,\
2621          ricActionDef->size, 0, 0);
2622    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
2623    {
2624       DU_LOG("\nERROR  -->  E2AP : ASN decode failed for E2SM-KPM Action Definition");
2625       failureCause->causeType = E2_PROTOCOL;
2626       failureCause->cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE;
2627       return RFAILED;
2628    }
2629    printf("\n");
2630    xer_fprint(stdout, &asn_DEF_E2SM_KPM_ActionDefinition, actionDefPtr);
2631
2632
2633    /* Validate if Report style to subscribe is supported by E2 Node */
2634    for(styleIdx= 0; styleIdx < ranFuncDb->numOfReportStyleSupported; styleIdx++)
2635    {
2636       /* Validate Report style type and report style format type is supported by E2 Node */
2637       if((ranFuncDb->reportStyleList[styleIdx].reportStyle.styleType == actionDefPtr->ric_Style_Type) &&
2638             (ranFuncDb->reportStyleList[styleIdx].reportStyle.formatType == actionDefPtr->actionDefinition_formats.present))
2639       {
2640          /* Fetch Report stype type and format type */
2641          actionDefDb->styleType = actionDefPtr->ric_Style_Type;
2642          actionDefDb->formatType = actionDefPtr->actionDefinition_formats.present;
2643
2644          switch(actionDefPtr->actionDefinition_formats.present)
2645          {
2646             case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
2647                {
2648                   actionFormat1 = actionDefPtr->actionDefinition_formats.choice.actionDefinition_Format1; 
2649
2650                   /* Fetch granularity period */
2651                   actionDefDb->choice.format1.granularityPeriod = actionFormat1->granulPeriod;
2652
2653                   /* Validate and add the Measurement to subscription list */
2654                   measInfoSupportedList = &ranFuncDb->reportStyleList[styleIdx].measurementInfoList;
2655                   measInfoSubscribedList = &actionDefDb->choice.format1.measurementInfoList;
2656                   if(extractMeasInfoList(measInfoSupportedList, &actionFormat1->measInfoList, \
2657                      measInfoSubscribedList, &memFailure) == ROK)
2658                   {
2659                      if(!memFailure)
2660                      {
2661                         /* Free E2SM_KPM_ActionDefinition_t */
2662                         freeAperDecodingOfRicActionDefinition(actionDefPtr);
2663                         return ROK;
2664                      }
2665                   }
2666
2667                   break;  /* End of E2SM-KPM Action definition format 1 case */
2668                }
2669
2670             default :
2671                {
2672                   DU_LOG("\nERROR  ->  DUAPP: Only E2SM-KPM Action Definition Format 1 is supported");
2673                   break;
2674                }
2675          } /* End of switch for E2SM-KPM Action definition formats */
2676       }
2677
2678       if(memFailure)
2679       {
2680          failureCause->causeType = E2_MISCELLANEOUS;
2681          failureCause->cause = E2_MISCELLANEOUS_CAUSE_UNSPECIFIED; 
2682          break;
2683       }
2684    } /* End of for loop, traversing Report-styles-supported list in E2 node */
2685
2686    /* Memset action Db and Free E2SM_KPM_ActionDefinition_t */
2687    memset(actionDefDb, 0, sizeof(ActionDefinition));
2688    freeAperDecodingOfRicActionDefinition(actionDefPtr);
2689
2690    if(failureCause->causeType == E2_NOTHING)
2691    {
2692       failureCause->causeType = E2_RIC_REQUEST;
2693       failureCause->cause = E2_ACTION_NOT_SUPPORTED;
2694    }
2695    return RFAILED;
2696 }
2697
2698 /*******************************************************************
2699  *
2700  * @brief Extract RIC Action to be setup
2701  *
2702  * @details
2703  *
2704  *    Function : extractRicActionToBeSetup
2705  *
2706  * Functionality : This function :
2707  *     - Validates that each action-to-be-setup is supported by E2 node
2708  *     - Stores event trigger details in local DB
2709  *
2710  * @params[in] RAN Function Database structure
2711  *             RIC Subscription Info to be added to RAN function
2712  *             RIC Action To Be Setup List received from RIC
2713  * @return ROK     - success
2714  *         RFAILED - failure
2715  *
2716  ******************************************************************/
2717 uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \
2718    RICactions_ToBeSetup_List_t *actionList, E2FailureCause *failureCause, PendingSubsRspInfo *subsRsp)
2719 {
2720    uint8_t actionIdx = 0;
2721    uint8_t ricActionId = 0;
2722    RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
2723
2724    if(actionList->list.array)
2725    {
2726       for(actionIdx = 0; actionIdx < actionList->list.count; actionIdx++)
2727       {
2728          actionItem =(RICaction_ToBeSetup_ItemIEs_t *)actionList->list.array[actionIdx];
2729          switch(actionItem->id)
2730          {
2731             case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item:
2732                {
2733                   /* If Action type is REPORT and 
2734                    * If RIC action definition's extraction and validation passes, 
2735                    * Then : 
2736                    * This action is added to action sequence list of subscription info */
2737                   ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
2738
2739                   if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType == RICactionType_report)
2740                   {
2741                      ricSubscriptionInfo->actionSequence[ricActionId].actionId = ricActionId;
2742                      ricSubscriptionInfo->actionSequence[ricActionId].type = REPORT;
2743
2744                      if(extractRicActionDef(ranFuncDb, &ricSubscriptionInfo->actionSequence[ricActionId].definition, \
2745                         actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, failureCause) == ROK)
2746                      {
2747                         ricSubscriptionInfo->actionSequence[ricActionId].action = CONFIG_ADD;
2748                         ricSubscriptionInfo->numOfActions++;
2749                         break;
2750                      }
2751                   }
2752
2753                   /* In case of any failure, action is rejected
2754                    * Added to rejected-action-list in subscription response */
2755                   memset(&ricSubscriptionInfo->actionSequence[ricActionId], 0, sizeof(ActionInfo));
2756                   ricSubscriptionInfo->actionSequence[ricActionId].actionId = -1;
2757
2758                   subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].id = ricActionId;
2759                   if(failureCause->causeType == E2_NOTHING)
2760                   {
2761                      failureCause->causeType = E2_RIC_REQUEST;
2762                      failureCause->cause = E2_ACTION_NOT_SUPPORTED;
2763                   }
2764                   memcpy(&subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].failureCause, \
2765                         failureCause, sizeof(E2FailureCause));
2766                   subsRsp->numOfRejectedActions++;
2767                   break;
2768                }
2769             default:
2770                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id);
2771                break;
2772          }
2773       }
2774    }
2775
2776    /* If there is even 1 action that can be added, return ROK */
2777    if(ricSubscriptionInfo->numOfActions)
2778       return ROK;
2779
2780    if(failureCause->causeType == E2_NOTHING)
2781    {
2782       failureCause->causeType = E2_RIC_REQUEST;
2783       failureCause->cause = E2_ACTION_NOT_SUPPORTED;
2784    }
2785    return RFAILED;
2786 }
2787
2788 /******************************************************************
2789  *
2790  * @brief Processes RIC Subscription Req sent by RIC
2791  *
2792  * @details
2793  *
2794  *    Function : procRicSubscriptionRequest
2795  *
2796  *    Functionality: Processes RIC Subscription Request from RIC
2797  *
2798  * @params[in] E2AP_PDU_t ASN decoded E2AP message
2799  * @return ROK     - success
2800  *         RFAILED - failure
2801  *
2802  * ****************************************************************/
2803 uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg)
2804 {
2805    uint8_t idx = 0, actionIdx = 0; 
2806    uint8_t ret = ROK;
2807    uint16_t ranFuncId = 0;
2808    RicRequestId ricReqId;
2809    CmLList  *ricSubscriptionNode = NULLP;
2810    RanFunction *ranFuncDb = NULLP;
2811    RICsubscriptionRequest_t *ricSubsReq = NULLP;
2812    RICsubscriptionDetails_t *subsDetails = NULLP;
2813    RicSubscription *ricSubscriptionInfo = NULLP;
2814    E2FailureCause failureCause;
2815
2816    DU_LOG("\nINFO   -->  E2AP : RIC Subscription request received"); 
2817
2818    memset(&failureCause, 0, sizeof(E2FailureCause));
2819    memset(&ricReqId, 0, sizeof(RicRequestId));
2820
2821    ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
2822    for(idx=0; idx<ricSubsReq->protocolIEs.list.count; idx++)
2823    {
2824       if(ricSubsReq->protocolIEs.list.array[idx])
2825       {
2826          switch(ricSubsReq->protocolIEs.list.array[idx]->id)
2827          {
2828             case ProtocolIE_IDE2_id_RICrequestID:
2829                {
2830                   ricReqId.requestorId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID;
2831                   ricReqId.instanceId  = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID;
2832
2833                   break;
2834                }
2835
2836             case ProtocolIE_IDE2_id_RANfunctionID:
2837                {
2838                   ranFuncId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID; 
2839
2840                   /* Validating RAN Function id */
2841                   ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
2842
2843                   if(!ranFuncDb)
2844                   {
2845                      failureCause.causeType = E2_RIC_REQUEST;
2846                      failureCause.cause = E2_RAN_FUNCTION_ID_INVALID;
2847                      ret = RFAILED;
2848                      break;
2849                   }
2850
2851                   if(ranFuncDb->numPendingSubsRsp >= MAX_PENDING_SUBSCRIPTION_RSP)
2852                   {
2853                      failureCause.causeType = E2_RIC_REQUEST;
2854                      failureCause.cause = E2_FUNCTION_RESOURCE_LIMIT; 
2855                      ret = RFAILED;
2856                      break;
2857                   }
2858
2859                   DU_ALLOC(ricSubscriptionInfo, sizeof(RicSubscription));
2860                   if(!ricSubscriptionInfo)
2861                   {
2862                      DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for ricSubscriptionInfo");
2863                      failureCause.causeType = E2_MISCELLANEOUS;
2864                      failureCause.cause = E2_MISCELLANEOUS_CAUSE_UNSPECIFIED;
2865                      ret = RFAILED;
2866                      break;
2867                   }
2868                   ricSubscriptionInfo->requestId.requestorId = ricReqId.requestorId;
2869                   ricSubscriptionInfo->requestId.instanceId = ricReqId.instanceId;
2870                   ricSubscriptionInfo->ranFuncId = ranFuncId;
2871
2872                   for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
2873                   {
2874                      ricSubscriptionInfo->actionSequence[actionIdx].actionId = -1;
2875                   }
2876
2877                   memset(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp], 0, sizeof(PendingSubsRspInfo));
2878                   memcpy(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp].requestId, 
2879                         &ricReqId, sizeof(RicRequestId));
2880                   ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp].ranFuncId = ranFuncId;
2881                   break;
2882                }
2883
2884             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
2885                {
2886                   subsDetails = &ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails;
2887
2888                   /* Decode, Validate and record Event Trigger Definition */
2889                   if(extractEventTriggerDef(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricEventTriggerDefinition, \
2890                      &failureCause) != ROK)
2891                   {
2892                      ret = RFAILED;
2893                      break;
2894                   }
2895
2896                   /* Decode, Validate and record RIC actions */
2897                   if(extractRicActionToBeSetup(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricAction_ToBeSetup_List, \
2898                      &failureCause, &ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp]) != ROK)
2899                   {
2900                      ret = RFAILED;
2901                      break;
2902                   }
2903                }
2904                break;
2905
2906             default:
2907                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RIC SubsReq:%ld",
2908                      ricSubsReq->protocolIEs.list.array[idx]->id);
2909                break;
2910          }
2911
2912          if(ret == RFAILED)
2913             break;
2914       }
2915    }
2916
2917    freeAperDecodingOfRicSubsReq(ricSubsReq);
2918
2919    if(ret == ROK)
2920    {
2921       cmInitTimers(&(ricSubscriptionInfo->ricSubsReportTimer), 1);
2922
2923       /* Add RAN subcription detail to RAN function */
2924       DU_ALLOC(ricSubscriptionNode, sizeof(CmLList));
2925       if(ricSubscriptionNode)
2926       {
2927          ricSubscriptionNode->node = (PTR) ricSubscriptionInfo;
2928          cmLListAdd2Tail(&ranFuncDb->subscriptionList, ricSubscriptionNode);
2929       }
2930
2931       ranFuncDb->numPendingSubsRsp++;
2932
2933 #ifdef KPI_CALCULATION
2934       /* Send statistics request to other DU entities */
2935       BuildAndSendStatsReq(ricSubscriptionInfo);
2936 #endif      
2937    }
2938    else
2939    {
2940       DU_FREE(ricSubscriptionInfo, sizeof(RicSubscription));
2941
2942       if(ranFuncDb)
2943       {
2944          memset(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp], 0, sizeof(PendingSubsRspInfo));
2945       }
2946
2947       /* Send RIC Subcription Failure */
2948       BuildAndSendRicSubscriptionFailure(ricReqId, ranFuncId, failureCause);
2949    }
2950
2951    return ret;
2952 }
2953
2954 /******************************************************************
2955  *
2956  * @brief Free RIC Subscription Failure
2957  *
2958  * @details
2959  *
2960  *    Function : FreeRicSubscriptionFailure
2961  *
2962  *    Functionality: Free RIC Subscription Failure
2963  *
2964  * @params[in] E2AP PDU
2965  * @return void
2966  *
2967  * ****************************************************************/
2968 void FreeRicSubscriptionFailure(E2AP_PDU_t *e2apMsg)
2969 {
2970    uint8_t elemIdx = 0;
2971    RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP;
2972
2973    if(e2apMsg)
2974    {
2975       if(e2apMsg->choice.unsuccessfulOutcome)
2976       {
2977          ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
2978          if(ricSubscriptionFailure->protocolIEs.list.array)
2979          {
2980             for(elemIdx = 0; elemIdx < ricSubscriptionFailure->protocolIEs.list.count; elemIdx++)
2981             {
2982                DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t));
2983             }
2984             DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size);
2985          }
2986          DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
2987       }
2988       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2989    }
2990 }
2991
2992 /******************************************************************
2993  *
2994  * @brief Fill and Send RIC Subscription Failure to RIC
2995  *
2996  * @details
2997  *
2998  *    Function : BuildAndSendRicSubscriptionFailure
2999  *
3000  *    Functionality: Fill and Send RIC Subscription Failure to RIC
3001  *
3002  * @params[in] RIC Request ID
3003  *             RAN Function ID
3004  *             Cause of Failure
3005  * @return ROK     - success
3006  *         RFAILED - failure
3007  *
3008  * ****************************************************************/
3009 uint8_t BuildAndSendRicSubscriptionFailure(RicRequestId ricReqId, uint16_t ranFuncId, E2FailureCause failureCause)
3010 {
3011    uint8_t          ret = RFAILED;
3012    uint8_t          elementCnt = 0, elemIdx = 0;
3013    E2AP_PDU_t       *e2apMsg = NULLP;
3014    asn_enc_rval_t   encRetVal;        /* Encoder return value */
3015    RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP;
3016    RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
3017
3018    while(true)
3019    {
3020       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Failure\n");
3021
3022       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3023       if(e2apMsg == NULLP)
3024       {
3025          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
3026          break;
3027       }
3028
3029       e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome;
3030       DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
3031       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
3032       {
3033          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
3034          break;
3035       }
3036       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
3037       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
3038       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure;
3039
3040       ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
3041
3042       elementCnt = 3;
3043       ricSubscriptionFailure->protocolIEs.list.count = elementCnt;
3044       ricSubscriptionFailure->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionFailure_IEs_t *);
3045       DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size);
3046       if(!ricSubscriptionFailure->protocolIEs.list.array)
3047       {
3048          DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); 
3049          break;
3050       }
3051
3052       for(elemIdx = 0; elemIdx < elementCnt; elemIdx++)
3053       {
3054          DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t));
3055          if(!ricSubscriptionFailure->protocolIEs.list.array[elemIdx])
3056          {
3057             DU_LOG("\nERROR  -->  E2AP : Memory allocation at [%s] : Line [%d] for IE at index [%d]", \
3058                __func__, __LINE__, elemIdx);
3059             break;
3060          }
3061       }
3062       if(elemIdx < elementCnt)
3063          break;
3064
3065       elemIdx = 0;
3066
3067       /* RIC Request ID */
3068       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
3069       ricSubsFailIe->id = ProtocolIE_IDE2_id_RICrequestID;
3070       ricSubsFailIe->criticality = CriticalityE2_reject;
3071       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RICrequestID;
3072       ricSubsFailIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
3073       ricSubsFailIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
3074
3075       /* RAN Function ID */
3076       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
3077       ricSubsFailIe->id = ProtocolIE_IDE2_id_RANfunctionID;
3078       ricSubsFailIe->criticality = CriticalityE2_reject;
3079       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RANfunctionID;
3080       ricSubsFailIe->value.choice.RANfunctionID = ranFuncId;
3081
3082       /* Cause */
3083       ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
3084       ricSubsFailIe->id = ProtocolIE_IDE2_id_CauseE2;
3085       ricSubsFailIe->criticality = CriticalityE2_reject;
3086       ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_CauseE2;
3087       fillE2Cause(&ricSubsFailIe->value.choice.CauseE2, failureCause);
3088
3089       /* Prints the Msg formed */
3090       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3091       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3092       encBufSize = 0;
3093       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3094       if(encRetVal.encoded == ENCODE_FAIL)
3095       {
3096          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Failure Message (at %s)\n",\
3097                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3098          break;
3099       }
3100       else
3101       {
3102          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Failure Message \n");
3103 #ifdef DEBUG_ASN_PRINT
3104          for(int i=0; i< encBufSize; i++)
3105          {
3106             printf("%x",encBuf[i]);
3107          }
3108 #endif
3109       }
3110
3111       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
3112       {
3113          DU_LOG("\nINFO   -->  E2AP : Sending RIC Subscription Failure");
3114
3115       }
3116       ret = ROK;
3117       break;
3118    }
3119    FreeRicSubscriptionFailure(e2apMsg);
3120    return ret;
3121 }
3122
3123 /*******************************************************************
3124  *
3125  * @brief Free the RicIndication Message
3126  *
3127  * @details
3128  *
3129  *    Function : FreeRicIndication
3130  *
3131  * Functionality: Free the RicIndication Message
3132  *
3133  * @return void
3134  *         
3135  *
3136  ******************************************************************/
3137 void FreeRicIndication(E2AP_PDU_t  *e2apMsg) 
3138 {
3139    uint8_t idx = 0;
3140    RICindication_t *ricIndicationMsg= NULLP;
3141
3142    if(e2apMsg != NULLP)
3143    {
3144       if(e2apMsg->choice.initiatingMessage != NULLP)
3145       {
3146          ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
3147          if(ricIndicationMsg!= NULLP)
3148          {
3149             if(ricIndicationMsg->protocolIEs.list.array != NULLP)
3150             {
3151                for(idx=0; idx<ricIndicationMsg->protocolIEs.list.count; idx++)
3152                {
3153                   if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP)
3154                   {
3155                      switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
3156                      {
3157                         case ProtocolIE_IDE2_id_RICrequestID:
3158                         case ProtocolIE_IDE2_id_RANfunctionID:
3159                         case ProtocolIE_IDE2_id_RICactionID:
3160                         case ProtocolIE_IDE2_id_RICindicationType:
3161                            break;
3162
3163                         case ProtocolIE_IDE2_id_RICindicationHeader:
3164                            {
3165                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\
3166                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
3167                               break;
3168                            }
3169                         case ProtocolIE_IDE2_id_RICindicationMessage:
3170                            {
3171                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\
3172                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
3173                               break;
3174                            }
3175                         default:
3176                            break;
3177                      }
3178                      DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t));
3179                   }
3180                }
3181                DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size);
3182             }
3183          }
3184          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3185       }
3186       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3187    }
3188 }
3189
3190 /*******************************************************************
3191  *
3192  * @brief Free measurement record
3193  *
3194  * @details
3195  *
3196  *    Function : freeMeasRecord
3197  *
3198  * Functionality: Free all measurement recorded for a measurement
3199  *    within an action in a RIC subscription
3200  *
3201  * @param  Measurement data to be freed
3202  * @return void
3203  *
3204  ******************************************************************/
3205 void freeMeasData(MeasurementData_t *measData)
3206 {
3207    uint8_t measIdx = 0, measRecIdx = 0;
3208    MeasurementRecord_t *measRecord = NULLP;
3209
3210    if(measData->list.array)
3211    {
3212       for(measIdx = 0; measIdx < measData->list.count; measIdx++)
3213       {
3214          if(measData->list.array[measIdx])
3215          {
3216             measRecord = &measData->list.array[measIdx]->measRecord;
3217             if(measRecord->list.array)
3218             {
3219                for(measRecIdx = 0; measRecIdx < measRecord->list.count; measRecIdx++)
3220                {
3221                   DU_FREE(measRecord->list.array[measRecIdx], sizeof(MeasurementRecordItem_t));
3222                }
3223                DU_FREE(measRecord->list.array, measRecord->list.size);
3224             }
3225             DU_FREE(measData->list.array[measIdx], sizeof(MeasurementDataItem_t));
3226          }
3227       }
3228       DU_FREE(measData->list.array, measData->list.size);
3229    }
3230 }
3231
3232 /*******************************************************************
3233  *
3234  * @brief Fill measurement info list
3235  *
3236  * @details
3237  *
3238  *    Function : freeMeasInfoList
3239  *
3240  * Functionality: Fills all measurement info within an action 
3241  *    in a RIC subscription
3242  *
3243  * @param  Measurement Info list to be freed
3244  * @return void
3245  *
3246  ******************************************************************/
3247 void freeMeasInfoList(MeasurementInfoList_t *measInfoList)
3248 {
3249    uint8_t measInfoIdx = 0;
3250
3251    if(measInfoList->list.array)
3252    {
3253       for(measInfoIdx = 0; measInfoIdx < measInfoList->list.count; measInfoIdx++)
3254       {
3255          if(measInfoList->list.array[measInfoIdx])
3256          {
3257             DU_FREE(measInfoList->list.array[measInfoIdx]->measType.choice.measName.buf, \
3258                   measInfoList->list.array[measInfoIdx]->measType.choice.measName.size);
3259
3260             DU_FREE(measInfoList->list.array[measInfoIdx], measInfoList->list.size);
3261          }
3262       }
3263       DU_FREE(measInfoList->list.array, measInfoList->list.size);
3264    }
3265 }
3266
3267 /*******************************************************************
3268  *
3269  * @brief Free E2SM-KPM Indication Message
3270  *
3271  * @details
3272  *
3273  *    Function : FreeE2smKpmIndicationMessage
3274  *
3275  * Functionality: Free E2SM-KPM Indication Message
3276  *
3277  * @param  E2SM-KPM Indication message to be freed
3278  * @return void
3279  *
3280  ******************************************************************/
3281 void FreeE2smKpmIndicationMessage(E2SM_KPM_IndicationMessage_t *e2smKpmIndMsg)
3282 {
3283    E2SM_KPM_IndicationMessage_Format1_t *format1Msg = NULLP;
3284
3285    switch(e2smKpmIndMsg->indicationMessage_formats.present)
3286    {
3287       case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format1:
3288          {
3289             if(e2smKpmIndMsg->indicationMessage_formats.choice.indicationMessage_Format1)
3290             {
3291                format1Msg = e2smKpmIndMsg->indicationMessage_formats.choice.indicationMessage_Format1;
3292                
3293                /* Measurement Data */
3294                freeMeasData(&format1Msg->measData);
3295
3296                /* Measurement Info List */
3297                if(format1Msg->measInfoList)
3298                {
3299                   freeMeasInfoList(format1Msg->measInfoList);
3300                   DU_FREE(format1Msg->measInfoList, sizeof(MeasurementInfoList_t));
3301                }
3302
3303                /* Granularity Period */
3304                DU_FREE(format1Msg->granulPeriod, sizeof(GranularityPeriod_t));
3305
3306                DU_FREE(format1Msg, sizeof(E2SM_KPM_IndicationMessage_Format1_t));
3307             }
3308             break;
3309          }
3310
3311       case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_NOTHING:
3312       case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format2:
3313       default:
3314          break;
3315    }
3316 }
3317
3318 /*******************************************************************
3319  *
3320  * @brief Fill measurement record
3321  *
3322  * @details
3323  *
3324  *    Function : fillMeasRecord
3325  *
3326  * Functionality: Fills all measurement value for a measurement
3327  *    within an action in a RIC subscription
3328  *
3329  * @param  Measurement record to be filled
3330  *         Measurement database with measurement records
3331  * @return ROK     - success
3332  *         RFAILED - failure
3333  *
3334  ******************************************************************/
3335 uint8_t fillMeasRecord(MeasurementRecord_t *measRecord, MeasurementInfo *measInfoDb)
3336 {
3337    uint8_t measRecIdx = 0;
3338    CmLList *measValNode = NULLP;
3339    double  measVal = 0;
3340
3341    measRecord->list.count = measInfoDb->measuredValue.count;
3342    measRecord->list.size = measRecord->list.count * sizeof(MeasurementRecordItem_t *);
3343
3344    DU_ALLOC(measRecord->list.array, measRecord->list.size);
3345    if(!measRecord->list.array)
3346    {
3347       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3348       return RFAILED;
3349    }
3350
3351    for(measRecIdx = 0; measRecIdx < measRecord->list.count; measRecIdx++)
3352    {
3353       DU_ALLOC(measRecord->list.array[measRecIdx], sizeof(MeasurementRecordItem_t));
3354       if(!measRecord->list.array[measRecIdx])
3355       {
3356          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3357          return RFAILED;
3358       }
3359    }
3360
3361    measRecIdx = 0;
3362    CM_LLIST_FIRST_NODE(&measInfoDb->measuredValue, measValNode);
3363    while(measValNode)
3364    {
3365      measVal = *(double *)measValNode->node;
3366      if(measVal == (int)measVal)
3367      {
3368         measRecord->list.array[measRecIdx]->present = MeasurementRecordItem_PR_integer;
3369         measRecord->list.array[measRecIdx]->choice.integer = (int)measVal;
3370      }
3371      else
3372      {
3373          measRecord->list.array[measRecIdx]->present = MeasurementRecordItem_PR_real;
3374          measRecord->list.array[measRecIdx]->choice.real = measVal;
3375      }
3376      measRecIdx++;
3377
3378      /* Once the measurement record is added to the message, delete it from DB */
3379      cmLListDelFrm(&measInfoDb->measuredValue, measValNode);
3380      DU_FREE(measValNode->node, sizeof(double));
3381      DU_FREE(measValNode, sizeof(CmLList));
3382
3383      CM_LLIST_FIRST_NODE(&measInfoDb->measuredValue, measValNode);
3384      measVal = 0;
3385    }
3386
3387    return ROK;
3388 }
3389
3390 /*******************************************************************
3391  *
3392  * @brief Fills measuerement data
3393  *
3394  * @details
3395  *
3396  *    Function : fillMeasData
3397  *
3398  * Functionality: Fill all measurement recorded for all measurements
3399  *    in an action in a RIC subscription
3400  *
3401  * @param  Measurement data to be filled
3402  *         Measurement info list from an action DB
3403  * @return ROK     - success
3404  *         RFAILED - failure
3405  *
3406  ******************************************************************/
3407 uint8_t fillMeasData(MeasurementData_t *measData, CmLListCp *measInfoListDb)
3408 {
3409   uint8_t measIdx = 0;
3410   CmLList *measInfoNode = NULLP;
3411   MeasurementInfo *measInfoDb = NULLP;
3412   MeasurementRecord_t *measRecord = NULLP;
3413
3414   measData->list.count = measInfoListDb->count;
3415   measData->list.size = measData->list.count * sizeof(MeasurementDataItem_t *);
3416
3417   DU_ALLOC(measData->list.array, measData->list.size);
3418   if(!measData->list.array)
3419   {
3420      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3421      return RFAILED;
3422   }
3423
3424   measIdx = 0;
3425   CM_LLIST_FIRST_NODE(measInfoListDb, measInfoNode);
3426   while(measInfoNode)
3427   {
3428      measInfoDb = (MeasurementInfo *)measInfoNode->node;
3429      if(measInfoDb)
3430      {
3431         DU_ALLOC(measData->list.array[measIdx], sizeof(MeasurementDataItem_t));
3432         if(!measData->list.array[measIdx])
3433         {
3434            DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3435            return RFAILED;
3436         }
3437
3438         measRecord = &measData->list.array[measIdx]->measRecord;
3439         if(fillMeasRecord(measRecord, measInfoDb) != ROK)
3440         {
3441            DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement record");
3442            return RFAILED;
3443         }
3444         measIdx++;
3445      }
3446      measInfoNode = measInfoNode->next;
3447   }
3448
3449   return ROK;
3450 }
3451
3452 /*******************************************************************
3453  *
3454  * @brief Fill all measurement info
3455  *
3456  * @details
3457  *
3458  *    Function : fillMeasInfoList
3459  *
3460  * Functionality: Fills all measurement info belonging to an action
3461  *  in a RIC subscription
3462  *
3463  * @param   Measurement Info list to be filled
3464  *          Measurement Info list from E2AP DB
3465  * @return ROK     - success
3466  *         RFAILED - failure
3467  *
3468  ******************************************************************/
3469 uint8_t fillMeasInfoList(MeasurementInfoList_t *measInfoList, CmLListCp *measInfoListDb)
3470 {
3471    uint8_t measInfoIdx = 0;
3472    CmLList *measInfoNode = NULLP;
3473    MeasurementInfo *measInfoDb = NULLP;
3474    MeasurementInfoItem_t *measInfoItem = NULLP;
3475
3476    measInfoList->list.count = measInfoListDb->count;
3477    measInfoList->list.size = measInfoList->list.count * sizeof(MeasurementInfoItem_t *);
3478
3479    DU_ALLOC(measInfoList->list.array, measInfoList->list.size);
3480    if(!measInfoList->list.array)
3481    {
3482       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3483       return RFAILED;
3484    }
3485
3486    measInfoIdx = 0;
3487    CM_LLIST_FIRST_NODE(measInfoListDb, measInfoNode);
3488    while(measInfoNode)
3489    {
3490       DU_ALLOC(measInfoList->list.array[measInfoIdx], sizeof(MeasurementInfoItem_t));
3491       if(!measInfoList->list.array[measInfoIdx])
3492       {
3493          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3494          return RFAILED;
3495       }
3496
3497       measInfoItem = measInfoList->list.array[measInfoIdx];
3498       measInfoDb = (MeasurementInfo *)measInfoNode->node;
3499       if(measInfoDb)
3500       {
3501          /* Measurement Type */
3502          measInfoItem->measType.present = MeasurementType_PR_measName;
3503          measInfoItem->measType.choice.measName.size = strlen(measInfoDb->measurementTypeName);
3504
3505          DU_ALLOC(measInfoItem->measType.choice.measName.buf, measInfoItem->measType.choice.measName.size);
3506          if(!measInfoItem->measType.choice.measName.buf)
3507          {
3508             DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3509             return RFAILED;
3510          }
3511
3512          memcpy(measInfoItem->measType.choice.measName.buf, measInfoDb->measurementTypeName,\
3513             measInfoItem->measType.choice.measName.size);
3514
3515          measInfoIdx++;
3516       }
3517       measInfoNode = measInfoNode->next;
3518       measInfoDb = NULLP;
3519    }
3520
3521    return ROK;
3522 }
3523
3524  /*******************************************************************
3525  *
3526  * @brief Fill E2SM-KPM Indication Message Format 1
3527  *
3528  * @details
3529  *
3530  *    Function : fillE2smKpmIndMsgFormat1
3531  *
3532  * Functionality: Fill E2SM-KPM Indication Message Format 1
3533  *
3534  * @param  Format 1 Message to be filled
3535  *         Action Definition format 1 from E2AP DB
3536  * @return ROK     - success
3537  *         RFAILED - failure
3538  *
3539  ******************************************************************/
3540 uint8_t fillE2smKpmIndMsgFormat1(E2SM_KPM_IndicationMessage_Format1_t *format1Msg, ActionDefFormat1 *format1)
3541 {
3542   /* Measurement Data */
3543   if(fillMeasData(&format1Msg->measData, &format1->measurementInfoList) != ROK)
3544   {
3545      DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement data");
3546      return RFAILED;
3547   }
3548
3549   /* Measurement Information */
3550   DU_ALLOC(format1Msg->measInfoList, sizeof(MeasurementInfoList_t));
3551   if(!format1Msg->measInfoList)
3552   {
3553      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3554      return RFAILED;
3555   }
3556
3557   if(fillMeasInfoList(format1Msg->measInfoList, &format1->measurementInfoList) != ROK)
3558   {
3559      DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement information list");
3560      return RFAILED;
3561   }
3562
3563   /* Granularity Period */
3564   DU_ALLOC(format1Msg->granulPeriod, sizeof(GranularityPeriod_t));
3565   if(!format1Msg->granulPeriod)
3566   {
3567      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3568      return RFAILED;
3569   }
3570   *(format1Msg->granulPeriod) = format1->granularityPeriod;
3571
3572   return ROK;
3573 }
3574
3575 /*******************************************************************
3576  *
3577  * @brief Fill RIC Indication Message buffer
3578  *
3579  * @details
3580  *
3581  *    Function : fillRicIndMsgBuf
3582  *
3583  * Functionality: Fill E2SM-KPM Indication Message
3584  *    Encode this message and copy to RIC Indication Message buffer
3585  * 
3586  * @param  RIC Indication Message buffer to be filled
3587  *         Source action info from E2AP DB
3588  * @return ROK     - success
3589  *         RFAILED - failure
3590  *
3591  ******************************************************************/
3592 uint8_t fillRicIndMsgBuf(RICindicationMessage_t *ricIndMsgBuf, ActionInfo *actionInfo)
3593 {
3594    uint8_t ret = RFAILED;
3595    bool failedInFormat = false;
3596    E2SM_KPM_IndicationMessage_t e2smKpmIndMsg;
3597    asn_enc_rval_t   encRetVal;        /* Encoder return value */
3598
3599    memset(&e2smKpmIndMsg, 0, sizeof(E2SM_KPM_IndicationMessage_t));
3600
3601    while(true)
3602    {
3603       /* E2SM-KPM Indication message format type */
3604       e2smKpmIndMsg.indicationMessage_formats.present = actionInfo->definition.formatType;
3605       switch(e2smKpmIndMsg.indicationMessage_formats.present)
3606       {
3607          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format1:
3608             {
3609                /* E2SM-KPM Indication message format 1 */
3610                DU_ALLOC(e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1, \
3611                      sizeof(E2SM_KPM_IndicationMessage_Format1_t));
3612                if(!e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1)
3613                {
3614                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3615                   failedInFormat = true;
3616                   break;
3617                }
3618
3619                if(fillE2smKpmIndMsgFormat1(e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1, \
3620                   &actionInfo->definition.choice.format1) != ROK)
3621                {
3622                   DU_LOG("\nERROR  -->  E2AP : Failed to fill E2SM-KPM Indication message format 1");
3623                   failedInFormat = true;
3624                   break;
3625                }
3626                break;
3627             }
3628
3629          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_NOTHING:
3630          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format2:
3631          default:
3632             {
3633                DU_LOG("\nERROR  -->  E2AP : fillRicIndMsgBuf: Only Format 1 supported");
3634                failedInFormat = true;
3635                break;
3636             }
3637       }
3638
3639       if(failedInFormat)
3640          break;
3641
3642       /* Encode E2SM-KPM Indication Message */
3643       xer_fprint(stdout, &asn_DEF_E2SM_KPM_IndicationMessage, &e2smKpmIndMsg);
3644       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3645       encBufSize = 0;
3646       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_IndicationMessage, 0, &e2smKpmIndMsg, PrepFinalEncBuf, encBuf);
3647       if(encRetVal.encoded == ENCODE_FAIL)
3648       {
3649          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM Indication Message (at %s)\n",\
3650                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3651          break;
3652       }
3653       else
3654       {
3655          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SM-KPM Indication Message \n");
3656 #ifdef DEBUG_ASN_PRINT
3657          for(int i=0; i< encBufSize; i++)
3658          {
3659             printf("%x",encBuf[i]);
3660          } 
3661 #endif
3662       }
3663
3664       /* Copy encoded string to RIC Indication Message buffer */
3665       ricIndMsgBuf->size = encBufSize;
3666       DU_ALLOC(ricIndMsgBuf->buf, ricIndMsgBuf->size);
3667       if(!ricIndMsgBuf->buf)
3668       {
3669          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3670          break;
3671       }
3672       memset(ricIndMsgBuf->buf, 0, ricIndMsgBuf->size);
3673       memcpy(ricIndMsgBuf->buf, encBuf, encBufSize);
3674
3675       ret = ROK;
3676       break;
3677    }
3678
3679    /* Free E2SM-KPM Indication Message */
3680    FreeE2smKpmIndicationMessage(&e2smKpmIndMsg);
3681
3682    return ret;
3683 }
3684
3685 /*******************************************************************
3686  *
3687  * @brief Free E2SM-KPM Indication Header
3688  *
3689  * @details
3690  *
3691  *    Function : FreeE2smKpmIndicationHeader
3692  *
3693  * Functionality: Free E2SM-KPM Indication Header
3694  * 
3695  * @param  E2SM-KPM Indication Header to be free
3696  * @return void
3697  *
3698  ******************************************************************/
3699 void FreeE2smKpmIndicationHeader(E2SM_KPM_IndicationHeader_t *e2smKpmIndHdr)
3700 {
3701    E2SM_KPM_IndicationHeader_Format1_t *format1 = NULLP;
3702
3703    if(e2smKpmIndHdr)
3704    {
3705       switch(e2smKpmIndHdr->indicationHeader_formats.present)
3706       {
3707          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_indicationHeader_Format1:
3708             {
3709                if(e2smKpmIndHdr->indicationHeader_formats.choice.indicationHeader_Format1)
3710                {
3711                   format1 = e2smKpmIndHdr->indicationHeader_formats.choice.indicationHeader_Format1;
3712
3713                   DU_FREE(format1->colletStartTime.buf, format1->colletStartTime.size);
3714                   DU_FREE(format1, sizeof(E2SM_KPM_IndicationHeader_Format1_t));
3715                }
3716                break;
3717             }
3718          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_NOTHING:
3719          default:
3720             break;
3721       }
3722    }
3723 }
3724
3725 /*******************************************************************
3726  *
3727  * @brief Fill RIC Indication Header buffer
3728  *
3729  * @details
3730  *
3731  *    Function : fillRicIndHeader
3732  *
3733  * Functionality: Fill E2SM-KPM Indication Header
3734  *    Encode this message and copy to RIC Indication Header buffer
3735  * 
3736  * @param  RIC Indication Header buffer to be filled
3737  *         Source RIC subscription info from E2AP DB
3738  * @return ROK     - success
3739  *         RFAILED - failure
3740  *
3741  ******************************************************************/
3742 uint8_t fillRicIndHeader(RICindicationHeader_t *ricIndHdr, RicSubscription *ricSubsInfo)
3743 {
3744    uint8_t ret = RFAILED;
3745    uint8_t secBufIdx = 0, milliSecBufIdx = 0;
3746    int8_t byteIdx = 0;
3747    bool formatFailure = false;
3748    RanFunction *ranFunc = NULLP;
3749    ReportStartTime *startTime = NULLP;
3750    E2SM_KPM_IndicationHeader_t e2smKpmIndHdr;
3751    E2SM_KPM_IndicationHeader_Format1_t *format1 = NULLP;
3752    asn_enc_rval_t   encRetVal;        /* Encoder return value */
3753
3754    while(true)
3755    {
3756       ranFunc = fetchRanFuncFromRanFuncId(ricSubsInfo->ranFuncId);
3757       if(ranFunc == NULLP)
3758       {
3759          DU_LOG("\nERROR  -->  E2AP : RAN Function ID [%d] not found", ricSubsInfo->ranFuncId);
3760          break;
3761       }
3762
3763       memset(&e2smKpmIndHdr, 0, sizeof(E2SM_KPM_IndicationHeader_t));
3764
3765       e2smKpmIndHdr.indicationHeader_formats.present = ranFunc->ricIndicationHeaderFormat;
3766       switch(e2smKpmIndHdr.indicationHeader_formats.present)
3767       {
3768          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_indicationHeader_Format1:
3769             {
3770                DU_ALLOC(e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1, \
3771                      sizeof(E2SM_KPM_IndicationHeader_Format1_t));
3772                if(!e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1)
3773                {
3774                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3775                   formatFailure = true;
3776                   break;
3777                }
3778                format1 = e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1;
3779
3780                /* Fetch reporting period start time from DB */
3781                switch(ricSubsInfo->eventTriggerDefinition.formatType)
3782                {
3783                   case 1:
3784                   {
3785                      startTime = &ricSubsInfo->eventTriggerDefinition.choice.format1.startTime;
3786                   }
3787                }
3788
3789                format1->colletStartTime.size = 8 * sizeof(uint8_t);
3790                DU_ALLOC(format1->colletStartTime.buf, format1->colletStartTime.size);
3791                if(!format1->colletStartTime.buf)
3792                {
3793                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3794                   formatFailure = true;
3795                   break;
3796                }
3797
3798                /* As per O-RAN.WG3.E2SM-KPM-R003-v03.00, section 8.3.12 and
3799                 * RFC 5905, section 6 :
3800                 * Time stamp has a 64-bit format where first 32-bit is seconds
3801                 * and next 32-bit is fraction in picosecond-level.
3802                 * This fraction has been rounded in microseconds.
3803                 *
3804                 * Hence,
3805                 * Storing 32-bit seconds at MSB 0-3 and
3806                 * 32-bit milliseconds at next 4 bytes i.e. bytes 4-7
3807                 */
3808                secBufIdx = 0;
3809                milliSecBufIdx = 4;
3810                for(byteIdx = 3; byteIdx >= 0; byteIdx--)
3811                {
3812                   format1->colletStartTime.buf[secBufIdx++] = startTime->timeInSec >> (8*byteIdx);
3813                   format1->colletStartTime.buf[milliSecBufIdx++] = startTime->timeInMilliSec >> (8*byteIdx);
3814                }
3815                break;
3816             }
3817
3818          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_NOTHING:
3819          default:
3820          {
3821              DU_LOG("\nERROR  -->  E2AP : Only E2SM-KPM Indication Header Format 1 supported");
3822              formatFailure = true;
3823              break;
3824          }
3825       }
3826
3827       if(formatFailure)
3828          break;
3829
3830       /* Encode E2SM-KPM Indication Header */
3831       xer_fprint(stdout, &asn_DEF_E2SM_KPM_IndicationHeader, &e2smKpmIndHdr);
3832       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3833       encBufSize = 0;
3834       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_IndicationHeader, 0, &e2smKpmIndHdr, PrepFinalEncBuf, encBuf);
3835       if(encRetVal.encoded == ENCODE_FAIL)
3836       {
3837          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM Indication Header (at %s)\n",\
3838                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3839          break;
3840       }
3841       else
3842       {
3843          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SM-KPM Indication Header \n");
3844 #ifdef DEBUG_ASN_PRINT
3845          for(int i=0; i< encBufSize; i++)
3846          {
3847             printf("%x",encBuf[i]);
3848          } 
3849 #endif
3850       }
3851
3852       /* Copy encoded string to RIC Indication Header buffer */
3853       ricIndHdr->size = encBufSize;
3854       DU_ALLOC(ricIndHdr->buf, ricIndHdr->size);
3855       if(!ricIndHdr->buf)
3856       {
3857          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3858          break;
3859       }
3860       memset(ricIndHdr->buf, 0, ricIndHdr->size);
3861       memcpy(ricIndHdr->buf, encBuf, encBufSize);
3862       ret = ROK;
3863       break;
3864    }
3865
3866    /* Free E2SM-KPM Indication Header */
3867    FreeE2smKpmIndicationHeader(&e2smKpmIndHdr);
3868
3869    return ret;
3870 }
3871
3872 /*******************************************************************
3873  *
3874  * brief Fill the RIC Indication Message
3875  *
3876  * @details
3877  *
3878  *    Function : fillRicIndication
3879  *
3880  * Functionality: Fills the RIC Indication Message
3881  *
3882  * @param  RIC Indication Message to be filled
3883  *         RIC Subscription DB
3884  *         Action DB
3885  * @return ROK     - success
3886  *         RFAILED - failure
3887  *
3888  ******************************************************************/
3889 uint8_t fillRicIndication(RICindication_t *ricIndicationMsg, RicSubscription *ricSubscriptionInfo, ActionInfo *actionInfo)
3890 {
3891    uint8_t elementCnt = 0, idx = 0;
3892    uint8_t ret = ROK;
3893
3894    elementCnt = 6;
3895
3896    ricIndicationMsg->protocolIEs.list.count = elementCnt;
3897    ricIndicationMsg->protocolIEs.list.size  = elementCnt * sizeof(RICindication_IEs_t *);
3898
3899    /* Initialize the Ric Indication members */
3900    DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, ricIndicationMsg->protocolIEs.list.size);
3901    if(ricIndicationMsg->protocolIEs.list.array == NULLP)
3902    {
3903       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3904       return RFAILED;
3905    }
3906
3907    for(idx=0; idx<elementCnt; idx++)
3908    {
3909       DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx], sizeof(RICindication_IEs_t));
3910       if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
3911       {
3912          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3913          return RFAILED;
3914       }
3915    }
3916
3917    /* RIC Request ID */
3918    idx = 0;
3919    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
3920    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
3921    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICrequestID;
3922    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID = \
3923       ricSubscriptionInfo->requestId.requestorId;
3924    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID = \
3925       ricSubscriptionInfo->requestId.instanceId;
3926
3927    /* RAN Function ID */
3928    idx++;
3929    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
3930    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
3931    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RANfunctionID;
3932    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ricSubscriptionInfo->ranFuncId;
3933
3934    /* RIC Action ID */
3935    idx++;
3936    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
3937    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
3938    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICactionID;
3939    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = actionInfo->actionId;
3940
3941    /* RIC Indication Type */
3942    idx++;
3943    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
3944    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
3945    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationType;
3946    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = actionInfo->type;
3947
3948    /* RIC Indication Header */
3949    idx++;
3950    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
3951    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
3952    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationHeader;
3953    if(fillRicIndHeader(&ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader, \
3954       ricSubscriptionInfo) != ROK)
3955    {
3956       DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication header");
3957       return RFAILED;
3958    }
3959
3960    /* RIC Indication Message */
3961    idx++;
3962    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
3963    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
3964    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationMessage;
3965    if(fillRicIndMsgBuf(&ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage, \
3966       actionInfo) != ROK)
3967    {
3968       DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication Message");
3969       return RFAILED;
3970    }
3971
3972    return ret;
3973 }
3974
3975 /*******************************************************************
3976  *
3977  * @brief Builds and Send the RicIndication Message
3978  *
3979  * @details
3980  *
3981  *    Function : BuildAndSendRicIndication
3982  *
3983  * Functionality:Fills the RicIndication Message
3984  *
3985  * @return ROK     - success
3986  *         RFAILED - failure
3987  *
3988  ******************************************************************/
3989
3990 uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo, ActionInfo *actionInfo)
3991 {
3992    uint8_t          ret = RFAILED; 
3993    E2AP_PDU_t       *e2apMsg = NULLP;
3994    RICindication_t  *ricIndicationMsg = NULLP;
3995    asn_enc_rval_t   encRetVal;        /* Encoder return value */
3996
3997    while(true)
3998    {
3999       DU_LOG("\nINFO   -->  E2AP : Building RIC Indication Message\n");
4000
4001       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4002       if(e2apMsg == NULLP)
4003       {
4004          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4005          break;
4006       }
4007
4008       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4009       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4010       if(e2apMsg->choice.initiatingMessage == NULLP)
4011       {
4012          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4013          break;
4014       }
4015       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
4016       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4017       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication;
4018
4019       ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
4020
4021       if(fillRicIndication(ricIndicationMsg, ricSubscriptionInfo, actionInfo) != ROK)
4022       {
4023          DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication message");
4024          break;
4025       }
4026
4027       /* Prints the Msg formed */
4028       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4029       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4030       encBufSize = 0;
4031       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4032             encBuf);
4033       if(encRetVal.encoded == ENCODE_FAIL)
4034       {
4035          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Indication Message (at %s)\n",\
4036                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4037          break;
4038       }
4039       else
4040       {
4041          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Indication Message \n");
4042 #ifdef DEBUG_ASN_PRINT
4043          for(int i=0; i< encBufSize; i++)
4044          {
4045             printf("%x",encBuf[i]);
4046          } 
4047 #endif
4048       }
4049
4050       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
4051       {
4052          DU_LOG("\nINFO   -->  E2AP : Sending RIC Indication Message");      
4053
4054       }
4055       ret = ROK;
4056       break;
4057    }
4058    FreeRicIndication(e2apMsg);  
4059    return ret;
4060 }
4061
4062 /*******************************************************************
4063  *
4064  * @brief free e2 node component configuration req and rsp
4065  *
4066  * @details
4067  *
4068  *    Function : freeE2NodeComponentConfiguration 
4069  *
4070  *    Functionality:
4071  *       - free e2 node component configuration req and rsp
4072  *
4073  * @params[in] E2nodeComponentConfiguration_t *e2nodeComponentConfiguration
4074  * @return ROK     - success
4075  *         RFAILED - failure
4076  *
4077  * ****************************************************************/
4078
4079 void freeE2NodeComponentConfiguration(E2nodeComponentConfiguration_t *e2nodeComponentConfiguration)
4080 {
4081    /* Free E2 Node Component Request Part */
4082    DU_FREE(e2nodeComponentConfiguration->e2nodeComponentRequestPart.buf, e2nodeComponentConfiguration->e2nodeComponentRequestPart.size);
4083
4084    /* Free E2 Node Component Response Part */
4085    DU_FREE(e2nodeComponentConfiguration->e2nodeComponentResponsePart.buf, e2nodeComponentConfiguration->e2nodeComponentResponsePart.size);
4086                                  
4087 }
4088
4089 /*******************************************************************
4090  *
4091  * @brief free e2 node component component identifier
4092  *
4093  * @details
4094  *
4095  *    Function : freeE2NodeComponentIdentifier
4096  *
4097  *    Functionality:
4098  *       - free e2 node component component identifier
4099  *
4100  * @params[in] E2nodeComponentID_t  *componentID 
4101  * @return ROK     - success
4102  *         RFAILED - failure
4103  *
4104  * ****************************************************************/
4105
4106 void freeE2NodeComponentIdentifier(E2nodeComponentID_t *componentID)
4107 {
4108    if(componentID->choice.e2nodeComponentInterfaceTypeF1)
4109    {
4110       DU_FREE(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf, componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
4111       DU_FREE(componentID->choice.e2nodeComponentInterfaceTypeF1, sizeof(E2nodeComponentInterfaceF1_t));
4112    }
4113                                  
4114 }
4115
4116 /*******************************************************************
4117  *
4118  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
4119  *
4120  * @details
4121  *
4122  *    Function : FreeE2NodeConfigUpdate 
4123  *
4124  *    Functionality:
4125  *       - freeing the memory allocated for E2nodeConfigurationUpdate
4126  *
4127  * @params[in] E2AP_PDU_t *e2apMsg 
4128  * @return ROK     - success
4129  *         RFAILED - failure
4130  *
4131  * ****************************************************************/
4132
4133 void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg)
4134 {
4135    uint8_t arrIdx =0, e2NodeUpdateListIdx=0, e2NodeRemovalListIdx=0, e2NodeAddListIdx=0;
4136    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate =NULL;
4137    E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList  =NULL;
4138    E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItem =NULL;
4139    E2nodeComponentConfigRemoval_List_t *e2NodeRemovalList =NULL;
4140    E2nodeComponentConfigRemoval_ItemIEs_t *e2NodeRemovalItem =NULL;
4141    E2nodeComponentConfigAddition_List_t *e2NodeAddList =NULL;
4142    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem =NULL;
4143
4144    if(e2apMsg != NULLP)
4145    {
4146       if(e2apMsg->choice.initiatingMessage != NULLP)
4147       {
4148          e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
4149          if(e2NodeConfigUpdate->protocolIEs.list.array != NULLP)
4150          {
4151             for(arrIdx = 0; arrIdx < e2NodeConfigUpdate->protocolIEs.list.count; arrIdx++)
4152             {
4153                if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx])
4154                {
4155
4156                   switch(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id)
4157                   {
4158                      case ProtocolIE_IDE2_id_TransactionID:
4159                         break;
4160
4161                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
4162                      {
4163                          e2NodeAddList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;
4164                          if(e2NodeAddList->list.array)
4165                          {
4166                              for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
4167                              {
4168                                 e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
4169                                  
4170                                 freeE2NodeComponentConfiguration(&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration);
4171                                 freeE2NodeComponentIdentifier(&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID);
4172                                 DU_FREE(e2NodeAddItem, sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
4173                              }
4174                              DU_FREE(e2NodeAddList->list.array, e2NodeAddList->list.size);
4175                          }
4176                          break;
4177                      }
4178                      case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate:
4179                         {
4180                            e2NodeUpdateList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdate_List;
4181                            if(e2NodeUpdateList->list.array)
4182                            {
4183                               for(e2NodeUpdateListIdx = 0; e2NodeUpdateListIdx< e2NodeUpdateList->list.count; e2NodeUpdateListIdx++)
4184                               {
4185                                  e2NodeUpdateItem = (E2nodeComponentConfigUpdate_ItemIEs_t *) e2NodeUpdateList->list.array[e2NodeUpdateListIdx];
4186                                  
4187                                  freeE2NodeComponentConfiguration(&e2NodeUpdateItem->value.choice.E2nodeComponentConfigUpdate_Item.e2nodeComponentConfiguration);
4188                                  freeE2NodeComponentIdentifier(&e2NodeUpdateItem->value.choice.E2nodeComponentConfigUpdate_Item.e2nodeComponentID);
4189                                  DU_FREE(e2NodeUpdateItem, sizeof(E2nodeComponentConfigUpdate_ItemIEs_t));
4190                               }
4191                               DU_FREE(e2NodeUpdateList->list.array, e2NodeUpdateList->list.size);
4192                            }
4193                            break;
4194                         }
4195                      case ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval:
4196                         {
4197                            e2NodeRemovalList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemoval_List;
4198                            if(e2NodeRemovalList->list.array)
4199                            {
4200                               for(e2NodeRemovalListIdx = 0; e2NodeRemovalListIdx< e2NodeRemovalList->list.count; e2NodeRemovalListIdx++)
4201                               {
4202                                  e2NodeRemovalItem = (E2nodeComponentConfigRemoval_ItemIEs_t *) e2NodeRemovalList->list.array[e2NodeRemovalListIdx];
4203
4204                                  freeE2NodeComponentIdentifier(&e2NodeRemovalItem->value.choice.E2nodeComponentConfigRemoval_Item.e2nodeComponentID);
4205                                  DU_FREE(e2NodeRemovalItem, sizeof(E2nodeComponentConfigRemoval_ItemIEs_t));
4206                               }
4207                               DU_FREE(e2NodeRemovalList->list.array, e2NodeRemovalList->list.size);
4208                            }
4209                            break;
4210                         }
4211                            
4212                      default:
4213                         break;
4214                   }
4215                   DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
4216                }
4217             }
4218             DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
4219          }
4220          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4221       }
4222       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4223    }
4224 }
4225
4226 /*******************************************************************
4227  *
4228  * @brief Buld and send the E2 node config update msg 
4229  *
4230  * @details
4231  *
4232  *    Function : BuildAndSendE2NodeConfigUpdate
4233  *
4234  *    Functionality:
4235  *         - Buld and send the E2 node config update msg
4236  *
4237  * @params[in] 
4238  * @return ROK     - success
4239  *         RFAILED - failure
4240  *
4241  * ****************************************************************/
4242
4243 uint8_t BuildAndSendE2NodeConfigUpdate(E2NodeConfigList *e2NodeList)
4244 {
4245    uint8_t ret = RFAILED;
4246    uint8_t arrIdx = 0,elementCnt = 0, transId=0;
4247    E2AP_PDU_t  *e2apMsg = NULLP;
4248    asn_enc_rval_t     encRetVal;       /* Encoder return value */
4249    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate = NULLP;
4250
4251    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update\n");
4252    do
4253    {
4254       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4255       if(e2apMsg == NULLP)
4256       {
4257          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4258          break;
4259       }
4260
4261       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4262       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4263       if(e2apMsg->choice.initiatingMessage == NULLP)
4264       {
4265          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4266          break;
4267       }
4268       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4269       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
4270       e2apMsg->choice.initiatingMessage->value.present = \
4271       InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate;
4272       e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
4273       
4274       elementCnt =1;
4275       if(e2NodeList->addE2NodeCount)
4276          elementCnt++;
4277       if(e2NodeList->updateE2NodeCount)
4278          elementCnt++;
4279       if(e2NodeList->removeE2NodeCount)
4280          elementCnt++;
4281
4282       e2NodeConfigUpdate->protocolIEs.list.count = elementCnt;
4283       e2NodeConfigUpdate->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdate_IEs_t*);
4284       DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
4285       if(e2NodeConfigUpdate->protocolIEs.list.array == NULLP)
4286       {
4287          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
4288          break;
4289       }
4290       
4291       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
4292       {
4293          DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
4294          if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx] == NULLP)
4295          {
4296             
4297             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
4298             break;
4299          }
4300       }
4301       
4302       if(arrIdx<elementCnt)
4303          break;
4304
4305       arrIdx = 0;
4306       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4307       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4308       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_TransactionID;
4309       transId = assignTransactionId();
4310       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
4311
4312       if(e2NodeList->addE2NodeCount)
4313       {
4314          arrIdx++;
4315          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition;
4316          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4317          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigAddition_List;
4318          if(BuildE2NodeConfigAddList(&(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List),\
4319          ProcedureCodeE2_id_E2nodeConfigurationUpdate, e2NodeList->addE2NodeCount, e2NodeList->addE2Node)!=ROK)
4320          {
4321             DU_LOG("\nERROR  -->  E2AP : Failed to create E2 Node config list");
4322             break;
4323          }
4324       }
4325       
4326       if(e2NodeList->updateE2NodeCount)
4327       {
4328          arrIdx++;
4329          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate;
4330          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4331          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigUpdate_List;
4332          if(BuildE2NodeConfigUpdateList(&e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdate_List,\
4333          e2NodeList->updateE2NodeCount, e2NodeList->updateE2Node) != ROK)
4334          {
4335
4336             DU_LOG("\nERROR  -->  E2AP : Failed to update the E2 node configuration");
4337             break;
4338          }
4339       }
4340       
4341       if(e2NodeList->removeE2NodeCount)
4342       {
4343          arrIdx++;
4344          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval;
4345          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4346          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigRemoval_List;
4347          if(BuildE2NodeConfigRemoveList(&e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemoval_List,\
4348          e2NodeList->removeE2NodeCount, e2NodeList->removeE2Node) != ROK)
4349          {
4350
4351             DU_LOG("\nERROR  -->  E2AP : Failed to remove the E2 node configuration");
4352             break;
4353          }
4354       }
4355
4356       /* Prints the Msg formed */
4357       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4358
4359       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4360       encBufSize = 0;
4361       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
4362       if(encRetVal.encoded == ENCODE_FAIL)
4363       {
4364          DU_LOG("\nERROR  -->  E2AP : Could not encode E2nodeConfigurationUpdate structure (at %s)\n",\
4365                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4366          break;
4367       }
4368       else
4369       {
4370          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2nodeConfigurationUpdate\n");
4371 #ifdef DEBUG_ASN_PRINT
4372          for(int i=0; i< encBufSize; i++)
4373          {
4374             printf("%x",encBuf[i]);
4375          }
4376 #endif
4377       }
4378       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize))
4379       {
4380          DU_LOG("\nERROR  -->  E2AP : Sending E2 node config update failed");
4381          break;
4382       }
4383
4384       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
4385       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
4386       memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.e2NodeConfigUpdate.configList, e2NodeList, sizeof(E2NodeConfigList));
4387       ret = ROK;
4388       break;
4389    }while(true);
4390    
4391    FreeE2NodeConfigUpdate(e2apMsg);
4392    return ret;
4393 }
4394
4395 /*******************************************************************
4396  *
4397  * @brief Deallocate the memory allocated for E2ResetRequest msg
4398  *
4399  * @details
4400  *
4401  *    Function : FreeE2ResetRequest
4402  *
4403  *    Functionality:
4404  *       - freeing the memory allocated for E2ResetRequest
4405  *
4406  * @params[in] E2AP_PDU_t *e2apMsg
4407  * @return ROK     - success
4408  *         RFAILED - failure
4409  *
4410  * ****************************************************************/
4411 void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg)
4412 {
4413    uint8_t ieIdx =0;
4414    ResetRequestE2_t  *resetReq = NULLP;
4415
4416    if(e2apMsg != NULLP)
4417    {
4418       if(e2apMsg->choice.initiatingMessage != NULLP)
4419       {
4420          resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4421          if(resetReq->protocolIEs.list.array)
4422          {
4423             for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
4424             {
4425                DU_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4426             }
4427             DU_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4428          }
4429          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4430       }
4431       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4432    }
4433 }
4434
4435 /*******************************************************************
4436  *
4437  * @brief Build and send the E2 reset request msg
4438  *
4439  * @details
4440  *
4441  *    Function : BuildAndSendE2ResetRequest
4442  *
4443  *    Functionality:
4444  *         - Buld and send the E2 reset request msg to RIC
4445  *
4446  * @params[in]
4447  * @return ROK     - success
4448  *         RFAILED - failure
4449  *
4450  * ****************************************************************/
4451 uint8_t BuildAndSendE2ResetRequest(E2FailureCause resetCause)
4452 {
4453    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
4454    uint8_t ret = RFAILED;
4455    E2AP_PDU_t        *e2apMsg = NULLP;
4456    ResetRequestE2_t  *resetReq = NULLP;
4457    asn_enc_rval_t     encRetVal;       /* Encoder return value */
4458
4459    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Request\n");
4460
4461    do
4462    {
4463       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4464       if(e2apMsg == NULLP)
4465       {
4466          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for E2AP-PDU failed");
4467          break;
4468       }
4469
4470       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4471       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4472       if(e2apMsg->choice.initiatingMessage == NULLP)
4473       {
4474          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for initiatingMessage");
4475          break;
4476       }
4477
4478       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
4479       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4480       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
4481       resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4482
4483       elementCnt = 2;
4484       resetReq->protocolIEs.list.count = elementCnt;
4485       resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
4486
4487       DU_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4488       if(!resetReq->protocolIEs.list.array)
4489       {
4490          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
4491             Reset Request IE array");
4492          break;
4493       }
4494
4495       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
4496       {
4497          DU_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4498          if(!resetReq->protocolIEs.list.array[ieIdx])
4499          {
4500             DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
4501             Reset Request IE array element");
4502             break;
4503          }
4504       }
4505
4506       /* In case of failure */
4507       if(ieIdx < elementCnt)
4508          break;
4509
4510       ieIdx = 0;
4511       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4512       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
4513       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
4514       transId = assignTransactionId();
4515       resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
4516
4517       ieIdx++;
4518       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
4519       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
4520       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
4521       fillE2Cause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, resetCause);
4522
4523       /* Prints the Msg formed */
4524       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4525
4526       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4527       encBufSize = 0;
4528       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4529             encBuf);
4530       if(encRetVal.encoded == ENCODE_FAIL)
4531       {
4532          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupRequest structure (at %s)\n",\
4533                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4534          break;
4535       }
4536       else
4537       {
4538          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2SetupRequest\n");
4539 #ifdef DEBUG_ASN_PRINT
4540          for(int i=0; i< encBufSize; i++)
4541          {
4542             printf("%x",encBuf[i]);
4543          }
4544 #endif
4545       }
4546       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
4547       {
4548          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
4549          break;
4550       }
4551
4552       /* In case the message is sent successfully, store the transaction info to
4553        * be used when response is received */
4554       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
4555       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
4556
4557       ret = ROK;
4558       break;
4559    }while(true);
4560
4561    /* Free all memory */
4562    FreeE2ResetRequest(e2apMsg);
4563    return ret;
4564 }
4565
4566 /*******************************************************************
4567  *
4568  * @brief Deallocate the memory allocated for Reset Response msg
4569  *
4570  * @details
4571  *
4572  *    Function : freeAperDecodingOfE2ResetRsp
4573  *
4574  *    Functionality:
4575  *       - freeing the memory allocated for Reset response
4576  *
4577  * @params[in] ResetResponseE2_t *resetResponse
4578  * @return void
4579  *
4580  * ****************************************************************/
4581 void freeAperDecodingOfE2ResetRsp(ResetResponseE2_t *resetResponse)
4582 {
4583    uint8_t ieIdx;
4584
4585    if(resetResponse)
4586    {
4587       if(resetResponse->protocolIEs.list.array)
4588       {
4589          for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
4590          {
4591             if(resetResponse->protocolIEs.list.array[ieIdx])
4592             {
4593                switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
4594                {
4595                   case ProtocolIE_IDE2_id_TransactionID:
4596                      break;
4597
4598                   case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
4599                      break;
4600                }
4601                free(resetResponse->protocolIEs.list.array[ieIdx]);
4602             }
4603          }
4604          free(resetResponse->protocolIEs.list.array);
4605       }
4606    }
4607 }
4608
4609 /******************************************************************
4610  *
4611  * @brief Processes E2 Reset Response sent by RIC
4612  *
4613  * @details
4614  *
4615  *    Function : procResetResponse
4616  *
4617  *    Functionality: Processes E2 Reset Response sent by RIC
4618  *
4619  * @params[in] E2AP_PDU_t ASN decoded E2AP message
4620  * @return ROK     - success
4621  *         RFAILED - failure
4622  *
4623  * ****************************************************************/
4624 uint8_t procResetResponse(E2AP_PDU_t *e2apMsg)
4625 {
4626    uint8_t ieIdx =0, transId;
4627    ResetResponseE2_t *resetResponse;
4628
4629    DU_LOG("\nINFO   -->  E2AP : E2 Reset Response received");
4630    resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;;
4631
4632    for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
4633    {
4634       switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
4635       {
4636          case ProtocolIE_IDE2_id_TransactionID:
4637             transId = resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
4638             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) && \
4639                   (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
4640             {
4641                memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
4642             }
4643             else
4644             {
4645                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
4646                return RFAILED;
4647             }
4648             break;
4649          case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
4650             /* As per ORAN WG3 E2AP spec v3.0, section 9.2.2
4651                Criticality Diagnostics IE is sent by Near-RT RIC when parts of a received message i.e. 
4652                Reset Request in this case, have not been comprehended or were missing, or if the message 
4653                contained logical errors.
4654
4655                Processing of this ID should be implemented when negative call flows are to be supported.
4656              */
4657             break;
4658          default:
4659             DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2 Reset Response : %ld",
4660                   resetResponse->protocolIEs.list.array[ieIdx]->id);
4661             break;
4662       }
4663    }
4664
4665    freeAperDecodingOfE2ResetRsp(resetResponse);
4666    return ROK;
4667 }
4668
4669 /******************************************************************
4670  *
4671  * @brief Deallocation of memory allocated by aper decoder for e2 setup Failure
4672  *
4673  * @details
4674  *
4675  *    Function : freeAperDecodingOfE2SetupFailure
4676  *
4677  *    Functionality: Deallocation of memory allocated by aper decoder for e2
4678  *    setup Failure
4679  *
4680  * @params[in] E2setupFailure_t *e2SetupFailure;
4681  * @return void
4682  *
4683  * ****************************************************************/
4684 void freeAperDecodingOfE2SetupFailure(E2setupFailure_t *e2SetupFailure)
4685 {
4686    uint8_t arrIdx;
4687
4688    if(e2SetupFailure)
4689    {
4690       if(e2SetupFailure->protocolIEs.list.array)
4691       {
4692          for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
4693          {
4694             if(e2SetupFailure->protocolIEs.list.array[arrIdx])
4695             {
4696                free(e2SetupFailure->protocolIEs.list.array[arrIdx]);  
4697             }
4698          }
4699          free(e2SetupFailure->protocolIEs.list.array);
4700       }
4701    }
4702 }
4703 /******************************************************************
4704  *
4705  * @brief Processes E2 Setup Failure sent by RIC
4706  *
4707  * @details
4708  *
4709  *    Function : procE2SetupFailure
4710  *
4711  *    Functionality: Processes E2 Setup failure sent by RIC
4712  *
4713  * @params[in] E2AP_PDU_t ASN decoded E2AP message
4714  * @return ROK     - success
4715  *         RFAILED - failure
4716  *
4717  * ****************************************************************/
4718 void procE2SetupFailure(E2AP_PDU_t *e2apMsg)
4719 {
4720    uint8_t arrIdx =0, transId =0, timerValue=0; 
4721    E2setupFailure_t *e2SetupFailure;
4722
4723    DU_LOG("\nINFO   -->  E2AP : E2 Setup failure received"); 
4724    e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
4725
4726    for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
4727    {
4728       switch(e2SetupFailure->protocolIEs.list.array[arrIdx]->id)
4729       {
4730          case ProtocolIE_IDE2_id_TransactionID:
4731          {
4732             transId = e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
4733             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
4734                   (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
4735             {
4736                memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
4737             }
4738             else
4739             {
4740                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
4741                return ;
4742             }
4743             break;
4744          }
4745          case ProtocolIE_IDE2_id_TimeToWaitE2:
4746             {
4747                timerValue = convertE2WaitTimerEnumToValue(e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
4748                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR)) == FALSE)
4749                {
4750                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR, timerValue);
4751                }
4752                else
4753                {
4754                   DU_LOG("\nERROR   -->  E2AP : EVENT_E2_SETUP_TMR timer is already running");
4755                   return;
4756                }
4757                break; 
4758             }
4759       }
4760    }
4761
4762    freeAperDecodingOfE2SetupFailure(e2SetupFailure);
4763 }
4764 /******************************************************************
4765  *
4766  * @brief Deallocation of memory allocated by aper decoder for RIC service Query
4767  *
4768  * @details
4769  *
4770  *    Function : freeAperDecodingOfRicServiceQuery
4771  *
4772  *    Functionality: Deallocation of memory allocated by aper decoder for RIC
4773  *    service Query
4774  *
4775  * @params[in] RICserviceQuery_t *ricServiceQuery;
4776  * @return void
4777  *
4778  * ****************************************************************/
4779
4780 void freeAperDecodingOfRicServiceQuery(RICserviceQuery_t *ricServiceQuery)
4781 {
4782    uint8_t arrIdx,ranFuncIdx;
4783     RANfunctionsID_List_t *ranFuncAddedList;
4784
4785    if(ricServiceQuery)
4786    {
4787       if(ricServiceQuery->protocolIEs.list.array)
4788       {
4789          for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
4790          {
4791             if(ricServiceQuery->protocolIEs.list.array[arrIdx])
4792             {
4793                switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
4794                {
4795                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
4796                   {
4797                      ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
4798                      if(ranFuncAddedList->list.array)
4799                      {
4800                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
4801                         {
4802                            free(ranFuncAddedList->list.array[ranFuncIdx]);
4803                         }
4804                         free(ranFuncAddedList->list.array);;
4805                      }
4806                      break;
4807                   }
4808                   default:
4809                      break;
4810                }
4811                free(ricServiceQuery->protocolIEs.list.array[arrIdx]);
4812             }
4813          }
4814          free(ricServiceQuery->protocolIEs.list.array);
4815       }
4816    }
4817 }
4818 /*******************************************************************
4819  *
4820  * @brief Build RanFunction Delete List
4821  *
4822  * @details
4823  *
4824  *    Function : BuildRanFunctionDeleteList
4825  *
4826  * Functionality:  Build RanFunction Delete List
4827  *
4828  * @params[in]
4829  *    RANfunctionsID List
4830  *    Count of the RAN function
4831  *    Received RAN function list
4832  *
4833  * @return ROK     - success
4834  *         RFAILED - failure
4835  *
4836  ******************************************************************/
4837
4838 uint8_t BuildRanFunctionDeleteList(RANfunctionsID_List_t *deleteList, uint8_t count, RanFuncInfo *recvdRanFunc)
4839 {
4840    uint8_t ranFuncIdx=0;
4841    RANfunctionID_ItemIEs_t *delRanFuncItem;
4842
4843    if(count)
4844    {
4845       deleteList->list.count = count;
4846       deleteList->list.size = deleteList->list.count * sizeof(RANfunctionID_ItemIEs_t*);
4847       DU_ALLOC(deleteList->list.array, deleteList->list.size);
4848       if(deleteList->list.array == NULLP)
4849       {
4850          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
4851          return RFAILED;
4852       }
4853       for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
4854       {
4855          DU_ALLOC(deleteList->list.array[ranFuncIdx], sizeof(RANfunctionID_ItemIEs_t));
4856          if(deleteList->list.array[ranFuncIdx] == NULLP)
4857          {
4858             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
4859             return RFAILED;
4860          }
4861          delRanFuncItem= (RANfunctionID_ItemIEs_t *) deleteList->list.array[ranFuncIdx];
4862          delRanFuncItem->id = ProtocolIE_IDE2_id_RANfunctionID_Item;
4863          delRanFuncItem->criticality = CriticalityE2_ignore;
4864          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionID = recvdRanFunc[ranFuncIdx].id;
4865          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionRevision = recvdRanFunc[ranFuncIdx].revisionCounter;
4866
4867       }
4868    }
4869    return ROK;
4870 }
4871 /*******************************************************************
4872  *
4873  * @brief De Allocate  Ric Service Update message
4874  *
4875  * @details
4876  *
4877  *    Function : FreeRicServiceUpdate
4878  *
4879  *    Functionality: De-Allocating Ric Service Update message
4880  *
4881  * @params[in] E2AP_PDU_t *e2apMsg
4882
4883  * @return void
4884  *
4885  * ****************************************************************/
4886
4887 void FreeRicServiceUpdate(E2AP_PDU_t *e2apMsg)
4888 {
4889    uint8_t arrIdx = 0;
4890    uint8_t ranFuncAddListIdx=0, ranFuncDelIdx=0;
4891    RICserviceUpdate_t *ricServiceUpdate;
4892    RANfunctions_List_t *ranFunctionsList;
4893    RANfunction_ItemIEs_t *ranFuncItemIe;
4894    RANfunction_Item_t  *ranFunItem;
4895    RANfunctionsID_List_t *deleteList;
4896
4897    /* De-allocating Memory */
4898    if(e2apMsg != NULLP)
4899    {
4900       if(e2apMsg->choice.initiatingMessage != NULLP)
4901       {
4902          ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
4903          if(ricServiceUpdate->protocolIEs.list.array != NULLP)
4904          {
4905             for(arrIdx = 0; arrIdx < ricServiceUpdate->protocolIEs.list.count; arrIdx++)
4906             {
4907                if(ricServiceUpdate->protocolIEs.list.array[arrIdx] != NULLP)
4908                {
4909                   switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
4910                   {
4911                      case ProtocolIE_IDE2_id_TransactionID:
4912                         break;
4913
4914                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
4915                      case ProtocolIE_IDE2_id_RANfunctionsModified:
4916                         {
4917                            ranFunctionsList = &(ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List);
4918                            if(ranFunctionsList->list.array)
4919                            {
4920                               for(ranFuncAddListIdx= 0; ranFuncAddListIdx< ranFunctionsList->list.count; ranFuncAddListIdx++)
4921                               {
4922                                  if(ranFunctionsList->list.array[ranFuncAddListIdx])
4923                                  {
4924                                     ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncAddListIdx];
4925                                     ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
4926                                     DU_FREE(ranFunItem->ranFunctionOID.buf, ranFunItem->ranFunctionOID.size);
4927                                     DU_FREE(ranFunItem->ranFunctionDefinition.buf, ranFunItem->ranFunctionDefinition.size);
4928                                     DU_FREE(ranFunctionsList->list.array[ranFuncAddListIdx], sizeof(RANfunction_ItemIEs_t));
4929                                  }
4930                               }
4931                               DU_FREE(ranFunctionsList->list.array, ranFunctionsList->list.size);
4932                            }
4933                            break;
4934                         }
4935                      case ProtocolIE_IDE2_id_RANfunctionsDeleted:
4936                         {
4937                            deleteList= &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
4938                            if(deleteList->list.array)
4939                            {
4940                               for(ranFuncDelIdx = 0; ranFuncDelIdx< deleteList->list.count; ranFuncDelIdx++)
4941                               {
4942                                  DU_FREE(deleteList->list.array[ranFuncDelIdx], sizeof(RANfunctionID_ItemIEs_t));
4943                               }
4944                               DU_FREE(deleteList->list.array, deleteList->list.size);
4945   
4946                            }
4947                            break;
4948                         }
4949                      default:
4950                         DU_LOG("\nERROR  --> E2AP: Invalid event at ricServiceUpdate %ld ",\
4951                               (ricServiceUpdate->protocolIEs.list.array[arrIdx]->id));
4952                         break;
4953                   }
4954                   DU_FREE(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
4955                }
4956             }
4957             DU_FREE(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
4958          }
4959          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4960       }
4961       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4962    }
4963 }
4964
4965 /*******************************************************************
4966  *
4967  * @brief Builds and Send the RicServiceUpdateuest
4968  *
4969  * @details
4970  *
4971  *    Function : BuildAndSendRicServiceUpdate
4972  *
4973  * Functionality:Fills the RicServiceUpdateuest
4974  *
4975  * @return ROK     - success
4976  *         RFAILED - failure
4977  *
4978  ******************************************************************/
4979
4980 uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate)
4981 {
4982    uint8_t arrIdx = 0, elementCnt=0;
4983    uint8_t transId = 0, ret = RFAILED;
4984    bool memAllocFailed =false;
4985    E2AP_PDU_t        *e2apMsg = NULLP;
4986    RICserviceUpdate_t  *ricServiceUpdate = NULLP;
4987    asn_enc_rval_t     encRetVal;       /* Encoder return value */
4988
4989    DU_LOG("\nINFO   -->  E2AP : Building Ric Service Update\n");
4990    do
4991    {
4992       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4993       if(e2apMsg == NULLP)
4994       {
4995          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4996          break;
4997       }
4998       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4999       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5000       if(e2apMsg->choice.initiatingMessage == NULLP)
5001       {
5002          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
5003          break;
5004       }
5005       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
5006       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
5007       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceUpdate;
5008       ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
5009       
5010       /* For TransId IE, set elementCnt to 1.
5011       If there is any item in the RAN function add list, RAN function modification list, or RAN function delete list, increment the elementCnt.*/
5012
5013       elementCnt =1;
5014       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5015         elementCnt++;
5016       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
5017          elementCnt++;
5018       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
5019          elementCnt++;
5020        
5021       ricServiceUpdate->protocolIEs.list.count = elementCnt;
5022       ricServiceUpdate->protocolIEs.list.size = elementCnt * sizeof(RICserviceUpdate_IEs_t*);
5023
5024       /* Initialize the E2Setup members */
5025       DU_ALLOC(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
5026       if(ricServiceUpdate->protocolIEs.list.array == NULLP)
5027       {
5028          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
5029          break;
5030       }
5031       
5032       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
5033       {
5034          DU_ALLOC(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
5035          if(ricServiceUpdate->protocolIEs.list.array[arrIdx] == NULLP)
5036          {
5037             memAllocFailed = true;
5038             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayIdx [%d]", arrIdx);
5039             break;
5040          }
5041       }
5042       if(memAllocFailed == true)
5043          break;
5044
5045       arrIdx = 0;
5046
5047       /* TransactionID */
5048       ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
5049       ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5050       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
5051       if(serviceUpdate.dir == E2_NODE_INITIATED)
5052          transId = assignTransactionId();
5053       else
5054         transId = serviceUpdate.transId;
5055       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
5056
5057       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5058       {
5059          arrIdx++;
5060          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAdded;
5061          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5062          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
5063          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,\
5064          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded, serviceUpdate.recvRanFuncList.ranFunToBeAdded) !=ROK)
5065          {
5066             break;
5067          }
5068       }
5069
5070       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
5071       {
5072          arrIdx++;
5073          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsModified;
5074          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5075          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
5076          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,
5077          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeModified, serviceUpdate.recvRanFuncList.ranFunToBeModified) !=ROK)
5078          {
5079             break;
5080          }
5081       }
5082
5083       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
5084       {
5085          arrIdx++;
5086          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsDeleted;
5087          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5088          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctionsID_List;
5089          if(BuildRanFunctionDeleteList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List,\
5090          serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted, serviceUpdate.recvRanFuncList.ranFunToBeDeleted) != ROK)
5091          {
5092             break;
5093          }
5094       }
5095       /* Prints the Msg formed */
5096       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5097
5098       memset(encBuf, 0, ENC_BUF_MAX_LEN);
5099       encBufSize = 0;
5100       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
5101       if(encRetVal.encoded == ENCODE_FAIL)
5102       {
5103          DU_LOG("\nERROR  -->  E2AP : Could not encode RicServiceUpdateuest structure (at %s)\n",\
5104                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
5105          break;
5106       }
5107       else
5108       {
5109          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RicServiceUpdateuest\n");
5110 #ifdef DEBUG_ASN_PRINT
5111          for(int i=0; i< encBufSize; i++)
5112          {
5113             printf("%x",encBuf[i]);
5114          }
5115 #endif
5116       }
5117       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
5118       {
5119          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
5120          break;
5121       }
5122       ret = ROK;
5123       break;
5124    }while(true);
5125    
5126    if(ret == ROK)
5127    {
5128       if(serviceUpdate.dir == E2_NODE_INITIATED)
5129       {
5130          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
5131          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5132       }
5133       else
5134       {
5135          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId = transId;
5136          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5137       }
5138       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.dir = serviceUpdate.dir;
5139       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.transId =transId;
5140       memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.recvRanFuncList, &serviceUpdate.recvRanFuncList, sizeof(E2TmpRanFunList));
5141    }
5142    FreeRicServiceUpdate(e2apMsg);
5143    return ret;
5144 }
5145 /******************************************************************
5146  *
5147  * @brief Processes RIC service Query sent by RIC
5148  *
5149  * @details
5150  *
5151  *    Function : procRicServiceQuery
5152  *
5153  *    Functionality: Processes RIC service Query sent by RIC
5154  *
5155  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5156  * @return ROK     - success
5157  *         RFAILED - failure
5158  *
5159  * ****************************************************************/
5160
5161 void procRicServiceQuery(E2AP_PDU_t *e2apMsg)
5162 {
5163    ConfigType action;
5164    uint16_t arrIdx =0, ranFuncIdx=0,tmpIdx=0;
5165    uint16_t id,revisionCcounter;
5166    bool tmpArray[MAX_RAN_FUNCTION] = {false};
5167    RICserviceQuery_t *ricServiceQuery=NULL;
5168    RicServiceUpdate ricUpdate;
5169    RANfunctionID_ItemIEs_t *ranFuncAddedItemIe;
5170    RANfunctionsID_List_t *ranFuncAddedList;
5171
5172    DU_LOG("\nINFO   -->  E2AP : RIC Service Query received");
5173    memset(&ricUpdate, 0, sizeof(RicServiceUpdate));
5174    ricUpdate.dir = RIC_INITIATED;
5175    ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
5176
5177    for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
5178    {
5179       switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
5180       {
5181          /* TODO completing in next patch/gerrit */
5182          case ProtocolIE_IDE2_id_TransactionID:
5183          {
5184             ricUpdate.transId = ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
5185             break;
5186          }
5187
5188          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5189          {
5190             ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5191             if(ranFuncAddedList->list.array)
5192             {
5193                for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
5194                {
5195                   if(ranFuncAddedList->list.array[ranFuncIdx])
5196                   {
5197                      /* Using the RAN function Id, identify the RAN function to be modified or deleted.  */
5198                      
5199                      ranFuncAddedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAddedList->list.array[ranFuncIdx];
5200                      id = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionID;
5201                      revisionCcounter = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision;
5202                      
5203                      if((id != duCb.e2apDb.ranFunction[id-1].id))
5204                      {
5205                         action = CONFIG_DEL;
5206                      }
5207                      else if((id == duCb.e2apDb.ranFunction[id-1].id)&&(revisionCcounter!=duCb.e2apDb.ranFunction[id-1].revisionCounter))
5208                      {
5209                         action = CONFIG_MOD;
5210                      }
5211
5212                      if(action == CONFIG_DEL)
5213                      {
5214                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].id = id;
5215                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].revisionCounter = revisionCcounter;
5216                         ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted++;
5217                      }
5218                      else if(action == CONFIG_MOD)
5219                      {
5220                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].id = id;
5221                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].revisionCounter = revisionCcounter;
5222                         ricUpdate.recvRanFuncList.numOfRanFunToBeModified++;
5223                      }
5224
5225                      /* If any ID is set to true, it means that the ID has been used in either modification or deletion list. 
5226                       * Else we will add the IDs into the added list */
5227                      tmpArray[id-1] = true;
5228                   }
5229                }
5230             }
5231             break;
5232          }
5233       }
5234    }
5235
5236    /*  Traversing the whole RAN function list in ducb to check if any new Ran function ids have been added. */
5237    for(arrIdx =0; arrIdx<MAX_RAN_FUNCTION; arrIdx++)
5238    {
5239       tmpIdx= ricUpdate.recvRanFuncList.numOfRanFunToBeAdded;
5240       if((duCb.e2apDb.ranFunction[arrIdx].id >0)&&(!tmpArray[arrIdx]))
5241       {
5242          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[arrIdx].id;
5243          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[arrIdx].revisionCounter;
5244          ricUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
5245       }
5246    }
5247
5248    if(BuildAndSendRicServiceUpdate(ricUpdate)!= ROK)
5249    {
5250       DU_LOG("\nERROR  -->  E2AP : Failed to build and send ric service update message");
5251    }
5252
5253    freeAperDecodingOfRicServiceQuery(ricServiceQuery);
5254 }
5255
5256 /******************************************************************
5257  *
5258  * @brief Deallocation of memory allocated by aper decoder for 
5259  *    RIC service update ack
5260  *
5261  * @details
5262  *
5263  *    Function : freeAperDecodingOfRicServiceUpdateAck
5264  *
5265  *    Functionality: Deallocation of memory allocated by aper decoder 
5266  *    for RIC service update ack
5267  *
5268  * @params[in] RICserviceUpdateAck_t *ricServiceAck;
5269  * @return void
5270  *
5271  * ****************************************************************/
5272
5273 void freeAperDecodingOfRicServiceUpdateAck(RICserviceUpdateAcknowledge_t *ricServiceAck)
5274 {
5275    uint8_t arrIdx=0,ranFuncIdx=0;
5276    RANfunctionsID_List_t *ranFuncAddedList=NULL;
5277
5278    if(ricServiceAck)
5279    {
5280       if(ricServiceAck->protocolIEs.list.array)
5281       {
5282          for(arrIdx=0; arrIdx<ricServiceAck->protocolIEs.list.count; arrIdx++)
5283          {
5284             if(ricServiceAck->protocolIEs.list.array[arrIdx])
5285             {
5286                switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id)
5287                {
5288                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5289                   {
5290                      ranFuncAddedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5291                      if(ranFuncAddedList->list.array)
5292                      {
5293                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
5294                         {
5295                            free(ranFuncAddedList->list.array[ranFuncIdx]);
5296                         }
5297                         free(ranFuncAddedList->list.array);
5298                      }
5299                      break;
5300                   }
5301                   default:
5302                      break;
5303                }
5304                free(ricServiceAck->protocolIEs.list.array[arrIdx]);  
5305             }
5306          }
5307          free(ricServiceAck->protocolIEs.list.array);
5308       }
5309    }
5310 }
5311
5312 /******************************************************************
5313  *
5314  * @brief Processes RIC service update ack sent by RIC
5315  *
5316  * @details
5317  *
5318  *    Function : procRicServiceUpdateAck
5319  *
5320  *    Functionality: Processes RIC service update ack sent by RIC
5321  *
5322  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5323  * @return ROK     - success
5324  *         RFAILED - failure
5325  *
5326  * ****************************************************************/
5327
5328 void procRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
5329 {
5330    uint8_t arrIdx =0, transId =0; 
5331    uint16_t id =0, tmpIdx=0, ranFuncIdx=0;
5332    RicServiceUpdate serviceUpdate;
5333    RANfunctionsIDcause_List_t *rejectedList=NULL;
5334    RICserviceUpdateAcknowledge_t *ricServiceAck=NULL;
5335    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
5336    
5337    DU_LOG("\nINFO   -->  E2AP : RIC service update ack received"); 
5338    memset(&serviceUpdate, 0, sizeof(RicServiceUpdate));
5339    ricServiceAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
5340    
5341    for(arrIdx=0; arrIdx<ricServiceAck->protocolIEs.list.count; arrIdx++)
5342    {
5343       switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id)
5344       {
5345          case ProtocolIE_IDE2_id_TransactionID:
5346          {
5347             transId = ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
5348             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
5349             (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
5350             {
5351               memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
5352             }
5353             else if((duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId == transId) &&\
5354             (duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
5355             {
5356               memset(&duCb.e2apDb.e2TransInfo.ricInitTransaction[transId], 0, sizeof(E2TransInfo));
5357             }
5358             else
5359             {
5360                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
5361                return ;
5362             }
5363             break;
5364          }
5365          
5366          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5367             break;
5368
5369          case ProtocolIE_IDE2_id_RANfunctionsRejected:
5370          {
5371             rejectedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
5372             if(rejectedList->list.array)
5373             {
5374                for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
5375                {
5376                   ranFuncRejectedItemIe =  (RANfunctionIDcause_ItemIEs_t*)rejectedList->list.array[ranFuncIdx];
5377                   id = ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID;
5378                   tmpIdx= serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded;
5379                   serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[id-1].id;
5380                   serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[id-1].revisionCounter;
5381                   serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
5382                }
5383             }
5384             break;
5385          }
5386
5387       }
5388    }
5389
5390    if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5391    {
5392       serviceUpdate.dir = E2_NODE_INITIATED;
5393       BuildAndSendRicServiceUpdate(serviceUpdate);
5394    }
5395    freeAperDecodingOfRicServiceUpdateAck(ricServiceAck);
5396 }
5397
5398 /******************************************************************
5399  *
5400  * @brief Deallocation of memory allocated by aper decoder for 
5401  *       RIC service update failure
5402  *
5403  * @details
5404  *
5405  *    Function : freeAperDecodingOfRicServiceUpdateFailure
5406  *
5407  *    Functionality: Deallocation of memory allocated by aper decoder 
5408  *    for RIC service update failure
5409  *
5410  * @params[in] RICserviceUpdateFailure_t *ricServiceFailure;
5411  * @return void
5412  *
5413  * ****************************************************************/
5414
5415 void freeAperDecodingOfRicServiceUpdateFailure(RICserviceUpdateFailure_t *ricServiceFailure)
5416 {
5417    uint8_t arrIdx=0;
5418
5419    if(ricServiceFailure)
5420    {
5421       if(ricServiceFailure->protocolIEs.list.array)
5422       {
5423          for(arrIdx=0; arrIdx<ricServiceFailure->protocolIEs.list.count; arrIdx++)
5424          {
5425             if(ricServiceFailure->protocolIEs.list.array[arrIdx])
5426             {
5427                free(ricServiceFailure->protocolIEs.list.array[arrIdx]);  
5428             }
5429          }
5430          free(ricServiceFailure->protocolIEs.list.array);
5431       }
5432    }
5433 }
5434
5435 /******************************************************************
5436  *
5437  * @brief Processes RIC service update failure sent by RIC
5438  *
5439  * @details
5440  *
5441  *    Function : procRicServiceUpdateFailure
5442  *
5443  *    Functionality: Processes RIC service update failure sent by RIC
5444  *
5445  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5446  * @return ROK     - success
5447  *         RFAILED - failure
5448  *
5449  * ****************************************************************/
5450
5451 void procRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
5452 {
5453    uint8_t arrIdx =0, timerValue=0; 
5454    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
5455
5456    DU_LOG("\nINFO   -->  E2AP : RIC service update failure received"); 
5457    ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
5458
5459    for(arrIdx=0; arrIdx<ricServiceFailure->protocolIEs.list.count; arrIdx++)
5460    {
5461       switch(ricServiceFailure->protocolIEs.list.array[arrIdx]->id)
5462       {
5463          case ProtocolIE_IDE2_id_TransactionID:
5464             {
5465                break;
5466             }
5467          case ProtocolIE_IDE2_id_TimeToWaitE2:
5468             {
5469                timerValue = convertE2WaitTimerEnumToValue(ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
5470                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR)) == FALSE)
5471                {
5472                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR, timerValue);
5473                }
5474                else
5475                {
5476                   DU_LOG("\nERROR   -->  E2AP : EVENT_RIC_SERVICE_UPDATE_TMR  timer is already running");
5477                   return;
5478                }
5479                break; 
5480             }
5481          case ProtocolIE_IDE2_id_CauseE2:
5482             {
5483                break;
5484             }
5485       }
5486    }
5487
5488    freeAperDecodingOfRicServiceUpdateFailure(ricServiceFailure);
5489 }
5490
5491 /******************************************************************
5492  *
5493  * @brief DU Send E2 Node Configuration Update
5494  *
5495  * @details
5496  *
5497  *    Function : duSendE2NodeConfigurationUpdate 
5498  *
5499  *    Functionality: DU Send E2 Node Configuration Update
5500  *
5501  * @return ROK     - success
5502  *         RFAILED - failure
5503  *
5504  * ****************************************************************/
5505
5506 uint8_t duSendE2NodeConfigurationUpdate()
5507 {
5508    E2NodeConfigList e2NodeList;
5509    CmLList *node =NULL;
5510    E2NodeComponent *e2NodeComponentInfo=NULL;
5511
5512    memset(&e2NodeList, 0, sizeof(E2NodeConfigList));
5513    CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node);
5514    while(node)
5515    {
5516       e2NodeComponentInfo = (E2NodeComponent*)node->node;
5517
5518       if(e2NodeComponentInfo->componentRequestPart && e2NodeComponentInfo->componentResponsePart)
5519       {
5520          switch(e2NodeComponentInfo->componentActionType)
5521          {
5522             case E2_NODE_COMPONENT_ADD:
5523                {
5524                   e2NodeList.addE2Node[e2NodeList.addE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
5525                   e2NodeList.addE2Node[e2NodeList.addE2NodeCount].actionType = e2NodeComponentInfo->componentActionType;
5526                   e2NodeList.removeE2NodeCount++;
5527                   break;
5528                }
5529             case E2_NODE_COMPONENT_UPDATE:
5530                {
5531                   e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
5532                   e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].actionType = e2NodeComponentInfo->componentActionType;
5533                   e2NodeList.updateE2NodeCount++;
5534                   break;
5535
5536                }
5537             case E2_NODE_COMPONENT_DEL:
5538                {
5539                   e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
5540                   e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].actionType = e2NodeComponentInfo->componentActionType;
5541                   e2NodeList.removeE2NodeCount++;
5542                   break;
5543                }
5544          }
5545       }
5546       node = node->next;
5547    }
5548
5549    if(BuildAndSendE2NodeConfigUpdate(&e2NodeList) !=ROK)
5550    {
5551       DU_LOG("\nERROR  -->  E2AP : Failed to build and send e2 node config update message to RIC_stub");
5552       return RFAILED;
5553    }
5554    return ROK;
5555 }
5556
5557 /*******************************************************************
5558  *
5559  * @brief Free RIC Subscription Modification Required
5560  *
5561  * @details
5562  *
5563  *    Function : FreeRicSubsModRequired
5564  *
5565  * Functionality: Freqq RIC Subscription Modification required
5566  *
5567  * @param  E2AP Message PDU to be freed
5568  * @return void
5569  *
5570  ******************************************************************/
5571 void FreeRicSubsModRequired(E2AP_PDU_t *e2apMsg)
5572 {
5573    uint8_t ieIdx = 0, arrIdx = 0;
5574    RICsubscriptionModificationRequired_t  *ricSubsModReqd = NULLP;
5575    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
5576    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
5577    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
5578
5579    if(e2apMsg)
5580    {
5581       if(e2apMsg->choice.initiatingMessage)
5582       {
5583          ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired;
5584          if(ricSubsModReqd->protocolIEs.list.array)
5585          {
5586             for(ieIdx = 0; ieIdx < ricSubsModReqd->protocolIEs.list.count; ieIdx++)
5587             {
5588                if(ricSubsModReqd->protocolIEs.list.array[ieIdx])
5589                {
5590                   ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
5591                   switch(ricSubsModReqdIe->id)
5592                   {
5593                      case ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List:
5594                         {
5595                            actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
5596                            if(actionToBeModList->list.array)
5597                            {
5598                               for(arrIdx = 0; arrIdx < actionToBeModList->list.count; arrIdx++)
5599                               { 
5600                                  DU_FREE(actionToBeModList->list.array[arrIdx], \
5601                                     sizeof(RICaction_RequiredToBeModified_ItemIEs_t));
5602                               }
5603                               DU_FREE(actionToBeModList->list.array, actionToBeModList->list.size);
5604                            }
5605                            break;
5606                         }
5607
5608                      case ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List:
5609                         {
5610                            actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
5611                            if(actionToBeRmvList->list.array)
5612                            {
5613                               for(arrIdx = 0; arrIdx < actionToBeRmvList->list.count; arrIdx++)
5614                               { 
5615                                  DU_FREE(actionToBeRmvList->list.array[arrIdx], \
5616                                     sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t));
5617                               }
5618                               DU_FREE(actionToBeRmvList->list.array, actionToBeRmvList->list.size);
5619                            }
5620                            break;
5621                         }
5622
5623                      default:
5624                         break;
5625                   }
5626                   DU_FREE(ricSubsModReqd->protocolIEs.list.array[ieIdx], \
5627                         sizeof(RICsubscriptionModificationRequired_IEs_t));
5628                }
5629             }
5630             DU_FREE(ricSubsModReqd->protocolIEs.list.array, ricSubsModReqd->protocolIEs.list.size);
5631          }
5632          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5633       }
5634       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
5635    }
5636 }
5637
5638 /*******************************************************************
5639  *
5640  * @brief Fill Action required to be modified list
5641  *
5642  * @details
5643  *
5644  *    Function : FillActionReqdToBeModList
5645  *
5646  * Functionality: Fill Action required to be modified list
5647  *
5648  * @param  RIC Actions Required To Be Modified List to be filled
5649  *         Number of actions to be modified
5650  *         RIC Subscription DB
5651  * @return ROK     - success
5652  *         RFAILED - failure
5653  *
5654  ******************************************************************/
5655 uint8_t FillActionReqdToBeModList(RICactions_RequiredToBeModified_List_t *actionToBeModList, uint8_t numActionsMod, \
5656    RicSubscription *ricSubscription)
5657 {
5658    uint8_t arrIdx = 0, actionIdx = 0;
5659    RICaction_RequiredToBeModified_ItemIEs_t *actionToBeMod = NULL;
5660
5661    actionToBeModList->list.count = numActionsMod;
5662    actionToBeModList->list.size = numActionsMod * sizeof(RICaction_RequiredToBeModified_ItemIEs_t *);
5663    DU_ALLOC(actionToBeModList->list.array, actionToBeModList->list.size);
5664    if(!actionToBeModList->list.array)
5665    {
5666       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
5667       return RFAILED;
5668    }
5669
5670    arrIdx = 0;
5671    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
5672    {
5673       if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD)
5674       {
5675          DU_ALLOC(actionToBeModList->list.array[arrIdx], sizeof(RICaction_RequiredToBeModified_ItemIEs_t));
5676          if(!actionToBeModList->list.array[arrIdx])
5677          {
5678             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
5679             return RFAILED;
5680          }
5681          actionToBeMod = (RICaction_RequiredToBeModified_ItemIEs_t *)actionToBeModList->list.array[arrIdx];
5682
5683          actionToBeMod->id = ProtocolIE_IDE2_id_RICaction_RequiredToBeModified_Item;
5684          actionToBeMod->criticality = CriticalityE2_reject;
5685          actionToBeMod->value.present = \
5686             RICaction_RequiredToBeModified_ItemIEs__value_PR_RICaction_RequiredToBeModified_Item;
5687          actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricActionID = \
5688             ricSubscription->actionSequence[actionIdx].actionId;
5689          actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricTimeToWait = RICtimeToWait_w5ms;
5690
5691          arrIdx++;
5692       }
5693    }
5694
5695    return ROK;
5696 }
5697
5698 /*******************************************************************
5699  *
5700  * @brief Fill Action required to be removed list
5701  *
5702  * @details
5703  *
5704  *    Function : FillActionReqdToBeRmvList
5705  *
5706  * Functionality: Fill Action required to be removed list
5707  *
5708  * @param  RIC Actions Required To Be Removed List to be filled
5709  *         Number of actions to be removed
5710  *         RIC Subscription DB
5711  * @return ROK     - success
5712  *         RFAILED - failure
5713  *
5714  ******************************************************************/
5715 uint8_t FillActionReqdToBeRmvList(RICactions_RequiredToBeRemoved_List_t *actionToBeRmvList, uint8_t numActionsRmv, \
5716    RicSubscription *ricSubscription)
5717 {
5718    uint8_t arrIdx = 0, actionIdx = 0;
5719    RICaction_RequiredToBeRemoved_ItemIEs_t *actionToBeRmv = NULL;
5720
5721    actionToBeRmvList->list.count = numActionsRmv;
5722    actionToBeRmvList->list.size = numActionsRmv * sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t *);
5723    DU_ALLOC(actionToBeRmvList->list.array, actionToBeRmvList->list.size);
5724    if(!actionToBeRmvList->list.array)
5725    {
5726       DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
5727       return RFAILED;
5728    }
5729
5730    arrIdx = 0;
5731    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
5732    {
5733       if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL)
5734       {
5735          DU_ALLOC(actionToBeRmvList->list.array[arrIdx], sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t));
5736          if(!actionToBeRmvList->list.array[arrIdx])
5737          {
5738             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
5739             return RFAILED;
5740          }
5741          actionToBeRmv = (RICaction_RequiredToBeRemoved_ItemIEs_t *)actionToBeRmvList->list.array[arrIdx];
5742
5743          actionToBeRmv->id = ProtocolIE_IDE2_id_RICaction_RequiredToBeRemoved_Item;
5744          actionToBeRmv->criticality = CriticalityE2_reject;
5745          actionToBeRmv->value.present = \
5746             RICaction_RequiredToBeRemoved_ItemIEs__value_PR_RICaction_RequiredToBeRemoved_Item;
5747          actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.ricActionID = \
5748             ricSubscription->actionSequence[actionIdx].actionId;
5749          fillE2Cause(&actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.cause, \
5750             ricSubscription->actionSequence[actionIdx].failureCause);
5751
5752          arrIdx++;
5753       }
5754    }
5755
5756    return ROK;
5757 }
5758
5759 /*******************************************************************
5760  *
5761  * @brief Fill RIC Subscription Modification Required IEs
5762  *
5763  * @details
5764  *
5765  *    Function : FillRicSubsModRequired
5766  *
5767  * Functionality: Fill RIC Subscription Modification Required IEs
5768  *
5769  * @param  RIC Subscription Modification Required IEs to be filled
5770  *         RIC Subscription DB
5771  * @return ROK     - success
5772  *         RFAILED - failure
5773  *
5774  ******************************************************************/
5775 uint8_t FillRicSubsModRequired(RICsubscriptionModificationRequired_t *ricSubsModReqd, RicSubscription *ricSubscription)
5776 {
5777    uint8_t ieIdx = 0, elementCnt=0, actionIdx = 0;
5778    uint8_t numActionsMod = 0, numActionsRmv = 0;
5779    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
5780    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
5781    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
5782
5783    /* Count number of Actions to be modified or deleted */
5784    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
5785    {
5786       if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD)
5787          numActionsMod++;
5788       else if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL)
5789          numActionsRmv++;
5790    }
5791
5792    /* Count number of IEs to be added to messages */
5793    elementCnt = 2;
5794    if(numActionsMod)
5795       elementCnt++;
5796    if(numActionsRmv)
5797       elementCnt++;
5798
5799    ricSubsModReqd->protocolIEs.list.count = elementCnt;
5800    ricSubsModReqd->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationRequired_IEs_t *);
5801    DU_ALLOC(ricSubsModReqd->protocolIEs.list.array, ricSubsModReqd->protocolIEs.list.size);
5802    if(!ricSubsModReqd->protocolIEs.list.array)
5803    {
5804       DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
5805       return RFAILED;
5806    }
5807
5808    for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
5809    {
5810       DU_ALLOC(ricSubsModReqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRequired_IEs_t));
5811       if(!ricSubsModReqd->protocolIEs.list.array[ieIdx])
5812       {
5813          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
5814          return RFAILED;
5815       }
5816    }
5817
5818    /* RIC Request ID */
5819    ieIdx = 0;
5820    ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
5821    ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICrequestID;
5822    ricSubsModReqdIe->criticality = CriticalityE2_reject;
5823    ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RICrequestID;
5824    ricSubsModReqdIe->value.choice.RICrequestID.ricRequestorID = ricSubscription->requestId.requestorId;
5825    ricSubsModReqdIe->value.choice.RICrequestID.ricInstanceID = ricSubscription->requestId.instanceId;
5826
5827    /* RAN Function ID */
5828    ieIdx++;
5829    ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
5830    ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RANfunctionID;
5831    ricSubsModReqdIe->criticality = CriticalityE2_reject;
5832    ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RANfunctionID;
5833    ricSubsModReqdIe->value.choice.RANfunctionID = ricSubscription->ranFuncId;
5834
5835    /* RIC Actions Required to be Modified */
5836    if(numActionsMod)
5837    {
5838       ieIdx++;
5839       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
5840       ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List;
5841       ricSubsModReqdIe->criticality = CriticalityE2_reject;
5842       ricSubsModReqdIe->value.present = \
5843          RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeModified_List;
5844       actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
5845
5846       if(FillActionReqdToBeModList(actionToBeModList, numActionsMod, ricSubscription) != ROK)
5847       {
5848          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill actions required to be modified list", __func__);
5849          return RFAILED;
5850       }
5851    }
5852
5853    /* RIC Actions Required to be removed */
5854    if(numActionsRmv)
5855    {
5856       ieIdx++;
5857       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
5858       ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List;
5859       ricSubsModReqdIe->criticality = CriticalityE2_reject;
5860       ricSubsModReqdIe->value.present = \
5861          RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeRemoved_List;
5862       actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
5863
5864       if(FillActionReqdToBeRmvList(actionToBeRmvList, numActionsRmv, ricSubscription) != ROK)
5865       {
5866          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill actions required to be removed list", __func__);
5867          return RFAILED;
5868       }
5869    }
5870
5871    return ROK;
5872 }
5873
5874 /*******************************************************************
5875  *
5876  * @brief Builds and Send RIC Subscription Modification Required
5877  *        message
5878  *
5879  * @details
5880  *
5881  *    Function : BuildAndSendRicSubsModRequired
5882  *
5883  * Functionality:  Builds and Send RIC Subscription Modification 
5884  *    Required message
5885  *
5886  * @param  RIC Subscription DB
5887  * @return ROK     - success
5888  *         RFAILED - failure
5889  *
5890  ******************************************************************/
5891 uint8_t BuildAndSendRicSubsModRequired(RicSubscription *ricSubscription)
5892 {
5893    uint8_t ret = RFAILED;
5894    E2AP_PDU_t        *e2apMsg = NULLP;
5895    RICsubscriptionModificationRequired_t  *ricSubsModReqd = NULLP;
5896    asn_enc_rval_t     encRetVal;       /* Encoder return value */
5897
5898    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Required \n");
5899    while(true)
5900    {
5901       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
5902       if(e2apMsg == NULLP)
5903       {
5904          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
5905          break;
5906       }
5907
5908       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
5909       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5910       if(e2apMsg->choice.initiatingMessage == NULLP)
5911       {
5912          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
5913          break;
5914       }
5915       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
5916       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired;
5917       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionModificationRequired;
5918
5919       ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired;
5920
5921       if(FillRicSubsModRequired(ricSubsModReqd, ricSubscription) != ROK)
5922       {
5923          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Subscription Modification Required IEs", __func__);
5924          break;
5925       }
5926       
5927       /* Encode */
5928       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5929
5930       memset(encBuf, 0, ENC_BUF_MAX_LEN);
5931       encBufSize = 0;
5932       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
5933       if(encRetVal.encoded == ENCODE_FAIL)
5934       {
5935          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Modifiction Required structure (at %s)\n",\
5936                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
5937          break;
5938       }
5939       else
5940       {
5941          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RIC Subscription Modification Required \n");
5942 #ifdef DEBUG_ASN_PRINT
5943          for(int i=0; i< encBufSize; i++)
5944          {
5945             printf("%x",encBuf[i]);
5946          }
5947 #endif
5948       }
5949       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
5950       {
5951          DU_LOG("\nERROR  -->  E2AP : Sending RIC Subscription Modification Required failed");
5952       }
5953
5954       ret = ROK;
5955       break;
5956    }
5957
5958    /* Free RIC Subscription modification required */
5959    FreeRicSubsModRequired(e2apMsg);
5960    return ret;
5961 }
5962
5963 /*******************************************************************
5964  *
5965  * @brief Handles received E2AP message and sends back response  
5966  *
5967  * @details
5968  *
5969  *    Function : E2APMsgHdlr
5970  *
5971  *    Functionality:
5972  *         - Decodes received E2AP control message
5973  *         - Prepares response message, encodes and sends to SCTP
5974  *
5975  * @params[in] 
5976  * @return ROK     - success
5977  *         RFAILED - failure
5978  *
5979  * ****************************************************************/
5980 void E2APMsgHdlr(Buffer *mBuf)
5981 {
5982    int i =0;
5983    char *recvBuf = NULLP;
5984    MsgLen copyCnt =0;
5985    MsgLen recvBufLen =0;
5986    E2AP_PDU_t *e2apMsg = NULLP;
5987    asn_dec_rval_t rval ={0}; /* Decoder return value */
5988    E2AP_PDU_t e2apasnmsg={0} ;
5989
5990    DU_LOG("\nDEBUG   -->  E2AP : Received E2AP message buffer");
5991    ODU_PRINT_MSG(mBuf, 0,0);
5992
5993    /* Copy mBuf into char array to decode it */
5994    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
5995    DU_ALLOC(recvBuf, (Size)recvBufLen);
5996
5997    if(recvBuf == NULLP)
5998    {
5999       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
6000       return;
6001    }
6002    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
6003    {
6004       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
6005       return;
6006    }
6007
6008 #ifdef DEBUG_ASN_PRINT
6009    printf("\nDEBUG   -->  E2AP : Received flat buffer to be decoded : ");
6010    for(i=0; i< recvBufLen; i++)
6011    {
6012       printf("%x",recvBuf[i]);
6013    }
6014 #endif
6015
6016    /* Decoding flat buffer into E2AP messsage */
6017    e2apMsg = &e2apasnmsg;
6018    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
6019
6020    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
6021    DU_FREE(recvBuf, (Size)recvBufLen);
6022
6023    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
6024    {
6025       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
6026       return;
6027    }
6028    printf("\n");
6029    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6030
6031    switch(e2apMsg->present)
6032    {
6033       case E2AP_PDU_PR_unsuccessfulOutcome:
6034          {
6035             switch(e2apMsg->choice.unsuccessfulOutcome->value.present)
6036             {
6037                case UnsuccessfulOutcomeE2__value_PR_E2setupFailure:
6038                   {
6039                      procE2SetupFailure(e2apMsg);
6040                      break;
6041                   }
6042                case UnsuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateFailure:
6043                   {
6044                      procE2NodeConfigUpdateFailure(e2apMsg);
6045                      break;
6046                   }
6047                case UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure:
6048                   {
6049                      procRicServiceUpdateFailure(e2apMsg);
6050                      break;
6051                   }
6052                default:
6053                   {
6054                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome  [%d]",\
6055                            e2apMsg->choice.unsuccessfulOutcome->value.present);
6056                      return;
6057                   }
6058             }
6059             break;
6060          }
6061       case E2AP_PDU_PR_successfulOutcome:
6062          {
6063             switch(e2apMsg->choice.successfulOutcome->value.present)
6064             {
6065                case SuccessfulOutcomeE2__value_PR_E2setupResponse:
6066                   {
6067                      if(!duCb.e2Status)
6068                      {
6069                         procE2SetupRsp(e2apMsg);
6070                      }
6071                      break;
6072                   }
6073                case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge:
6074                   {
6075                      DU_LOG("\nDEBUG   -->  E2AP : E2 node Config update ack message recevied");
6076                      break;
6077                   }
6078                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
6079                   {
6080                      procResetResponse(e2apMsg);
6081                      break;
6082                   }
6083                case SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge:
6084                   {
6085                      procRicServiceUpdateAck(e2apMsg);
6086                      break;
6087                   }
6088
6089
6090                default:
6091                   {
6092                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome  [%d]",\
6093                            e2apMsg->choice.successfulOutcome->value.present);
6094                      return;
6095                   }
6096             }/* End of switch(successfulOutcome) */
6097             free(e2apMsg->choice.successfulOutcome);
6098             break;
6099          }
6100
6101       case E2AP_PDU_PR_initiatingMessage:
6102          {
6103             switch(e2apMsg->choice.initiatingMessage->value.present)
6104             {
6105                case InitiatingMessageE2__value_PR_RICsubscriptionRequest: 
6106                   {
6107                      procRicSubscriptionRequest(e2apMsg);
6108                      break;
6109                   }
6110                case InitiatingMessageE2__value_PR_RICserviceQuery:
6111                   {
6112                      procRicServiceQuery(e2apMsg);
6113                      break;
6114                   }
6115                case InitiatingMessageE2__value_PR_ErrorIndicationE2:
6116                   {
6117                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
6118                      break;
6119                   }
6120                default:
6121                   {
6122                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\
6123                            e2apMsg->choice.initiatingMessage->value.present);
6124                      return;
6125                   }
6126             }/* End of switch(initiatingMessage) */
6127             free(e2apMsg->choice.initiatingMessage);
6128             break;
6129          }
6130       default:
6131          {
6132             DU_LOG("\nERROR  -->  E2AP : Invalid type of e2apMsg->present [%d]",e2apMsg->present);
6133             return;
6134          }
6135          free(e2apMsg);
6136
6137    }/* End of switch(e2apMsg->present) */
6138
6139 } /* End of E2APMsgHdlr */
6140
6141 /**********************************************************************
6142   End of file
6143  **********************************************************************/