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