[Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-534] Handling of reset rsp
[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 void
2186  *
2187  * ****************************************************************/
2188
2189 void procE2SetupRsp(E2AP_PDU_t *e2apMsg)
2190 {
2191    bool invalidTransId = false;
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                   invalidTransId = true;
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                            }
2251                            else
2252                            {
2253                               cmLListDelFrm(&duCb.e2apDb.e2NodeComponentList, node);
2254                               DU_FREE(e2NodeComponentInfo->componentRequestPart, e2NodeComponentInfo->reqBufSize);
2255                               DU_FREE(e2NodeComponentInfo->componentResponsePart, e2NodeComponentInfo->rspBufSize);
2256                               DU_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent));
2257                               DU_FREE(node, sizeof(CmLList));
2258                            }
2259                            break;
2260                         }
2261                      default:
2262                         break;
2263                   }
2264                }
2265                break;
2266             }
2267
2268          default:
2269             {
2270                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2SetupRsp:%ld",
2271                      e2SetRspMsg->protocolIEs.list.array[arrIdx]->id);
2272                break;
2273             }
2274       }
2275
2276       if(invalidTransId == true)
2277       {
2278          break;
2279       }
2280    }
2281    freeAperDecodingOfE2SetupRsp(e2SetRspMsg);
2282
2283    if(invalidTransId == false)
2284    {
2285       if(duSendE2NodeConfigurationUpdate() != ROK)
2286       {
2287          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 node config update");
2288       }
2289    }
2290 }
2291
2292 /*******************************************************************
2293  *
2294  * @brief Free RIC Subscription Request
2295  *
2296  * @details
2297  *
2298  *    Function : freeAperDecodingOfRicSubsReq
2299  *
2300  * Functionality : Free RIC Subscription Request
2301  *
2302  * @return void
2303  *
2304  ******************************************************************/
2305 void freeAperDecodingOfRicSubsReq(RICsubscriptionRequest_t *ricSubscriptionReq)
2306 {
2307    uint8_t idx = 0;
2308    uint8_t elementIdx = 0;
2309    RICsubscriptionDetails_t *subsDetails = NULLP;
2310    RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
2311
2312    if(ricSubscriptionReq->protocolIEs.list.array)
2313    {
2314       for(idx=0; idx < ricSubscriptionReq->protocolIEs.list.count; idx++)
2315       {
2316          switch(ricSubscriptionReq->protocolIEs.list.array[idx]->id)
2317          {
2318             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
2319                {
2320                   subsDetails = &(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails);
2321                   free(subsDetails->ricEventTriggerDefinition.buf);
2322
2323                   if(subsDetails->ricAction_ToBeSetup_List.list.array)
2324                   {
2325                      for(elementIdx = 0; elementIdx < subsDetails->ricAction_ToBeSetup_List.list.count; elementIdx++)
2326                      {
2327                         if(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
2328                         {
2329                            actionItem = (RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx];
2330                            if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
2331                            {
2332                               free(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf);
2333                               free(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition);
2334                            }
2335                            free(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx]);
2336                         }
2337                      }
2338                      free(subsDetails->ricAction_ToBeSetup_List.list.array);
2339                   }
2340                   break;
2341                }
2342          }
2343          free(ricSubscriptionReq->protocolIEs.list.array[idx]);
2344       }
2345       free(ricSubscriptionReq->protocolIEs.list.array);
2346    }
2347 }
2348
2349 /*******************************************************************
2350  *
2351  * @brief Free Event Trigger Definition
2352  *
2353  * @details
2354  *
2355  *    Function : freeAperDecodingOfEventTriggerDef
2356  *
2357  *    Functionality: Free Event Trigger Definition
2358  *
2359  * @params[in] E2SM-KPM Event Trigger Definition
2360  * @return void
2361  *
2362  * ****************************************************************/
2363 void  freeAperDecodingOfEventTriggerDef(E2SM_KPM_EventTriggerDefinition_t *eventTiggerDef)
2364 {
2365    if(eventTiggerDef)
2366    {
2367       switch(eventTiggerDef->eventDefinition_formats.present)
2368       {
2369          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING:
2370             break;
2371
2372          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1:
2373             free(eventTiggerDef->eventDefinition_formats.choice.eventDefinition_Format1);
2374             break;
2375       }
2376    }
2377 }
2378
2379 /*******************************************************************
2380  *
2381  * @brief Extract E2SM-KPM Event trigger definition
2382  *
2383  * @details
2384  *
2385  *    Function : extractEventTriggerDef
2386  *
2387  * Functionality : This function :
2388  *     - Decodes E2SM-KPM Event Trigger Definition
2389  *     - Validates that even trigger style is supported by E2 node
2390  *     - Stores event trigger details in local DB
2391  *
2392  * @params[in] RAN Function Database structure
2393  *             RIC Subscription Info to be added to RAN function
2394  *             RIC Event Trigger Definition buffer received from RIC
2395  * @return ROK     - success
2396  *         RFAILED - failure
2397  *
2398  ******************************************************************/
2399 uint8_t extractEventTriggerDef(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \
2400    RICeventTriggerDefinition_t *ricEventTriggerDef, E2FailureCause *failureCause)
2401 {
2402    uint8_t ret = RFAILED;
2403    uint8_t eventIdx = 0;
2404    asn_dec_rval_t rval ={0};
2405    E2SM_KPM_EventTriggerDefinition_t eventTiggerDef, *eventTiggerDefPtr = NULLP;
2406
2407    /* Decoding E2SM-KPM Even Trigger Definition */
2408    eventTiggerDefPtr = &eventTiggerDef;
2409    memset(eventTiggerDefPtr, 0, sizeof(E2SM_KPM_EventTriggerDefinition_t));
2410
2411    rval = aper_decode(0, &asn_DEF_E2SM_KPM_EventTriggerDefinition, (void **)&eventTiggerDefPtr, ricEventTriggerDef->buf,\
2412          ricEventTriggerDef->size, 0, 0);
2413    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
2414    {
2415       DU_LOG("\nERROR  -->  E2AP : ASN decode failed for E2SM-KPM Event Trigger Definition");
2416       failureCause->causeType = E2_PROTOCOL; 
2417       failureCause->cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE;
2418       return RFAILED;
2419    }
2420    printf("\n");
2421    xer_fprint(stdout, &asn_DEF_E2SM_KPM_EventTriggerDefinition, eventTiggerDefPtr);
2422
2423    /* Validating the received event trigger definition format */
2424    for(eventIdx = 0; eventIdx < ranFuncDb->numOfEventTriggerStyleSupported; eventIdx++)
2425    {
2426       if((eventTiggerDefPtr->eventDefinition_formats.present != \
2427          E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING) && \
2428          (eventTiggerDefPtr->eventDefinition_formats.present == ranFuncDb->eventTriggerStyleList[eventIdx].formatType))
2429       {
2430          ricSubscriptionInfo->eventTriggerDefinition.formatType = ranFuncDb->eventTriggerStyleList[eventIdx].formatType;
2431          ricSubscriptionInfo->eventTriggerDefinition.choice.format1.reportingPeriod = \
2432             eventTiggerDefPtr->eventDefinition_formats.choice.eventDefinition_Format1->reportingPeriod;
2433
2434          ret = ROK;
2435          break;
2436       }
2437    }
2438
2439    if(ret == RFAILED)
2440    {
2441       failureCause->causeType = E2_RIC_REQUEST;
2442       failureCause->cause = E2_EVENT_TRIGGER_NOT_SUPPORTED;
2443    }
2444    /* Free E2SM_KPM_EventTriggerDefinition_t */
2445    freeAperDecodingOfEventTriggerDef(eventTiggerDefPtr);
2446    return ret;
2447 }
2448
2449 /*******************************************************************
2450  *
2451  * @brief Free RIC Action Definition
2452  *
2453  * @details
2454  *
2455  *    Function :  freeAperDecodingOfRicActionDefinition
2456  *
2457  *    Functionality: Free RIC Action Definition
2458  *
2459  * @params[in] E2SM-KPM Action definition
2460  * @return void
2461  *
2462  * ****************************************************************/
2463 void  freeAperDecodingOfRicActionDefinition(E2SM_KPM_ActionDefinition_t *actionDef)
2464 {
2465    uint8_t  elementIdx = 0;
2466    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
2467    MeasurementInfoItem_t *measItem = NULLP;
2468
2469    switch(actionDef->actionDefinition_formats.present)
2470    {
2471       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
2472          {
2473             if(actionDef->actionDefinition_formats.choice.actionDefinition_Format1)
2474             {
2475                actionFormat1 = actionDef->actionDefinition_formats.choice.actionDefinition_Format1;
2476                if(actionFormat1->measInfoList.list.array)
2477                {
2478                   for(elementIdx = 0; elementIdx < actionFormat1->measInfoList.list.count; elementIdx++)
2479                   {
2480                      if(actionFormat1->measInfoList.list.array[elementIdx])
2481                      {
2482                         measItem = actionFormat1->measInfoList.list.array[elementIdx];
2483                         switch(measItem->measType.present)
2484                         {
2485                            case MeasurementType_PR_NOTHING:
2486                               break;
2487
2488                            case MeasurementType_PR_measName:
2489                            {
2490                               free(measItem->measType.choice.measName.buf);
2491                               break;
2492                            }
2493
2494                            case MeasurementType_PR_measID:
2495                               break;
2496                         }
2497                         free(measItem);
2498                      }
2499                   }
2500                   free(actionFormat1->measInfoList.list.array);
2501                }
2502                free(actionFormat1);
2503             }
2504             break;
2505          }
2506       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format2:
2507       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format3:
2508       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format4:
2509       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format5:
2510       default:
2511          break;   
2512    }
2513 }
2514
2515 /*******************************************************************
2516  *
2517  * @brief Extract Measurement Info list from action definition
2518  *
2519  * @details
2520  *
2521  *    Function : extractMeasInfoList
2522  *
2523  * Functionality : This function :
2524  *     - Traverses Measurement-to-be-subscribed list
2525  *     - Validates that each measurement in Measurement-to-be-subscribed
2526  *       list is supported in RAN-Function->Measurement-supported list.
2527  *     - If all measurements in an action is supported by RAN function,
2528  *       it is added to measurement-subscribed list in local DB
2529  *
2530  * @params[in] Measurement Info supported list by RAN function
2531  *             Measurement Info to be subscribed as requested by RIC
2532  *             Measurement Info finally subscribed
2533  *             Memory failure indicator
2534  * @return ROK     - success
2535  *         RFAILED - failure
2536  *
2537  ******************************************************************/
2538 uint8_t extractMeasInfoList(CmLListCp *measInfoSupportedList, MeasurementInfoList_t *measInfoToBeSubscribedList, \
2539    CmLListCp *measInfoSubscribedList, bool *memFailure)
2540 {
2541    uint8_t elementIdx = 0;
2542    MeasurementInfoForAction *measInfoSupportedDb = NULLP;
2543    MeasurementInfo *measInfoSubscribedDb = NULLP, *measInfoToDel = NULLP;
2544    CmLList *supportedMeasNode = NULLP, *measToAddNode = NULLP, *measToDelNode = NULLP;;
2545    MeasurementInfoItem_t *measItem = NULLP;
2546
2547    /* Validate Measurement list is supported by E2 node. 
2548     *
2549     * Traverse and compare the Measurement-Supported List in E2
2550     * node with Measurement-to-be-subscribed list received from RIC.
2551     * If a match is found, add it to measurement-subscription list.
2552     */
2553    for(elementIdx = 0; elementIdx < measInfoToBeSubscribedList->list.count; elementIdx++)
2554    {
2555       measInfoSubscribedDb = NULLP;
2556       measToAddNode = NULLP;
2557       measItem = measInfoToBeSubscribedList->list.array[elementIdx];
2558
2559       CM_LLIST_FIRST_NODE(measInfoSupportedList, supportedMeasNode);
2560       while(supportedMeasNode)
2561       {
2562          measInfoSupportedDb = (MeasurementInfoForAction*)supportedMeasNode->node;
2563          switch(measItem->measType.present)
2564          {
2565             case MeasurementType_PR_measName:
2566                {
2567                   if(!strcmp(measInfoSupportedDb->measurementTypeName, (char *)measItem->measType.choice.measName.buf))
2568                   {
2569                      DU_ALLOC(measInfoSubscribedDb, sizeof(MeasurementInfo));
2570                   }
2571                   break;
2572                }
2573
2574             case MeasurementType_PR_measID:
2575                {
2576                   if(measInfoSupportedDb->measurementTypeId == measItem->measType.choice.measID)
2577                   {
2578                      DU_ALLOC(measInfoSubscribedDb, sizeof(MeasurementInfo));
2579                   }
2580                   break;
2581                }
2582
2583             default:
2584                {
2585                   DU_LOG("\nERROR  ->  DUAPP: Invalid Measurement-type identifier in \
2586                         E2SM-KPM Action Definition Format");
2587                   break;
2588                }
2589          } /* End of switch, for measurement type identifier */
2590
2591          /* If measurement type is supported, add to measurement-subscription list */
2592          if(measInfoSubscribedDb)
2593          {
2594             measInfoSubscribedDb->measurementTypeId = measInfoSupportedDb->measurementTypeId;
2595             memcpy(measInfoSubscribedDb->measurementTypeName, measInfoSupportedDb->measurementTypeName, \
2596                   strlen(measInfoSupportedDb->measurementTypeName));
2597
2598             DU_ALLOC(measToAddNode, sizeof(CmLList));
2599             if(measToAddNode)
2600             {
2601                measToAddNode->node = (PTR) measInfoSubscribedDb;
2602                cmLListAdd2Tail(measInfoSubscribedList, measToAddNode);
2603
2604                /* Break out of while loop if measurement info is found in measurement-supported list  */
2605                break;
2606             }
2607             else
2608             {
2609                DU_FREE(measInfoSubscribedDb, sizeof(MeasurementInfo));
2610                measInfoSubscribedDb = NULLP;
2611                *memFailure = true;
2612                break;
2613             }
2614          }
2615
2616          supportedMeasNode = supportedMeasNode->next;  
2617
2618       } /* End of while for traversing measurement-supported list in a report style */
2619
2620       /* If a measurement-to-be-subscribed is not found in measurement-supported list in this report style
2621        * Then :
2622        * Delete all entries from measurement-subscription list and
2623        * Break out of for loop to search in next report style */
2624       if(!measInfoSubscribedDb)
2625       {
2626          deleteMeasurementInfoList(measInfoSubscribedList);
2627          break;
2628       }
2629
2630    } /* End of for loop , traversing measurement-to-be-subscribed list */
2631
2632    /* If all measurement-to-be-subscribed was found in measurement-supported list and 
2633     * was added to measurement-subscription list successfully, return from here */
2634    if(measInfoToBeSubscribedList->list.count == measInfoSubscribedList->count)
2635       return ROK;
2636
2637    return RFAILED;
2638 }
2639
2640 /*******************************************************************
2641  *
2642  * @brief Extract E2SM-KPM Action definition
2643  *
2644  * @details
2645  *
2646  *    Function : extractRicActionDef
2647  *
2648  * Functionality : This function :
2649  *     - Decodes E2SM-KPM Action Definition
2650  *     - Validates that action is supported by E2 node
2651  *     - Stores action details in local DB
2652  *
2653  * @params[in] RAN Function Database structure
2654  *             RIC subscription's Action definition to be added to 
2655  *                RAN function
2656  *             RIC Action Definition buffer received from RIC
2657  * @return ROK     - success
2658  *         RFAILED - failure
2659  *
2660  ******************************************************************/
2661 uint8_t extractRicActionDef(RanFunction *ranFuncDb, ActionDefinition *actionDefDb, RICactionDefinition_t *ricActionDef,\
2662    E2FailureCause *failureCause)
2663 {
2664    bool memFailure = false;
2665    uint8_t styleIdx = 0;
2666    asn_dec_rval_t rval ={0};
2667
2668    E2SM_KPM_ActionDefinition_t actionDef, *actionDefPtr = NULLP;
2669    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
2670    CmLListCp *measInfoSupportedList = NULLP;
2671    CmLListCp *measInfoSubscribedList = NULLP;
2672
2673    /* Decoding E2SM-KPM Action Definition */
2674    actionDefPtr = &actionDef;
2675    memset(actionDefPtr, 0, sizeof(E2SM_KPM_EventTriggerDefinition_t));
2676
2677    rval = aper_decode(0, &asn_DEF_E2SM_KPM_ActionDefinition, (void **)&actionDefPtr, ricActionDef->buf,\
2678          ricActionDef->size, 0, 0);
2679    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
2680    {
2681       DU_LOG("\nERROR  -->  E2AP : ASN decode failed for E2SM-KPM Action Definition");
2682       failureCause->causeType = E2_PROTOCOL;
2683       failureCause->cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE;
2684       return RFAILED;
2685    }
2686    printf("\n");
2687    xer_fprint(stdout, &asn_DEF_E2SM_KPM_ActionDefinition, actionDefPtr);
2688
2689
2690    /* Validate if Report style to subscribe is supported by E2 Node */
2691    for(styleIdx= 0; styleIdx < ranFuncDb->numOfReportStyleSupported; styleIdx++)
2692    {
2693       /* Validate Report style type and report style format type is supported by E2 Node */
2694       if((ranFuncDb->reportStyleList[styleIdx].reportStyle.styleType == actionDefPtr->ric_Style_Type) &&
2695             (ranFuncDb->reportStyleList[styleIdx].reportStyle.formatType == actionDefPtr->actionDefinition_formats.present))
2696       {
2697          /* Fetch Report stype type and format type */
2698          actionDefDb->styleType = actionDefPtr->ric_Style_Type;
2699          actionDefDb->formatType = actionDefPtr->actionDefinition_formats.present;
2700
2701          switch(actionDefPtr->actionDefinition_formats.present)
2702          {
2703             case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
2704                {
2705                   actionFormat1 = actionDefPtr->actionDefinition_formats.choice.actionDefinition_Format1; 
2706
2707                   /* Fetch granularity period */
2708                   actionDefDb->choice.format1.granularityPeriod = actionFormat1->granulPeriod;
2709
2710                   /* Validate and add the Measurement to subscription list */
2711                   measInfoSupportedList = &ranFuncDb->reportStyleList[styleIdx].measurementInfoList;
2712                   measInfoSubscribedList = &actionDefDb->choice.format1.measurementInfoList;
2713                   if(extractMeasInfoList(measInfoSupportedList, &actionFormat1->measInfoList, \
2714                      measInfoSubscribedList, &memFailure) == ROK)
2715                   {
2716                      if(!memFailure)
2717                      {
2718                         /* Free E2SM_KPM_ActionDefinition_t */
2719                         freeAperDecodingOfRicActionDefinition(actionDefPtr);
2720                         return ROK;
2721                      }
2722                   }
2723
2724                   break;  /* End of E2SM-KPM Action definition format 1 case */
2725                }
2726
2727             default :
2728                {
2729                   DU_LOG("\nERROR  ->  DUAPP: Only E2SM-KPM Action Definition Format 1 is supported");
2730                   break;
2731                }
2732          } /* End of switch for E2SM-KPM Action definition formats */
2733       }
2734
2735       if(memFailure)
2736       {
2737          failureCause->causeType = E2_MISCELLANEOUS;
2738          failureCause->cause = E2_MISCELLANEOUS_CAUSE_UNSPECIFIED; 
2739          break;
2740       }
2741    } /* End of for loop, traversing Report-styles-supported list in E2 node */
2742
2743    /* Memset action Db and Free E2SM_KPM_ActionDefinition_t */
2744    memset(actionDefDb, 0, sizeof(ActionDefinition));
2745    freeAperDecodingOfRicActionDefinition(actionDefPtr);
2746
2747    if(failureCause->causeType == E2_NOTHING)
2748    {
2749       failureCause->causeType = E2_RIC_REQUEST;
2750       failureCause->cause = E2_ACTION_NOT_SUPPORTED;
2751    }
2752    return RFAILED;
2753 }
2754
2755 /*******************************************************************
2756  *
2757  * @brief Extract RIC Action to be setup
2758  *
2759  * @details
2760  *
2761  *    Function : extractRicActionToBeSetup
2762  *
2763  * Functionality : This function :
2764  *     - Validates that each action-to-be-setup is supported by E2 node
2765  *     - Stores event trigger details in local DB
2766  *
2767  * @params[in] RAN Function Database structure
2768  *             RIC Subscription Info to be added to RAN function
2769  *             RIC Action To Be Setup List received from RIC
2770  * @return ROK     - success
2771  *         RFAILED - failure
2772  *
2773  ******************************************************************/
2774 uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \
2775    RICactions_ToBeSetup_List_t *actionList, E2FailureCause *failureCause, PendingSubsRspInfo *subsRsp)
2776 {
2777    uint8_t actionIdx = 0;
2778    uint8_t ricActionId = 0;
2779    RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
2780
2781    if(actionList->list.array)
2782    {
2783       for(actionIdx = 0; actionIdx < actionList->list.count; actionIdx++)
2784       {
2785          actionItem =(RICaction_ToBeSetup_ItemIEs_t *)actionList->list.array[actionIdx];
2786          switch(actionItem->id)
2787          {
2788             case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item:
2789                {
2790                   /* If Action type is REPORT and 
2791                    * If RIC action definition's extraction and validation passes, 
2792                    * Then : 
2793                    * This action is added to action sequence list of subscription info */
2794                   ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
2795
2796                   if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType == RICactionType_report)
2797                   {
2798                      ricSubscriptionInfo->actionSequence[ricActionId].actionId = ricActionId;
2799                      ricSubscriptionInfo->actionSequence[ricActionId].type = REPORT;
2800
2801                      if(extractRicActionDef(ranFuncDb, &ricSubscriptionInfo->actionSequence[ricActionId].definition, \
2802                         actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, failureCause) == ROK)
2803                      {
2804                         ricSubscriptionInfo->actionSequence[ricActionId].action = CONFIG_ADD;
2805                         ricSubscriptionInfo->numOfActions++;
2806                         break;
2807                      }
2808                   }
2809
2810                   /* In case of any failure, action is rejected
2811                    * Added to rejected-action-list in subscription response */
2812                   deleteActionSequence(&ricSubscriptionInfo->actionSequence[ricActionId]);
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      measValNode= measValNode->next;  
3434      /* Once the measurement record is added to the message, delete it from DB */
3435      measVal = 0;
3436    }
3437    deleteMeasuredValueList(&measInfoDb->measuredValue);
3438    return ROK;
3439 }
3440
3441 /*******************************************************************
3442  *
3443  * @brief Fills measuerement data
3444  *
3445  * @details
3446  *
3447  *    Function : fillMeasData
3448  *
3449  * Functionality: Fill all measurement recorded for all measurements
3450  *    in an action in a RIC subscription
3451  *
3452  * @param  Measurement data to be filled
3453  *         Measurement info list from an action DB
3454  * @return ROK     - success
3455  *         RFAILED - failure
3456  *
3457  ******************************************************************/
3458 uint8_t fillMeasData(MeasurementData_t *measData, CmLListCp *measInfoListDb)
3459 {
3460   uint8_t measIdx = 0;
3461   CmLList *measInfoNode = NULLP;
3462   MeasurementInfo *measInfoDb = NULLP;
3463   MeasurementRecord_t *measRecord = NULLP;
3464
3465   measData->list.count = measInfoListDb->count;
3466   measData->list.size = measData->list.count * sizeof(MeasurementDataItem_t *);
3467
3468   DU_ALLOC(measData->list.array, measData->list.size);
3469   if(!measData->list.array)
3470   {
3471      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3472      return RFAILED;
3473   }
3474
3475   measIdx = 0;
3476   CM_LLIST_FIRST_NODE(measInfoListDb, measInfoNode);
3477   while(measInfoNode)
3478   {
3479      measInfoDb = (MeasurementInfo *)measInfoNode->node;
3480      if(measInfoDb)
3481      {
3482         DU_ALLOC(measData->list.array[measIdx], sizeof(MeasurementDataItem_t));
3483         if(!measData->list.array[measIdx])
3484         {
3485            DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3486            return RFAILED;
3487         }
3488
3489         measRecord = &measData->list.array[measIdx]->measRecord;
3490         if(fillMeasRecord(measRecord, measInfoDb) != ROK)
3491         {
3492            DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement record");
3493            return RFAILED;
3494         }
3495         measIdx++;
3496      }
3497      measInfoNode = measInfoNode->next;
3498   }
3499
3500   return ROK;
3501 }
3502
3503 /*******************************************************************
3504  *
3505  * @brief Fill all measurement info
3506  *
3507  * @details
3508  *
3509  *    Function : fillMeasInfoList
3510  *
3511  * Functionality: Fills all measurement info belonging to an action
3512  *  in a RIC subscription
3513  *
3514  * @param   Measurement Info list to be filled
3515  *          Measurement Info list from E2AP DB
3516  * @return ROK     - success
3517  *         RFAILED - failure
3518  *
3519  ******************************************************************/
3520 uint8_t fillMeasInfoList(MeasurementInfoList_t *measInfoList, CmLListCp *measInfoListDb)
3521 {
3522    uint8_t measInfoIdx = 0;
3523    CmLList *measInfoNode = NULLP;
3524    MeasurementInfo *measInfoDb = NULLP;
3525    MeasurementInfoItem_t *measInfoItem = NULLP;
3526
3527    measInfoList->list.count = measInfoListDb->count;
3528    measInfoList->list.size = measInfoList->list.count * sizeof(MeasurementInfoItem_t *);
3529
3530    DU_ALLOC(measInfoList->list.array, measInfoList->list.size);
3531    if(!measInfoList->list.array)
3532    {
3533       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3534       return RFAILED;
3535    }
3536
3537    measInfoIdx = 0;
3538    CM_LLIST_FIRST_NODE(measInfoListDb, measInfoNode);
3539    while(measInfoNode)
3540    {
3541       DU_ALLOC(measInfoList->list.array[measInfoIdx], sizeof(MeasurementInfoItem_t));
3542       if(!measInfoList->list.array[measInfoIdx])
3543       {
3544          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3545          return RFAILED;
3546       }
3547
3548       measInfoItem = measInfoList->list.array[measInfoIdx];
3549       measInfoDb = (MeasurementInfo *)measInfoNode->node;
3550       if(measInfoDb)
3551       {
3552          /* Measurement Type */
3553          measInfoItem->measType.present = MeasurementType_PR_measName;
3554          measInfoItem->measType.choice.measName.size = strlen(measInfoDb->measurementTypeName);
3555
3556          DU_ALLOC(measInfoItem->measType.choice.measName.buf, measInfoItem->measType.choice.measName.size);
3557          if(!measInfoItem->measType.choice.measName.buf)
3558          {
3559             DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3560             return RFAILED;
3561          }
3562
3563          memcpy(measInfoItem->measType.choice.measName.buf, measInfoDb->measurementTypeName,\
3564             measInfoItem->measType.choice.measName.size);
3565
3566          measInfoIdx++;
3567       }
3568       measInfoNode = measInfoNode->next;
3569       measInfoDb = NULLP;
3570    }
3571
3572    return ROK;
3573 }
3574
3575  /*******************************************************************
3576  *
3577  * @brief Fill E2SM-KPM Indication Message Format 1
3578  *
3579  * @details
3580  *
3581  *    Function : fillE2smKpmIndMsgFormat1
3582  *
3583  * Functionality: Fill E2SM-KPM Indication Message Format 1
3584  *
3585  * @param  Format 1 Message to be filled
3586  *         Action Definition format 1 from E2AP DB
3587  * @return ROK     - success
3588  *         RFAILED - failure
3589  *
3590  ******************************************************************/
3591 uint8_t fillE2smKpmIndMsgFormat1(E2SM_KPM_IndicationMessage_Format1_t *format1Msg, ActionDefFormat1 *format1)
3592 {
3593   /* Measurement Data */
3594   if(fillMeasData(&format1Msg->measData, &format1->measurementInfoList) != ROK)
3595   {
3596      DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement data");
3597      return RFAILED;
3598   }
3599
3600   /* Measurement Information */
3601   DU_ALLOC(format1Msg->measInfoList, sizeof(MeasurementInfoList_t));
3602   if(!format1Msg->measInfoList)
3603   {
3604      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3605      return RFAILED;
3606   }
3607
3608   if(fillMeasInfoList(format1Msg->measInfoList, &format1->measurementInfoList) != ROK)
3609   {
3610      DU_LOG("\nERROR  -->  E2AP : Failed to fill measurement information list");
3611      return RFAILED;
3612   }
3613
3614   /* Granularity Period */
3615   DU_ALLOC(format1Msg->granulPeriod, sizeof(GranularityPeriod_t));
3616   if(!format1Msg->granulPeriod)
3617   {
3618      DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3619      return RFAILED;
3620   }
3621   *(format1Msg->granulPeriod) = format1->granularityPeriod;
3622
3623   return ROK;
3624 }
3625
3626 /*******************************************************************
3627  *
3628  * @brief Fill RIC Indication Message buffer
3629  *
3630  * @details
3631  *
3632  *    Function : fillRicIndMsgBuf
3633  *
3634  * Functionality: Fill E2SM-KPM Indication Message
3635  *    Encode this message and copy to RIC Indication Message buffer
3636  * 
3637  * @param  RIC Indication Message buffer to be filled
3638  *         Source action info from E2AP DB
3639  * @return ROK     - success
3640  *         RFAILED - failure
3641  *
3642  ******************************************************************/
3643 uint8_t fillRicIndMsgBuf(RICindicationMessage_t *ricIndMsgBuf, ActionInfo *actionInfo)
3644 {
3645    uint8_t ret = RFAILED;
3646    bool failedInFormat = false;
3647    E2SM_KPM_IndicationMessage_t e2smKpmIndMsg;
3648    asn_enc_rval_t   encRetVal;        /* Encoder return value */
3649
3650    memset(&e2smKpmIndMsg, 0, sizeof(E2SM_KPM_IndicationMessage_t));
3651
3652    while(true)
3653    {
3654       /* E2SM-KPM Indication message format type */
3655       e2smKpmIndMsg.indicationMessage_formats.present = actionInfo->definition.formatType;
3656       switch(e2smKpmIndMsg.indicationMessage_formats.present)
3657       {
3658          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format1:
3659             {
3660                /* E2SM-KPM Indication message format 1 */
3661                DU_ALLOC(e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1, \
3662                      sizeof(E2SM_KPM_IndicationMessage_Format1_t));
3663                if(!e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1)
3664                {
3665                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3666                   failedInFormat = true;
3667                   break;
3668                }
3669
3670                if(fillE2smKpmIndMsgFormat1(e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1, \
3671                   &actionInfo->definition.choice.format1) != ROK)
3672                {
3673                   DU_LOG("\nERROR  -->  E2AP : Failed to fill E2SM-KPM Indication message format 1");
3674                   failedInFormat = true;
3675                   break;
3676                }
3677                break;
3678             }
3679
3680          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_NOTHING:
3681          case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format2:
3682          default:
3683             {
3684                DU_LOG("\nERROR  -->  E2AP : fillRicIndMsgBuf: Only Format 1 supported");
3685                failedInFormat = true;
3686                break;
3687             }
3688       }
3689
3690       if(failedInFormat)
3691          break;
3692
3693       /* Encode E2SM-KPM Indication Message */
3694       xer_fprint(stdout, &asn_DEF_E2SM_KPM_IndicationMessage, &e2smKpmIndMsg);
3695       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3696       encBufSize = 0;
3697       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_IndicationMessage, 0, &e2smKpmIndMsg, PrepFinalEncBuf, encBuf);
3698       if(encRetVal.encoded == ENCODE_FAIL)
3699       {
3700          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM Indication Message (at %s)\n",\
3701                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3702          break;
3703       }
3704       else
3705       {
3706          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SM-KPM Indication Message \n");
3707 #ifdef DEBUG_ASN_PRINT
3708          for(int i=0; i< encBufSize; i++)
3709          {
3710             printf("%x",encBuf[i]);
3711          } 
3712 #endif
3713       }
3714
3715       /* Copy encoded string to RIC Indication Message buffer */
3716       ricIndMsgBuf->size = encBufSize;
3717       DU_ALLOC(ricIndMsgBuf->buf, ricIndMsgBuf->size);
3718       if(!ricIndMsgBuf->buf)
3719       {
3720          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3721          break;
3722       }
3723       memset(ricIndMsgBuf->buf, 0, ricIndMsgBuf->size);
3724       memcpy(ricIndMsgBuf->buf, encBuf, encBufSize);
3725
3726       ret = ROK;
3727       break;
3728    }
3729
3730    /* Free E2SM-KPM Indication Message */
3731    FreeE2smKpmIndicationMessage(&e2smKpmIndMsg);
3732
3733    return ret;
3734 }
3735
3736 /*******************************************************************
3737  *
3738  * @brief Free E2SM-KPM Indication Header
3739  *
3740  * @details
3741  *
3742  *    Function : FreeE2smKpmIndicationHeader
3743  *
3744  * Functionality: Free E2SM-KPM Indication Header
3745  * 
3746  * @param  E2SM-KPM Indication Header to be free
3747  * @return void
3748  *
3749  ******************************************************************/
3750 void FreeE2smKpmIndicationHeader(E2SM_KPM_IndicationHeader_t *e2smKpmIndHdr)
3751 {
3752    E2SM_KPM_IndicationHeader_Format1_t *format1 = NULLP;
3753
3754    if(e2smKpmIndHdr)
3755    {
3756       switch(e2smKpmIndHdr->indicationHeader_formats.present)
3757       {
3758          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_indicationHeader_Format1:
3759             {
3760                if(e2smKpmIndHdr->indicationHeader_formats.choice.indicationHeader_Format1)
3761                {
3762                   format1 = e2smKpmIndHdr->indicationHeader_formats.choice.indicationHeader_Format1;
3763
3764                   DU_FREE(format1->colletStartTime.buf, format1->colletStartTime.size);
3765                   DU_FREE(format1, sizeof(E2SM_KPM_IndicationHeader_Format1_t));
3766                }
3767                break;
3768             }
3769          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_NOTHING:
3770          default:
3771             break;
3772       }
3773    }
3774 }
3775
3776 /*******************************************************************
3777  *
3778  * @brief Fill RIC Indication Header buffer
3779  *
3780  * @details
3781  *
3782  *    Function : fillRicIndHeader
3783  *
3784  * Functionality: Fill E2SM-KPM Indication Header
3785  *    Encode this message and copy to RIC Indication Header buffer
3786  * 
3787  * @param  RIC Indication Header buffer to be filled
3788  *         Source RIC subscription info from E2AP DB
3789  * @return ROK     - success
3790  *         RFAILED - failure
3791  *
3792  ******************************************************************/
3793 uint8_t fillRicIndHeader(RICindicationHeader_t *ricIndHdr, RicSubscription *ricSubsInfo)
3794 {
3795    uint8_t ret = RFAILED;
3796    uint8_t secBufIdx = 0, milliSecBufIdx = 0;
3797    int8_t byteIdx = 0;
3798    bool formatFailure = false;
3799    RanFunction *ranFunc = NULLP;
3800    ReportStartTime *startTime = NULLP;
3801    E2SM_KPM_IndicationHeader_t e2smKpmIndHdr;
3802    E2SM_KPM_IndicationHeader_Format1_t *format1 = NULLP;
3803    asn_enc_rval_t   encRetVal;        /* Encoder return value */
3804
3805    while(true)
3806    {
3807       ranFunc = fetchRanFuncFromRanFuncId(ricSubsInfo->ranFuncId);
3808       if(ranFunc == NULLP)
3809       {
3810          DU_LOG("\nERROR  -->  E2AP : RAN Function ID [%d] not found", ricSubsInfo->ranFuncId);
3811          break;
3812       }
3813
3814       memset(&e2smKpmIndHdr, 0, sizeof(E2SM_KPM_IndicationHeader_t));
3815
3816       e2smKpmIndHdr.indicationHeader_formats.present = ranFunc->ricIndicationHeaderFormat;
3817       switch(e2smKpmIndHdr.indicationHeader_formats.present)
3818       {
3819          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_indicationHeader_Format1:
3820             {
3821                DU_ALLOC(e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1, \
3822                      sizeof(E2SM_KPM_IndicationHeader_Format1_t));
3823                if(!e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1)
3824                {
3825                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3826                   formatFailure = true;
3827                   break;
3828                }
3829                format1 = e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1;
3830
3831                /* Fetch reporting period start time from DB */
3832                switch(ricSubsInfo->eventTriggerDefinition.formatType)
3833                {
3834                   case 1:
3835                   {
3836                      startTime = &ricSubsInfo->eventTriggerDefinition.choice.format1.startTime;
3837                   }
3838                }
3839
3840                format1->colletStartTime.size = 8 * sizeof(uint8_t);
3841                DU_ALLOC(format1->colletStartTime.buf, format1->colletStartTime.size);
3842                if(!format1->colletStartTime.buf)
3843                {
3844                   DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3845                   formatFailure = true;
3846                   break;
3847                }
3848
3849                /* As per O-RAN.WG3.E2SM-KPM-R003-v03.00, section 8.3.12 and
3850                 * RFC 5905, section 6 :
3851                 * Time stamp has a 64-bit format where first 32-bit is seconds
3852                 * and next 32-bit is fraction in picosecond-level.
3853                 * This fraction has been rounded in microseconds.
3854                 *
3855                 * Hence,
3856                 * Storing 32-bit seconds at MSB 0-3 and
3857                 * 32-bit milliseconds at next 4 bytes i.e. bytes 4-7
3858                 */
3859                secBufIdx = 0;
3860                milliSecBufIdx = 4;
3861                for(byteIdx = 3; byteIdx >= 0; byteIdx--)
3862                {
3863                   format1->colletStartTime.buf[secBufIdx++] = startTime->timeInSec >> (8*byteIdx);
3864                   format1->colletStartTime.buf[milliSecBufIdx++] = startTime->timeInMilliSec >> (8*byteIdx);
3865                }
3866                break;
3867             }
3868
3869          case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_NOTHING:
3870          default:
3871          {
3872              DU_LOG("\nERROR  -->  E2AP : Only E2SM-KPM Indication Header Format 1 supported");
3873              formatFailure = true;
3874              break;
3875          }
3876       }
3877
3878       if(formatFailure)
3879          break;
3880
3881       /* Encode E2SM-KPM Indication Header */
3882       xer_fprint(stdout, &asn_DEF_E2SM_KPM_IndicationHeader, &e2smKpmIndHdr);
3883       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3884       encBufSize = 0;
3885       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_IndicationHeader, 0, &e2smKpmIndHdr, PrepFinalEncBuf, encBuf);
3886       if(encRetVal.encoded == ENCODE_FAIL)
3887       {
3888          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM Indication Header (at %s)\n",\
3889                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3890          break;
3891       }
3892       else
3893       {
3894          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SM-KPM Indication Header \n");
3895 #ifdef DEBUG_ASN_PRINT
3896          for(int i=0; i< encBufSize; i++)
3897          {
3898             printf("%x",encBuf[i]);
3899          } 
3900 #endif
3901       }
3902
3903       /* Copy encoded string to RIC Indication Header buffer */
3904       ricIndHdr->size = encBufSize;
3905       DU_ALLOC(ricIndHdr->buf, ricIndHdr->size);
3906       if(!ricIndHdr->buf)
3907       {
3908          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3909          break;
3910       }
3911       memset(ricIndHdr->buf, 0, ricIndHdr->size);
3912       memcpy(ricIndHdr->buf, encBuf, encBufSize);
3913       ret = ROK;
3914       break;
3915    }
3916
3917    /* Free E2SM-KPM Indication Header */
3918    FreeE2smKpmIndicationHeader(&e2smKpmIndHdr);
3919
3920    return ret;
3921 }
3922
3923 /*******************************************************************
3924  *
3925  * brief Fill the RIC Indication Message
3926  *
3927  * @details
3928  *
3929  *    Function : fillRicIndication
3930  *
3931  * Functionality: Fills the RIC Indication Message
3932  *
3933  * @param  RIC Indication Message to be filled
3934  *         RIC Subscription DB
3935  *         Action DB
3936  * @return ROK     - success
3937  *         RFAILED - failure
3938  *
3939  ******************************************************************/
3940 uint8_t fillRicIndication(RICindication_t *ricIndicationMsg, RicSubscription *ricSubscriptionInfo, ActionInfo *actionInfo)
3941 {
3942    uint8_t elementCnt = 0, idx = 0;
3943    uint8_t ret = ROK;
3944
3945    elementCnt = 6;
3946
3947    ricIndicationMsg->protocolIEs.list.count = elementCnt;
3948    ricIndicationMsg->protocolIEs.list.size  = elementCnt * sizeof(RICindication_IEs_t *);
3949
3950    /* Initialize the Ric Indication members */
3951    DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, ricIndicationMsg->protocolIEs.list.size);
3952    if(ricIndicationMsg->protocolIEs.list.array == NULLP)
3953    {
3954       DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3955       return RFAILED;
3956    }
3957
3958    for(idx=0; idx<elementCnt; idx++)
3959    {
3960       DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx], sizeof(RICindication_IEs_t));
3961       if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
3962       {
3963          DU_LOG("\nERROR  -->  E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
3964          return RFAILED;
3965       }
3966    }
3967
3968    /* RIC Request ID */
3969    idx = 0;
3970    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
3971    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
3972    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICrequestID;
3973    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID = \
3974       ricSubscriptionInfo->requestId.requestorId;
3975    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID = \
3976       ricSubscriptionInfo->requestId.instanceId;
3977
3978    /* RAN Function ID */
3979    idx++;
3980    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
3981    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
3982    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RANfunctionID;
3983    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ricSubscriptionInfo->ranFuncId;
3984
3985    /* RIC Action ID */
3986    idx++;
3987    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
3988    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
3989    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICactionID;
3990    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = actionInfo->actionId;
3991
3992    /* RIC Indication Type */
3993    idx++;
3994    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
3995    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
3996    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationType;
3997    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = actionInfo->type;
3998
3999    /* RIC Indication Header */
4000    idx++;
4001    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
4002    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4003    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationHeader;
4004    if(fillRicIndHeader(&ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader, \
4005       ricSubscriptionInfo) != ROK)
4006    {
4007       DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication header");
4008       return RFAILED;
4009    }
4010
4011    /* RIC Indication Message */
4012    idx++;
4013    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
4014    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
4015    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationMessage;
4016    if(fillRicIndMsgBuf(&ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage, \
4017       actionInfo) != ROK)
4018    {
4019       DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication Message");
4020       return RFAILED;
4021    }
4022
4023    return ret;
4024 }
4025
4026 /*******************************************************************
4027  *
4028  * @brief Builds and Send the RicIndication Message
4029  *
4030  * @details
4031  *
4032  *    Function : BuildAndSendRicIndication
4033  *
4034  * Functionality:Fills the RicIndication Message
4035  *
4036  * @return ROK     - success
4037  *         RFAILED - failure
4038  *
4039  ******************************************************************/
4040
4041 uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo, ActionInfo *actionInfo)
4042 {
4043    uint8_t          ret = RFAILED; 
4044    E2AP_PDU_t       *e2apMsg = NULLP;
4045    RICindication_t  *ricIndicationMsg = NULLP;
4046    asn_enc_rval_t   encRetVal;        /* Encoder return value */
4047
4048    while(true)
4049    {
4050       DU_LOG("\nINFO   -->  E2AP : Building RIC Indication Message\n");
4051
4052       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4053       if(e2apMsg == NULLP)
4054       {
4055          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4056          break;
4057       }
4058
4059       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4060       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4061       if(e2apMsg->choice.initiatingMessage == NULLP)
4062       {
4063          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4064          break;
4065       }
4066       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
4067       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4068       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication;
4069
4070       ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
4071
4072       if(fillRicIndication(ricIndicationMsg, ricSubscriptionInfo, actionInfo) != ROK)
4073       {
4074          DU_LOG("\nERROR  -->  E2AP : Failed to fill RIC Indication message");
4075          break;
4076       }
4077
4078       /* Prints the Msg formed */
4079       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4080       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4081       encBufSize = 0;
4082       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4083             encBuf);
4084       if(encRetVal.encoded == ENCODE_FAIL)
4085       {
4086          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Indication Message (at %s)\n",\
4087                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4088          break;
4089       }
4090       else
4091       {
4092          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Indication Message \n");
4093 #ifdef DEBUG_ASN_PRINT
4094          for(int i=0; i< encBufSize; i++)
4095          {
4096             printf("%x",encBuf[i]);
4097          } 
4098 #endif
4099       }
4100
4101       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
4102       {
4103          DU_LOG("\nINFO   -->  E2AP : Sending RIC Indication Message");      
4104
4105       }
4106       ret = ROK;
4107       break;
4108    }
4109    FreeRicIndication(e2apMsg);  
4110    return ret;
4111 }
4112
4113 /*******************************************************************
4114  *
4115  * @brief free e2 node component configuration req and rsp
4116  *
4117  * @details
4118  *
4119  *    Function : freeE2NodeComponentConfiguration 
4120  *
4121  *    Functionality:
4122  *       - free e2 node component configuration req and rsp
4123  *
4124  * @params[in] E2nodeComponentConfiguration_t *e2nodeComponentConfiguration
4125  * @return ROK     - success
4126  *         RFAILED - failure
4127  *
4128  * ****************************************************************/
4129
4130 void freeE2NodeComponentConfiguration(E2nodeComponentConfiguration_t *e2nodeComponentConfiguration)
4131 {
4132    /* Free E2 Node Component Request Part */
4133    DU_FREE(e2nodeComponentConfiguration->e2nodeComponentRequestPart.buf, e2nodeComponentConfiguration->e2nodeComponentRequestPart.size);
4134
4135    /* Free E2 Node Component Response Part */
4136    DU_FREE(e2nodeComponentConfiguration->e2nodeComponentResponsePart.buf, e2nodeComponentConfiguration->e2nodeComponentResponsePart.size);
4137                                  
4138 }
4139
4140 /*******************************************************************
4141  *
4142  * @brief free e2 node component component identifier
4143  *
4144  * @details
4145  *
4146  *    Function : freeE2NodeComponentIdentifier
4147  *
4148  *    Functionality:
4149  *       - free e2 node component component identifier
4150  *
4151  * @params[in] E2nodeComponentID_t  *componentID 
4152  * @return ROK     - success
4153  *         RFAILED - failure
4154  *
4155  * ****************************************************************/
4156
4157 void freeE2NodeComponentIdentifier(E2nodeComponentID_t *componentID)
4158 {
4159    if(componentID->choice.e2nodeComponentInterfaceTypeF1)
4160    {
4161       DU_FREE(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf, componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
4162       DU_FREE(componentID->choice.e2nodeComponentInterfaceTypeF1, sizeof(E2nodeComponentInterfaceF1_t));
4163    }
4164                                  
4165 }
4166
4167 /*******************************************************************
4168  *
4169  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
4170  *
4171  * @details
4172  *
4173  *    Function : FreeE2NodeConfigUpdate 
4174  *
4175  *    Functionality:
4176  *       - freeing the memory allocated for E2nodeConfigurationUpdate
4177  *
4178  * @params[in] E2AP_PDU_t *e2apMsg 
4179  * @return ROK     - success
4180  *         RFAILED - failure
4181  *
4182  * ****************************************************************/
4183
4184 void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg)
4185 {
4186    uint8_t arrIdx =0, e2NodeUpdateListIdx=0, e2NodeRemovalListIdx=0, e2NodeAddListIdx=0;
4187    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate =NULL;
4188    E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList  =NULL;
4189    E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItem =NULL;
4190    E2nodeComponentConfigRemoval_List_t *e2NodeRemovalList =NULL;
4191    E2nodeComponentConfigRemoval_ItemIEs_t *e2NodeRemovalItem =NULL;
4192    E2nodeComponentConfigAddition_List_t *e2NodeAddList =NULL;
4193    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem =NULL;
4194
4195    if(e2apMsg != NULLP)
4196    {
4197       if(e2apMsg->choice.initiatingMessage != NULLP)
4198       {
4199          e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
4200          if(e2NodeConfigUpdate->protocolIEs.list.array != NULLP)
4201          {
4202             for(arrIdx = 0; arrIdx < e2NodeConfigUpdate->protocolIEs.list.count; arrIdx++)
4203             {
4204                if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx])
4205                {
4206
4207                   switch(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id)
4208                   {
4209                      case ProtocolIE_IDE2_id_TransactionID:
4210                         break;
4211
4212                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
4213                      {
4214                          e2NodeAddList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;
4215                          if(e2NodeAddList->list.array)
4216                          {
4217                              for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
4218                              {
4219                                 e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
4220                                  
4221                                 freeE2NodeComponentConfiguration(&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration);
4222                                 freeE2NodeComponentIdentifier(&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID);
4223                                 DU_FREE(e2NodeAddItem, sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
4224                              }
4225                              DU_FREE(e2NodeAddList->list.array, e2NodeAddList->list.size);
4226                          }
4227                          break;
4228                      }
4229                      case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate:
4230                         {
4231                            e2NodeUpdateList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdate_List;
4232                            if(e2NodeUpdateList->list.array)
4233                            {
4234                               for(e2NodeUpdateListIdx = 0; e2NodeUpdateListIdx< e2NodeUpdateList->list.count; e2NodeUpdateListIdx++)
4235                               {
4236                                  e2NodeUpdateItem = (E2nodeComponentConfigUpdate_ItemIEs_t *) e2NodeUpdateList->list.array[e2NodeUpdateListIdx];
4237                                  
4238                                  freeE2NodeComponentConfiguration(&e2NodeUpdateItem->value.choice.E2nodeComponentConfigUpdate_Item.e2nodeComponentConfiguration);
4239                                  freeE2NodeComponentIdentifier(&e2NodeUpdateItem->value.choice.E2nodeComponentConfigUpdate_Item.e2nodeComponentID);
4240                                  DU_FREE(e2NodeUpdateItem, sizeof(E2nodeComponentConfigUpdate_ItemIEs_t));
4241                               }
4242                               DU_FREE(e2NodeUpdateList->list.array, e2NodeUpdateList->list.size);
4243                            }
4244                            break;
4245                         }
4246                      case ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval:
4247                         {
4248                            e2NodeRemovalList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemoval_List;
4249                            if(e2NodeRemovalList->list.array)
4250                            {
4251                               for(e2NodeRemovalListIdx = 0; e2NodeRemovalListIdx< e2NodeRemovalList->list.count; e2NodeRemovalListIdx++)
4252                               {
4253                                  e2NodeRemovalItem = (E2nodeComponentConfigRemoval_ItemIEs_t *) e2NodeRemovalList->list.array[e2NodeRemovalListIdx];
4254
4255                                  freeE2NodeComponentIdentifier(&e2NodeRemovalItem->value.choice.E2nodeComponentConfigRemoval_Item.e2nodeComponentID);
4256                                  DU_FREE(e2NodeRemovalItem, sizeof(E2nodeComponentConfigRemoval_ItemIEs_t));
4257                               }
4258                               DU_FREE(e2NodeRemovalList->list.array, e2NodeRemovalList->list.size);
4259                            }
4260                            break;
4261                         }
4262                            
4263                      default:
4264                         break;
4265                   }
4266                   DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
4267                }
4268             }
4269             DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
4270          }
4271          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4272       }
4273       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4274    }
4275 }
4276
4277 /*******************************************************************
4278  *
4279  * @brief Buld and send the E2 node config update msg 
4280  *
4281  * @details
4282  *
4283  *    Function : BuildAndSendE2NodeConfigUpdate
4284  *
4285  *    Functionality:
4286  *         - Buld and send the E2 node config update msg
4287  *
4288  * @params[in] 
4289  * @return ROK     - success
4290  *         RFAILED - failure
4291  *
4292  * ****************************************************************/
4293
4294 uint8_t BuildAndSendE2NodeConfigUpdate(E2NodeConfigList *e2NodeList)
4295 {
4296    uint8_t ret = RFAILED;
4297    uint8_t arrIdx = 0,elementCnt = 0, transId=0;
4298    E2AP_PDU_t  *e2apMsg = NULLP;
4299    asn_enc_rval_t     encRetVal;       /* Encoder return value */
4300    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate = NULLP;
4301
4302    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update\n");
4303    do
4304    {
4305       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4306       if(e2apMsg == NULLP)
4307       {
4308          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4309          break;
4310       }
4311
4312       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4313       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4314       if(e2apMsg->choice.initiatingMessage == NULLP)
4315       {
4316          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
4317          break;
4318       }
4319       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4320       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
4321       e2apMsg->choice.initiatingMessage->value.present = \
4322       InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate;
4323       e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
4324       
4325       elementCnt =1;
4326       if(e2NodeList->addE2NodeCount)
4327          elementCnt++;
4328       if(e2NodeList->updateE2NodeCount)
4329          elementCnt++;
4330       if(e2NodeList->removeE2NodeCount)
4331          elementCnt++;
4332
4333       e2NodeConfigUpdate->protocolIEs.list.count = elementCnt;
4334       e2NodeConfigUpdate->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdate_IEs_t*);
4335       DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
4336       if(e2NodeConfigUpdate->protocolIEs.list.array == NULLP)
4337       {
4338          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
4339          break;
4340       }
4341       
4342       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
4343       {
4344          DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
4345          if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx] == NULLP)
4346          {
4347             
4348             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
4349             break;
4350          }
4351       }
4352       
4353       if(arrIdx<elementCnt)
4354          break;
4355
4356       arrIdx = 0;
4357       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4358       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4359       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_TransactionID;
4360       transId = assignTransactionId();
4361       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
4362
4363       if(e2NodeList->addE2NodeCount)
4364       {
4365          arrIdx++;
4366          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition;
4367          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4368          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigAddition_List;
4369          if(BuildE2NodeConfigAddList(&(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List),\
4370          ProcedureCodeE2_id_E2nodeConfigurationUpdate, e2NodeList->addE2NodeCount, e2NodeList->addE2Node)!=ROK)
4371          {
4372             DU_LOG("\nERROR  -->  E2AP : Failed to create E2 Node config list");
4373             break;
4374          }
4375       }
4376       
4377       if(e2NodeList->updateE2NodeCount)
4378       {
4379          arrIdx++;
4380          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate;
4381          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4382          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigUpdate_List;
4383          if(BuildE2NodeConfigUpdateList(&e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdate_List,\
4384          e2NodeList->updateE2NodeCount, e2NodeList->updateE2Node) != ROK)
4385          {
4386
4387             DU_LOG("\nERROR  -->  E2AP : Failed to update the E2 node configuration");
4388             break;
4389          }
4390       }
4391       
4392       if(e2NodeList->removeE2NodeCount)
4393       {
4394          arrIdx++;
4395          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval;
4396          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4397          e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigRemoval_List;
4398          if(BuildE2NodeConfigRemoveList(&e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemoval_List,\
4399          e2NodeList->removeE2NodeCount, e2NodeList->removeE2Node) != ROK)
4400          {
4401
4402             DU_LOG("\nERROR  -->  E2AP : Failed to remove the E2 node configuration");
4403             break;
4404          }
4405       }
4406
4407       /* Prints the Msg formed */
4408       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4409
4410       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4411       encBufSize = 0;
4412       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
4413       if(encRetVal.encoded == ENCODE_FAIL)
4414       {
4415          DU_LOG("\nERROR  -->  E2AP : Could not encode E2nodeConfigurationUpdate structure (at %s)\n",\
4416                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4417          break;
4418       }
4419       else
4420       {
4421          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2nodeConfigurationUpdate\n");
4422 #ifdef DEBUG_ASN_PRINT
4423          for(int i=0; i< encBufSize; i++)
4424          {
4425             printf("%x",encBuf[i]);
4426          }
4427 #endif
4428       }
4429       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize))
4430       {
4431          DU_LOG("\nERROR  -->  E2AP : Sending E2 node config update failed");
4432          break;
4433       }
4434
4435       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
4436       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
4437       memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.e2NodeConfigUpdate.configList, e2NodeList, sizeof(E2NodeConfigList));
4438       ret = ROK;
4439       break;
4440    }while(true);
4441    
4442    FreeE2NodeConfigUpdate(e2apMsg);
4443    return ret;
4444 }
4445
4446 /*******************************************************************
4447  *
4448  * @brief Deallocate the memory allocated for E2ResetRequest msg
4449  *
4450  * @details
4451  *
4452  *    Function : FreeE2ResetRequest
4453  *
4454  *    Functionality:
4455  *       - freeing the memory allocated for E2ResetRequest
4456  *
4457  * @params[in] E2AP_PDU_t *e2apMsg
4458  * @return ROK     - success
4459  *         RFAILED - failure
4460  *
4461  * ****************************************************************/
4462 void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg)
4463 {
4464    uint8_t ieIdx =0;
4465    ResetRequestE2_t  *resetReq = NULLP;
4466
4467    if(e2apMsg != NULLP)
4468    {
4469       if(e2apMsg->choice.initiatingMessage != NULLP)
4470       {
4471          resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4472          if(resetReq->protocolIEs.list.array)
4473          {
4474             for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
4475             {
4476                DU_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4477             }
4478             DU_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4479          }
4480          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4481       }
4482       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4483    }
4484 }
4485
4486 /*******************************************************************
4487  *
4488  * @brief Build and send the E2 reset request msg
4489  *
4490  * @details
4491  *
4492  *    Function : BuildAndSendE2ResetRequest
4493  *
4494  *    Functionality:
4495  *         - Buld and send the E2 reset request msg to RIC
4496  *
4497  * @params[in]
4498  *    Reset cause
4499  * @return ROK     - success
4500  *         RFAILED - failure
4501  *
4502  * ****************************************************************/
4503 uint8_t BuildAndSendE2ResetRequest(E2FailureCause resetCause)
4504 {
4505    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
4506    uint8_t ret = RFAILED;
4507    E2AP_PDU_t        *e2apMsg = NULLP;
4508    ResetRequestE2_t  *resetReq = NULLP;
4509    asn_enc_rval_t     encRetVal;       /* Encoder return value */
4510
4511    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Request\n");
4512
4513    do
4514    {
4515       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4516       if(e2apMsg == NULLP)
4517       {
4518          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for E2AP-PDU failed");
4519          break;
4520       }
4521
4522       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4523       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4524       if(e2apMsg->choice.initiatingMessage == NULLP)
4525       {
4526          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for initiatingMessage");
4527          break;
4528       }
4529
4530       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
4531       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4532       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
4533       resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4534
4535       elementCnt = 2;
4536       resetReq->protocolIEs.list.count = elementCnt;
4537       resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
4538
4539       DU_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4540       if(!resetReq->protocolIEs.list.array)
4541       {
4542          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
4543             Reset Request IE array");
4544          break;
4545       }
4546
4547       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
4548       {
4549          DU_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4550          if(!resetReq->protocolIEs.list.array[ieIdx])
4551          {
4552             DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
4553             Reset Request IE array element");
4554             break;
4555          }
4556       }
4557
4558       /* In case of failure */
4559       if(ieIdx < elementCnt)
4560          break;
4561
4562       ieIdx = 0;
4563       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4564       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
4565       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
4566       transId = assignTransactionId();
4567       resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
4568
4569       ieIdx++;
4570       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
4571       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
4572       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
4573       fillE2Cause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, resetCause);
4574
4575       /* Prints the Msg formed */
4576       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4577
4578       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4579       encBufSize = 0;
4580       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4581             encBuf);
4582       if(encRetVal.encoded == ENCODE_FAIL)
4583       {
4584          DU_LOG("\nERROR  -->  E2AP : Could not encode reset request structure (at %s)\n",\
4585                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4586          break;
4587       }
4588       else
4589       {
4590          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for reset request\n");
4591 #ifdef DEBUG_ASN_PRINT
4592          for(int i=0; i< encBufSize; i++)
4593          {
4594             printf("%x",encBuf[i]);
4595          }
4596 #endif
4597       }
4598       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
4599       {
4600          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
4601          break;
4602       }
4603
4604       /* In case the message is sent successfully, store the transaction info to
4605        * be used when response is received */
4606       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
4607       duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
4608
4609       ret = ROK;
4610       break;
4611    }while(true);
4612
4613    /* Free all memory */
4614    FreeE2ResetRequest(e2apMsg);
4615    return ret;
4616 }
4617
4618 /*******************************************************************
4619  *
4620  * @brief Deallocate the memory allocated for Reset Response msg
4621  *
4622  * @details
4623  *
4624  *    Function : freeAperDecodingOfE2ResetRsp
4625  *
4626  *    Functionality:
4627  *       - freeing the memory allocated for Reset response
4628  *
4629  * @params[in] ResetResponseE2_t *resetResponse
4630  * @return void
4631  *
4632  * ****************************************************************/
4633 void freeAperDecodingOfE2ResetRsp(ResetResponseE2_t *resetResponse)
4634 {
4635    uint8_t ieIdx;
4636
4637    if(resetResponse)
4638    {
4639       if(resetResponse->protocolIEs.list.array)
4640       {
4641          for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
4642          {
4643             if(resetResponse->protocolIEs.list.array[ieIdx])
4644             {
4645                switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
4646                {
4647                   case ProtocolIE_IDE2_id_TransactionID:
4648                      break;
4649
4650                   case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
4651                      break;
4652                }
4653                free(resetResponse->protocolIEs.list.array[ieIdx]);
4654             }
4655          }
4656          free(resetResponse->protocolIEs.list.array);
4657       }
4658    }
4659 }
4660
4661 /******************************************************************
4662  *
4663  * @brief Processes E2 Reset Response sent by RIC
4664  *
4665  * @details
4666  *
4667  *    Function : procResetResponse
4668  *
4669  *    Functionality: Processes E2 Reset Response sent by RIC
4670  *
4671  * @params[in] E2AP_PDU_t ASN decoded E2AP message
4672  * @return void
4673  *
4674  * ****************************************************************/
4675 void procResetResponse(E2AP_PDU_t *e2apMsg)
4676 {
4677    bool invalidTransId=false;
4678    uint8_t ieIdx =0, transId =0;
4679    uint16_t ranFuncIdx=0;
4680    ResetResponseE2_t *resetResponse =NULLP;
4681
4682    DU_LOG("\nINFO   -->  E2AP : E2 Reset Response received");
4683    resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;;
4684
4685    for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
4686    {
4687       switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
4688       {
4689          case ProtocolIE_IDE2_id_TransactionID:
4690             {
4691                transId = resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
4692                if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) && \
4693                      (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
4694                {
4695                   memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
4696                }
4697                else
4698                {
4699                   DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
4700                   invalidTransId = true;
4701                }
4702                break;
4703             }
4704          case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
4705             {
4706                for(ranFuncIdx=0; ranFuncIdx<MAX_RAN_FUNCTION; ranFuncIdx++)
4707                {
4708                   if(duCb.e2apDb.ranFunction[ranFuncIdx].id >0)
4709                   {
4710                      deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList));
4711                      memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo));
4712                   }
4713                }
4714                break;
4715             }
4716          default:
4717             {
4718                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2 Reset Response : %ld",
4719                      resetResponse->protocolIEs.list.array[ieIdx]->id);
4720                break;
4721             }
4722       }
4723
4724       if(invalidTransId == true)
4725       {
4726          break;
4727       }
4728    }
4729
4730    freeAperDecodingOfE2ResetRsp(resetResponse);
4731 }
4732
4733 /******************************************************************
4734  *
4735  * @brief Deallocation of memory allocated by aper decoder for e2 setup Failure
4736  *
4737  * @details
4738  *
4739  *    Function : freeAperDecodingOfE2SetupFailure
4740  *
4741  *    Functionality: Deallocation of memory allocated by aper decoder for e2
4742  *    setup Failure
4743  *
4744  * @params[in] E2setupFailure_t *e2SetupFailure;
4745  * @return void
4746  *
4747  * ****************************************************************/
4748 void freeAperDecodingOfE2SetupFailure(E2setupFailure_t *e2SetupFailure)
4749 {
4750    uint8_t arrIdx;
4751
4752    if(e2SetupFailure)
4753    {
4754       if(e2SetupFailure->protocolIEs.list.array)
4755       {
4756          for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
4757          {
4758             if(e2SetupFailure->protocolIEs.list.array[arrIdx])
4759             {
4760                free(e2SetupFailure->protocolIEs.list.array[arrIdx]);  
4761             }
4762          }
4763          free(e2SetupFailure->protocolIEs.list.array);
4764       }
4765    }
4766 }
4767 /******************************************************************
4768  *
4769  * @brief Processes E2 Setup Failure sent by RIC
4770  *
4771  * @details
4772  *
4773  *    Function : procE2SetupFailure
4774  *
4775  *    Functionality: Processes E2 Setup failure sent by RIC
4776  *
4777  * @params[in] E2AP_PDU_t ASN decoded E2AP message
4778  * @return ROK     - success
4779  *         RFAILED - failure
4780  *
4781  * ****************************************************************/
4782 void procE2SetupFailure(E2AP_PDU_t *e2apMsg)
4783 {
4784    uint8_t arrIdx =0, transId =0, timerValue=0; 
4785    E2setupFailure_t *e2SetupFailure;
4786
4787    DU_LOG("\nINFO   -->  E2AP : E2 Setup failure received"); 
4788    e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
4789
4790    for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
4791    {
4792       switch(e2SetupFailure->protocolIEs.list.array[arrIdx]->id)
4793       {
4794          case ProtocolIE_IDE2_id_TransactionID:
4795          {
4796             transId = e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
4797             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
4798                   (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
4799             {
4800                memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
4801             }
4802             else
4803             {
4804                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
4805                return ;
4806             }
4807             break;
4808          }
4809          case ProtocolIE_IDE2_id_TimeToWaitE2:
4810             {
4811                timerValue = convertE2WaitTimerEnumToValue(e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
4812                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR)) == FALSE)
4813                {
4814                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR, timerValue);
4815                }
4816                else
4817                {
4818                   DU_LOG("\nERROR   -->  E2AP : EVENT_E2_SETUP_TMR timer is already running");
4819                   return;
4820                }
4821                break; 
4822             }
4823       }
4824    }
4825
4826    freeAperDecodingOfE2SetupFailure(e2SetupFailure);
4827 }
4828 /******************************************************************
4829  *
4830  * @brief Deallocation of memory allocated by aper decoder for RIC service Query
4831  *
4832  * @details
4833  *
4834  *    Function : freeAperDecodingOfRicServiceQuery
4835  *
4836  *    Functionality: Deallocation of memory allocated by aper decoder for RIC
4837  *    service Query
4838  *
4839  * @params[in] RICserviceQuery_t *ricServiceQuery;
4840  * @return void
4841  *
4842  * ****************************************************************/
4843
4844 void freeAperDecodingOfRicServiceQuery(RICserviceQuery_t *ricServiceQuery)
4845 {
4846    uint8_t arrIdx,ranFuncIdx;
4847     RANfunctionsID_List_t *ranFuncAddedList;
4848
4849    if(ricServiceQuery)
4850    {
4851       if(ricServiceQuery->protocolIEs.list.array)
4852       {
4853          for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
4854          {
4855             if(ricServiceQuery->protocolIEs.list.array[arrIdx])
4856             {
4857                switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
4858                {
4859                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
4860                   {
4861                      ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
4862                      if(ranFuncAddedList->list.array)
4863                      {
4864                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
4865                         {
4866                            free(ranFuncAddedList->list.array[ranFuncIdx]);
4867                         }
4868                         free(ranFuncAddedList->list.array);;
4869                      }
4870                      break;
4871                   }
4872                   default:
4873                      break;
4874                }
4875                free(ricServiceQuery->protocolIEs.list.array[arrIdx]);
4876             }
4877          }
4878          free(ricServiceQuery->protocolIEs.list.array);
4879       }
4880    }
4881 }
4882 /*******************************************************************
4883  *
4884  * @brief Build RanFunction Delete List
4885  *
4886  * @details
4887  *
4888  *    Function : BuildRanFunctionDeleteList
4889  *
4890  * Functionality:  Build RanFunction Delete List
4891  *
4892  * @params[in]
4893  *    RANfunctionsID List
4894  *    Count of the RAN function
4895  *    Received RAN function list
4896  *
4897  * @return ROK     - success
4898  *         RFAILED - failure
4899  *
4900  ******************************************************************/
4901
4902 uint8_t BuildRanFunctionDeleteList(RANfunctionsID_List_t *deleteList, uint8_t count, RanFuncInfo *recvdRanFunc)
4903 {
4904    uint8_t ranFuncIdx=0;
4905    RANfunctionID_ItemIEs_t *delRanFuncItem;
4906
4907    if(count)
4908    {
4909       deleteList->list.count = count;
4910       deleteList->list.size = deleteList->list.count * sizeof(RANfunctionID_ItemIEs_t*);
4911       DU_ALLOC(deleteList->list.array, deleteList->list.size);
4912       if(deleteList->list.array == NULLP)
4913       {
4914          DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
4915          return RFAILED;
4916       }
4917       for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
4918       {
4919          DU_ALLOC(deleteList->list.array[ranFuncIdx], sizeof(RANfunctionID_ItemIEs_t));
4920          if(deleteList->list.array[ranFuncIdx] == NULLP)
4921          {
4922             DU_LOG("\nERROR  --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__);
4923             return RFAILED;
4924          }
4925          delRanFuncItem= (RANfunctionID_ItemIEs_t *) deleteList->list.array[ranFuncIdx];
4926          delRanFuncItem->id = ProtocolIE_IDE2_id_RANfunctionID_Item;
4927          delRanFuncItem->criticality = CriticalityE2_ignore;
4928          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionID = recvdRanFunc[ranFuncIdx].id;
4929          delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionRevision = recvdRanFunc[ranFuncIdx].revisionCounter;
4930
4931       }
4932    }
4933    return ROK;
4934 }
4935 /*******************************************************************
4936  *
4937  * @brief De Allocate  Ric Service Update message
4938  *
4939  * @details
4940  *
4941  *    Function : FreeRicServiceUpdate
4942  *
4943  *    Functionality: De-Allocating Ric Service Update message
4944  *
4945  * @params[in] E2AP_PDU_t *e2apMsg
4946
4947  * @return void
4948  *
4949  * ****************************************************************/
4950
4951 void FreeRicServiceUpdate(E2AP_PDU_t *e2apMsg)
4952 {
4953    uint8_t arrIdx = 0;
4954    uint8_t ranFuncAddListIdx=0, ranFuncDelIdx=0;
4955    RICserviceUpdate_t *ricServiceUpdate;
4956    RANfunctions_List_t *ranFunctionsList;
4957    RANfunction_ItemIEs_t *ranFuncItemIe;
4958    RANfunction_Item_t  *ranFunItem;
4959    RANfunctionsID_List_t *deleteList;
4960
4961    /* De-allocating Memory */
4962    if(e2apMsg != NULLP)
4963    {
4964       if(e2apMsg->choice.initiatingMessage != NULLP)
4965       {
4966          ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
4967          if(ricServiceUpdate->protocolIEs.list.array != NULLP)
4968          {
4969             for(arrIdx = 0; arrIdx < ricServiceUpdate->protocolIEs.list.count; arrIdx++)
4970             {
4971                if(ricServiceUpdate->protocolIEs.list.array[arrIdx] != NULLP)
4972                {
4973                   switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
4974                   {
4975                      case ProtocolIE_IDE2_id_TransactionID:
4976                         break;
4977
4978                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
4979                      case ProtocolIE_IDE2_id_RANfunctionsModified:
4980                         {
4981                            ranFunctionsList = &(ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List);
4982                            if(ranFunctionsList->list.array)
4983                            {
4984                               for(ranFuncAddListIdx= 0; ranFuncAddListIdx< ranFunctionsList->list.count; ranFuncAddListIdx++)
4985                               {
4986                                  if(ranFunctionsList->list.array[ranFuncAddListIdx])
4987                                  {
4988                                     ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncAddListIdx];
4989                                     ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
4990                                     DU_FREE(ranFunItem->ranFunctionOID.buf, ranFunItem->ranFunctionOID.size);
4991                                     DU_FREE(ranFunItem->ranFunctionDefinition.buf, ranFunItem->ranFunctionDefinition.size);
4992                                     DU_FREE(ranFunctionsList->list.array[ranFuncAddListIdx], sizeof(RANfunction_ItemIEs_t));
4993                                  }
4994                               }
4995                               DU_FREE(ranFunctionsList->list.array, ranFunctionsList->list.size);
4996                            }
4997                            break;
4998                         }
4999                      case ProtocolIE_IDE2_id_RANfunctionsDeleted:
5000                         {
5001                            deleteList= &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5002                            if(deleteList->list.array)
5003                            {
5004                               for(ranFuncDelIdx = 0; ranFuncDelIdx< deleteList->list.count; ranFuncDelIdx++)
5005                               {
5006                                  DU_FREE(deleteList->list.array[ranFuncDelIdx], sizeof(RANfunctionID_ItemIEs_t));
5007                               }
5008                               DU_FREE(deleteList->list.array, deleteList->list.size);
5009   
5010                            }
5011                            break;
5012                         }
5013                      default:
5014                         DU_LOG("\nERROR  --> E2AP: Invalid event at ricServiceUpdate %ld ",\
5015                               (ricServiceUpdate->protocolIEs.list.array[arrIdx]->id));
5016                         break;
5017                   }
5018                   DU_FREE(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
5019                }
5020             }
5021             DU_FREE(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
5022          }
5023          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5024       }
5025       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
5026    }
5027 }
5028
5029 /*******************************************************************
5030  *
5031  * @brief Builds and Send the RicServiceUpdateuest
5032  *
5033  * @details
5034  *
5035  *    Function : BuildAndSendRicServiceUpdate
5036  *
5037  * Functionality:Fills the RicServiceUpdateuest
5038  *
5039  * @return ROK     - success
5040  *         RFAILED - failure
5041  *
5042  ******************************************************************/
5043
5044 uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate)
5045 {
5046    uint8_t arrIdx = 0, elementCnt=0;
5047    uint8_t transId = 0, ret = RFAILED;
5048    bool memAllocFailed =false;
5049    E2AP_PDU_t        *e2apMsg = NULLP;
5050    RICserviceUpdate_t  *ricServiceUpdate = NULLP;
5051    asn_enc_rval_t     encRetVal;       /* Encoder return value */
5052
5053    DU_LOG("\nINFO   -->  E2AP : Building Ric Service Update\n");
5054    do
5055    {
5056       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
5057       if(e2apMsg == NULLP)
5058       {
5059          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
5060          break;
5061       }
5062       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
5063       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5064       if(e2apMsg->choice.initiatingMessage == NULLP)
5065       {
5066          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
5067          break;
5068       }
5069       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
5070       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
5071       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceUpdate;
5072       ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate;
5073       
5074       /* For TransId IE, set elementCnt to 1.
5075       If there is any item in the RAN function add list, RAN function modification list, or RAN function delete list, increment the elementCnt.*/
5076
5077       elementCnt =1;
5078       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5079         elementCnt++;
5080       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
5081          elementCnt++;
5082       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
5083          elementCnt++;
5084        
5085       ricServiceUpdate->protocolIEs.list.count = elementCnt;
5086       ricServiceUpdate->protocolIEs.list.size = elementCnt * sizeof(RICserviceUpdate_IEs_t*);
5087
5088       /* Initialize the E2Setup members */
5089       DU_ALLOC(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size);
5090       if(ricServiceUpdate->protocolIEs.list.array == NULLP)
5091       {
5092          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
5093          break;
5094       }
5095       
5096       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
5097       {
5098          DU_ALLOC(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t));
5099          if(ricServiceUpdate->protocolIEs.list.array[arrIdx] == NULLP)
5100          {
5101             memAllocFailed = true;
5102             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayIdx [%d]", arrIdx);
5103             break;
5104          }
5105       }
5106       if(memAllocFailed == true)
5107          break;
5108
5109       arrIdx = 0;
5110
5111       /* TransactionID */
5112       ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
5113       ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5114       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
5115       if(serviceUpdate.dir == E2_NODE_INITIATED)
5116          transId = assignTransactionId();
5117       else
5118         transId = serviceUpdate.transId;
5119       ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
5120
5121       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5122       {
5123          arrIdx++;
5124          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAdded;
5125          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5126          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
5127          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,\
5128          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded, serviceUpdate.recvRanFuncList.ranFunToBeAdded) !=ROK)
5129          {
5130             break;
5131          }
5132       }
5133
5134       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified)
5135       {
5136          arrIdx++;
5137          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsModified;
5138          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5139          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List;
5140          if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,
5141          e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeModified, serviceUpdate.recvRanFuncList.ranFunToBeModified) !=ROK)
5142          {
5143             break;
5144          }
5145       }
5146
5147       if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted)
5148       {
5149          arrIdx++;
5150          ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsDeleted;
5151          ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5152          ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctionsID_List;
5153          if(BuildRanFunctionDeleteList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List,\
5154          serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted, serviceUpdate.recvRanFuncList.ranFunToBeDeleted) != ROK)
5155          {
5156             break;
5157          }
5158       }
5159       /* Prints the Msg formed */
5160       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5161
5162       memset(encBuf, 0, ENC_BUF_MAX_LEN);
5163       encBufSize = 0;
5164       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
5165       if(encRetVal.encoded == ENCODE_FAIL)
5166       {
5167          DU_LOG("\nERROR  -->  E2AP : Could not encode RicServiceUpdateuest structure (at %s)\n",\
5168                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
5169          break;
5170       }
5171       else
5172       {
5173          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RicServiceUpdateuest\n");
5174 #ifdef DEBUG_ASN_PRINT
5175          for(int i=0; i< encBufSize; i++)
5176          {
5177             printf("%x",encBuf[i]);
5178          }
5179 #endif
5180       }
5181       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
5182       {
5183          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
5184          break;
5185       }
5186       ret = ROK;
5187       break;
5188    }while(true);
5189    
5190    if(ret == ROK)
5191    {
5192       if(serviceUpdate.dir == E2_NODE_INITIATED)
5193       {
5194          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
5195          duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5196       }
5197       else
5198       {
5199          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId = transId;
5200          duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
5201       }
5202       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.dir = serviceUpdate.dir;
5203       duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.transId =transId;
5204       memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.recvRanFuncList, &serviceUpdate.recvRanFuncList, sizeof(E2TmpRanFunList));
5205    }
5206    FreeRicServiceUpdate(e2apMsg);
5207    return ret;
5208 }
5209 /******************************************************************
5210  *
5211  * @brief Processes RIC service Query sent by RIC
5212  *
5213  * @details
5214  *
5215  *    Function : procRicServiceQuery
5216  *
5217  *    Functionality: Processes RIC service Query sent by RIC
5218  *
5219  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5220  * @return ROK     - success
5221  *         RFAILED - failure
5222  *
5223  * ****************************************************************/
5224
5225 void procRicServiceQuery(E2AP_PDU_t *e2apMsg)
5226 {
5227    ConfigType action;
5228    uint16_t arrIdx =0, ranFuncIdx=0,tmpIdx=0;
5229    uint16_t id,revisionCcounter;
5230    bool tmpArray[MAX_RAN_FUNCTION] = {false};
5231    RICserviceQuery_t *ricServiceQuery=NULL;
5232    RicServiceUpdate ricUpdate;
5233    RANfunctionID_ItemIEs_t *ranFuncAddedItemIe;
5234    RANfunctionsID_List_t *ranFuncAddedList;
5235
5236    DU_LOG("\nINFO   -->  E2AP : RIC Service Query received");
5237    memset(&ricUpdate, 0, sizeof(RicServiceUpdate));
5238    ricUpdate.dir = RIC_INITIATED;
5239    ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
5240
5241    for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
5242    {
5243       switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
5244       {
5245          /* TODO completing in next patch/gerrit */
5246          case ProtocolIE_IDE2_id_TransactionID:
5247          {
5248             ricUpdate.transId = ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
5249             break;
5250          }
5251
5252          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5253          {
5254             ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5255             if(ranFuncAddedList->list.array)
5256             {
5257                for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
5258                {
5259                   if(ranFuncAddedList->list.array[ranFuncIdx])
5260                   {
5261                      /* Using the RAN function Id, identify the RAN function to be modified or deleted.  */
5262                      
5263                      ranFuncAddedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAddedList->list.array[ranFuncIdx];
5264                      id = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionID;
5265                      revisionCcounter = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision;
5266                      
5267                      if((id != duCb.e2apDb.ranFunction[id-1].id))
5268                      {
5269                         action = CONFIG_DEL;
5270                      }
5271                      else if((id == duCb.e2apDb.ranFunction[id-1].id)&&(revisionCcounter!=duCb.e2apDb.ranFunction[id-1].revisionCounter))
5272                      {
5273                         action = CONFIG_MOD;
5274                      }
5275
5276                      if(action == CONFIG_DEL)
5277                      {
5278                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].id = id;
5279                         ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].revisionCounter = revisionCcounter;
5280                         ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted++;
5281                      }
5282                      else if(action == CONFIG_MOD)
5283                      {
5284                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].id = id;
5285                         ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].revisionCounter = revisionCcounter;
5286                         ricUpdate.recvRanFuncList.numOfRanFunToBeModified++;
5287                      }
5288
5289                      /* If any ID is set to true, it means that the ID has been used in either modification or deletion list. 
5290                       * Else we will add the IDs into the added list */
5291                      tmpArray[id-1] = true;
5292                   }
5293                }
5294             }
5295             break;
5296          }
5297       }
5298    }
5299
5300    /*  Traversing the whole RAN function list in ducb to check if any new Ran function ids have been added. */
5301    for(arrIdx =0; arrIdx<MAX_RAN_FUNCTION; arrIdx++)
5302    {
5303       tmpIdx= ricUpdate.recvRanFuncList.numOfRanFunToBeAdded;
5304       if((duCb.e2apDb.ranFunction[arrIdx].id >0)&&(!tmpArray[arrIdx]))
5305       {
5306          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[arrIdx].id;
5307          ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[arrIdx].revisionCounter;
5308          ricUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
5309       }
5310    }
5311
5312    if(BuildAndSendRicServiceUpdate(ricUpdate)!= ROK)
5313    {
5314       DU_LOG("\nERROR  -->  E2AP : Failed to build and send ric service update message");
5315    }
5316
5317    freeAperDecodingOfRicServiceQuery(ricServiceQuery);
5318 }
5319
5320 /******************************************************************
5321  *
5322  * @brief Deallocation of memory allocated by aper decoder for 
5323  *    RIC service update ack
5324  *
5325  * @details
5326  *
5327  *    Function : freeAperDecodingOfRicServiceUpdateAck
5328  *
5329  *    Functionality: Deallocation of memory allocated by aper decoder 
5330  *    for RIC service update ack
5331  *
5332  * @params[in] RICserviceUpdateAck_t *ricServiceAck;
5333  * @return void
5334  *
5335  * ****************************************************************/
5336
5337 void freeAperDecodingOfRicServiceUpdateAck(RICserviceUpdateAcknowledge_t *ricServiceAck)
5338 {
5339    uint8_t arrIdx=0,ranFuncIdx=0;
5340    RANfunctionsID_List_t *ranFuncAddedList=NULL;
5341
5342    if(ricServiceAck)
5343    {
5344       if(ricServiceAck->protocolIEs.list.array)
5345       {
5346          for(arrIdx=0; arrIdx<ricServiceAck->protocolIEs.list.count; arrIdx++)
5347          {
5348             if(ricServiceAck->protocolIEs.list.array[arrIdx])
5349             {
5350                switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id)
5351                {
5352                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5353                   {
5354                      ranFuncAddedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
5355                      if(ranFuncAddedList->list.array)
5356                      {
5357                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
5358                         {
5359                            free(ranFuncAddedList->list.array[ranFuncIdx]);
5360                         }
5361                         free(ranFuncAddedList->list.array);
5362                      }
5363                      break;
5364                   }
5365                   default:
5366                      break;
5367                }
5368                free(ricServiceAck->protocolIEs.list.array[arrIdx]);  
5369             }
5370          }
5371          free(ricServiceAck->protocolIEs.list.array);
5372       }
5373    }
5374 }
5375
5376 /******************************************************************
5377  *
5378  * @brief Processes RIC service update ack sent by RIC
5379  *
5380  * @details
5381  *
5382  *    Function : procRicServiceUpdateAck
5383  *
5384  *    Functionality: Processes RIC service update ack sent by RIC
5385  *
5386  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5387  * @return ROK     - success
5388  *         RFAILED - failure
5389  *
5390  * ****************************************************************/
5391
5392 void procRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
5393 {
5394    uint8_t arrIdx =0, transId =0; 
5395    uint16_t id =0, tmpIdx=0, ranFuncIdx=0;
5396    RicServiceUpdate serviceUpdate;
5397    RANfunctionsIDcause_List_t *rejectedList=NULL;
5398    RICserviceUpdateAcknowledge_t *ricServiceAck=NULL;
5399    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
5400    
5401    DU_LOG("\nINFO   -->  E2AP : RIC service update ack received"); 
5402    memset(&serviceUpdate, 0, sizeof(RicServiceUpdate));
5403    ricServiceAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
5404    
5405    for(arrIdx=0; arrIdx<ricServiceAck->protocolIEs.list.count; arrIdx++)
5406    {
5407       switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id)
5408       {
5409          case ProtocolIE_IDE2_id_TransactionID:
5410          {
5411             transId = ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
5412             if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
5413             (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
5414             {
5415               memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
5416             }
5417             else if((duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId == transId) &&\
5418             (duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
5419             {
5420               memset(&duCb.e2apDb.e2TransInfo.ricInitTransaction[transId], 0, sizeof(E2TransInfo));
5421             }
5422             else
5423             {
5424                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
5425                return ;
5426             }
5427             break;
5428          }
5429          
5430          case ProtocolIE_IDE2_id_RANfunctionsAccepted:
5431             break;
5432
5433          case ProtocolIE_IDE2_id_RANfunctionsRejected:
5434          {
5435             rejectedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
5436             if(rejectedList->list.array)
5437             {
5438                for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
5439                {
5440                   ranFuncRejectedItemIe =  (RANfunctionIDcause_ItemIEs_t*)rejectedList->list.array[ranFuncIdx];
5441                   id = ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID;
5442                   tmpIdx= serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded;
5443                   serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[id-1].id;
5444                   serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[id-1].revisionCounter;
5445                   serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded++;
5446                }
5447             }
5448             break;
5449          }
5450
5451       }
5452    }
5453
5454    if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded)
5455    {
5456       serviceUpdate.dir = E2_NODE_INITIATED;
5457       BuildAndSendRicServiceUpdate(serviceUpdate);
5458    }
5459    freeAperDecodingOfRicServiceUpdateAck(ricServiceAck);
5460 }
5461
5462 /******************************************************************
5463  *
5464  * @brief Deallocation of memory allocated by aper decoder for 
5465  *       RIC service update failure
5466  *
5467  * @details
5468  *
5469  *    Function : freeAperDecodingOfRicServiceUpdateFailure
5470  *
5471  *    Functionality: Deallocation of memory allocated by aper decoder 
5472  *    for RIC service update failure
5473  *
5474  * @params[in] RICserviceUpdateFailure_t *ricServiceFailure;
5475  * @return void
5476  *
5477  * ****************************************************************/
5478
5479 void freeAperDecodingOfRicServiceUpdateFailure(RICserviceUpdateFailure_t *ricServiceFailure)
5480 {
5481    uint8_t arrIdx=0;
5482
5483    if(ricServiceFailure)
5484    {
5485       if(ricServiceFailure->protocolIEs.list.array)
5486       {
5487          for(arrIdx=0; arrIdx<ricServiceFailure->protocolIEs.list.count; arrIdx++)
5488          {
5489             if(ricServiceFailure->protocolIEs.list.array[arrIdx])
5490             {
5491                free(ricServiceFailure->protocolIEs.list.array[arrIdx]);  
5492             }
5493          }
5494          free(ricServiceFailure->protocolIEs.list.array);
5495       }
5496    }
5497 }
5498
5499 /******************************************************************
5500  *
5501  * @brief Processes RIC service update failure sent by RIC
5502  *
5503  * @details
5504  *
5505  *    Function : procRicServiceUpdateFailure
5506  *
5507  *    Functionality: Processes RIC service update failure sent by RIC
5508  *
5509  * @params[in] E2AP_PDU_t ASN decoded E2AP message
5510  * @return ROK     - success
5511  *         RFAILED - failure
5512  *
5513  * ****************************************************************/
5514
5515 void procRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
5516 {
5517    uint8_t arrIdx =0, timerValue=0; 
5518    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
5519
5520    DU_LOG("\nINFO   -->  E2AP : RIC service update failure received"); 
5521    ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
5522
5523    for(arrIdx=0; arrIdx<ricServiceFailure->protocolIEs.list.count; arrIdx++)
5524    {
5525       switch(ricServiceFailure->protocolIEs.list.array[arrIdx]->id)
5526       {
5527          case ProtocolIE_IDE2_id_TransactionID:
5528             {
5529                break;
5530             }
5531          case ProtocolIE_IDE2_id_TimeToWaitE2:
5532             {
5533                timerValue = convertE2WaitTimerEnumToValue(ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
5534                if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR)) == FALSE)
5535                {
5536                   duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR, timerValue);
5537                }
5538                else
5539                {
5540                   DU_LOG("\nERROR   -->  E2AP : EVENT_RIC_SERVICE_UPDATE_TMR  timer is already running");
5541                   return;
5542                }
5543                break; 
5544             }
5545          case ProtocolIE_IDE2_id_CauseE2:
5546             {
5547                break;
5548             }
5549       }
5550    }
5551
5552    freeAperDecodingOfRicServiceUpdateFailure(ricServiceFailure);
5553 }
5554
5555 /******************************************************************
5556  *
5557  * @brief DU Send E2 Node Configuration Update
5558  *
5559  * @details
5560  *
5561  *    Function : duSendE2NodeConfigurationUpdate 
5562  *
5563  *    Functionality: DU Send E2 Node Configuration Update
5564  *
5565  * @return ROK     - success
5566  *         RFAILED - failure
5567  *
5568  * ****************************************************************/
5569
5570 uint8_t duSendE2NodeConfigurationUpdate()
5571 {
5572    E2NodeConfigList e2NodeList;
5573    CmLList *node =NULL;
5574    E2NodeComponent *e2NodeComponentInfo=NULL;
5575
5576    memset(&e2NodeList, 0, sizeof(E2NodeConfigList));
5577    CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node);
5578    while(node)
5579    {
5580       e2NodeComponentInfo = (E2NodeComponent*)node->node;
5581
5582       if(e2NodeComponentInfo->componentRequestPart && e2NodeComponentInfo->componentResponsePart)
5583       {
5584          switch(e2NodeComponentInfo->componentActionType)
5585          {
5586             case E2_NODE_COMPONENT_ADD:
5587                {
5588                   e2NodeList.addE2Node[e2NodeList.addE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
5589                   e2NodeList.addE2Node[e2NodeList.addE2NodeCount].actionType = e2NodeComponentInfo->componentActionType;
5590                   e2NodeList.removeE2NodeCount++;
5591                   break;
5592                }
5593             case E2_NODE_COMPONENT_UPDATE:
5594                {
5595                   e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
5596                   e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].actionType = e2NodeComponentInfo->componentActionType;
5597                   e2NodeList.updateE2NodeCount++;
5598                   break;
5599
5600                }
5601             case E2_NODE_COMPONENT_DEL:
5602                {
5603                   e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].interface = e2NodeComponentInfo->interfaceType;
5604                   e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].actionType = e2NodeComponentInfo->componentActionType;
5605                   e2NodeList.removeE2NodeCount++;
5606                   break;
5607                }
5608          }
5609       }
5610       node = node->next;
5611    }
5612
5613    if(BuildAndSendE2NodeConfigUpdate(&e2NodeList) !=ROK)
5614    {
5615       DU_LOG("\nERROR  -->  E2AP : Failed to build and send e2 node config update message to RIC_stub");
5616       return RFAILED;
5617    }
5618    return ROK;
5619 }
5620
5621 /*******************************************************************
5622  *
5623  * @brief Free RIC Subscription Modification Required
5624  *
5625  * @details
5626  *
5627  *    Function : FreeRicSubsModRequired
5628  *
5629  * Functionality: Freqq RIC Subscription Modification required
5630  *
5631  * @param  E2AP Message PDU to be freed
5632  * @return void
5633  *
5634  ******************************************************************/
5635 void FreeRicSubsModRequired(E2AP_PDU_t *e2apMsg)
5636 {
5637    uint8_t ieIdx = 0, arrIdx = 0;
5638    RICsubscriptionModificationRequired_t  *ricSubsModReqd = NULLP;
5639    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
5640    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
5641    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
5642
5643    if(e2apMsg)
5644    {
5645       if(e2apMsg->choice.initiatingMessage)
5646       {
5647          ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired;
5648          if(ricSubsModReqd->protocolIEs.list.array)
5649          {
5650             for(ieIdx = 0; ieIdx < ricSubsModReqd->protocolIEs.list.count; ieIdx++)
5651             {
5652                if(ricSubsModReqd->protocolIEs.list.array[ieIdx])
5653                {
5654                   ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
5655                   switch(ricSubsModReqdIe->id)
5656                   {
5657                      case ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List:
5658                         {
5659                            actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
5660                            if(actionToBeModList->list.array)
5661                            {
5662                               for(arrIdx = 0; arrIdx < actionToBeModList->list.count; arrIdx++)
5663                               { 
5664                                  DU_FREE(actionToBeModList->list.array[arrIdx], \
5665                                     sizeof(RICaction_RequiredToBeModified_ItemIEs_t));
5666                               }
5667                               DU_FREE(actionToBeModList->list.array, actionToBeModList->list.size);
5668                            }
5669                            break;
5670                         }
5671
5672                      case ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List:
5673                         {
5674                            actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
5675                            if(actionToBeRmvList->list.array)
5676                            {
5677                               for(arrIdx = 0; arrIdx < actionToBeRmvList->list.count; arrIdx++)
5678                               { 
5679                                  DU_FREE(actionToBeRmvList->list.array[arrIdx], \
5680                                     sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t));
5681                               }
5682                               DU_FREE(actionToBeRmvList->list.array, actionToBeRmvList->list.size);
5683                            }
5684                            break;
5685                         }
5686
5687                      default:
5688                         break;
5689                   }
5690                   DU_FREE(ricSubsModReqd->protocolIEs.list.array[ieIdx], \
5691                         sizeof(RICsubscriptionModificationRequired_IEs_t));
5692                }
5693             }
5694             DU_FREE(ricSubsModReqd->protocolIEs.list.array, ricSubsModReqd->protocolIEs.list.size);
5695          }
5696          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5697       }
5698       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
5699    }
5700 }
5701
5702 /* A RIC Subscription includes RIC subsequent action only for RIC Insert service.
5703  * However, E2SM-KPM supports only RIC Report service.
5704  * Hence there is no subsequent action in RIC subscription that may require modification.
5705  * So commenting the action-modification IEs for the time being
5706  */
5707 #if 0
5708 /*******************************************************************
5709  *
5710  * @brief Fill Action required to be modified list
5711  *
5712  * @details
5713  *
5714  *    Function : FillActionReqdToBeModList
5715  *
5716  * Functionality: Fill Action required to be modified list
5717  *
5718  * @param  RIC Actions Required To Be Modified List to be filled
5719  *         Number of actions to be modified
5720  *         RIC Subscription DB
5721  * @return ROK     - success
5722  *         RFAILED - failure
5723  *
5724  ******************************************************************/
5725 uint8_t FillActionReqdToBeModList(RICactions_RequiredToBeModified_List_t *actionToBeModList, uint8_t numActionsMod, \
5726    RicSubscription *ricSubscription)
5727 {
5728    uint8_t arrIdx = 0, actionIdx = 0;
5729    RICaction_RequiredToBeModified_ItemIEs_t *actionToBeMod = NULL;
5730
5731    actionToBeModList->list.count = numActionsMod;
5732    actionToBeModList->list.size = numActionsMod * sizeof(RICaction_RequiredToBeModified_ItemIEs_t *);
5733    DU_ALLOC(actionToBeModList->list.array, actionToBeModList->list.size);
5734    if(!actionToBeModList->list.array)
5735    {
5736       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
5737       return RFAILED;
5738    }
5739
5740    arrIdx = 0;
5741    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
5742    {
5743       if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD)
5744       {
5745          DU_ALLOC(actionToBeModList->list.array[arrIdx], sizeof(RICaction_RequiredToBeModified_ItemIEs_t));
5746          if(!actionToBeModList->list.array[arrIdx])
5747          {
5748             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
5749             return RFAILED;
5750          }
5751          actionToBeMod = (RICaction_RequiredToBeModified_ItemIEs_t *)actionToBeModList->list.array[arrIdx];
5752
5753          actionToBeMod->id = ProtocolIE_IDE2_id_RICaction_RequiredToBeModified_Item;
5754          actionToBeMod->criticality = CriticalityE2_reject;
5755          actionToBeMod->value.present = \
5756             RICaction_RequiredToBeModified_ItemIEs__value_PR_RICaction_RequiredToBeModified_Item;
5757          actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricActionID = \
5758             ricSubscription->actionSequence[actionIdx].actionId;
5759          actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricTimeToWait = RICtimeToWait_w5ms;
5760
5761          arrIdx++;
5762       }
5763    }
5764
5765    return ROK;
5766 }
5767 #endif
5768
5769 /*******************************************************************
5770  *
5771  * @brief Fill Action required to be removed list
5772  *
5773  * @details
5774  *
5775  *    Function : FillActionReqdToBeRmvList
5776  *
5777  * Functionality: Fill Action required to be removed list
5778  *
5779  * @param  RIC Actions Required To Be Removed List to be filled
5780  *         Number of actions to be removed
5781  *         RIC Subscription DB
5782  * @return ROK     - success
5783  *         RFAILED - failure
5784  *
5785  ******************************************************************/
5786 uint8_t FillActionReqdToBeRmvList(RICactions_RequiredToBeRemoved_List_t *actionToBeRmvList, uint8_t numActionsRmv, \
5787    RicSubscription *ricSubscription)
5788 {
5789    uint8_t arrIdx = 0, actionIdx = 0;
5790    RICaction_RequiredToBeRemoved_ItemIEs_t *actionToBeRmv = NULL;
5791
5792    actionToBeRmvList->list.count = numActionsRmv;
5793    actionToBeRmvList->list.size = numActionsRmv * sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t *);
5794    DU_ALLOC(actionToBeRmvList->list.array, actionToBeRmvList->list.size);
5795    if(!actionToBeRmvList->list.array)
5796    {
5797       DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
5798       return RFAILED;
5799    }
5800
5801    arrIdx = 0;
5802    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
5803    {
5804       if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL)
5805       {
5806          DU_ALLOC(actionToBeRmvList->list.array[arrIdx], sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t));
5807          if(!actionToBeRmvList->list.array[arrIdx])
5808          {
5809             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
5810             return RFAILED;
5811          }
5812          actionToBeRmv = (RICaction_RequiredToBeRemoved_ItemIEs_t *)actionToBeRmvList->list.array[arrIdx];
5813
5814          actionToBeRmv->id = ProtocolIE_IDE2_id_RICaction_RequiredToBeRemoved_Item;
5815          actionToBeRmv->criticality = CriticalityE2_reject;
5816          actionToBeRmv->value.present = \
5817             RICaction_RequiredToBeRemoved_ItemIEs__value_PR_RICaction_RequiredToBeRemoved_Item;
5818          actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.ricActionID = \
5819             ricSubscription->actionSequence[actionIdx].actionId;
5820          fillE2Cause(&actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.cause, \
5821             ricSubscription->actionSequence[actionIdx].failureCause);
5822
5823          arrIdx++;
5824       }
5825    }
5826
5827    return ROK;
5828 }
5829
5830 /*******************************************************************
5831  *
5832  * @brief Fill RIC Subscription Modification Required IEs
5833  *
5834  * @details
5835  *
5836  *    Function : FillRicSubsModRequired
5837  *
5838  * Functionality: Fill RIC Subscription Modification Required IEs
5839  *
5840  * @param  RIC Subscription Modification Required IEs to be filled
5841  *         RIC Subscription DB
5842  * @return ROK     - success
5843  *         RFAILED - failure
5844  *
5845  ******************************************************************/
5846 uint8_t FillRicSubsModRequired(RICsubscriptionModificationRequired_t *ricSubsModReqd, RicSubscription *ricSubscription)
5847 {
5848    uint8_t ieIdx = 0, elementCnt=0, actionIdx = 0;
5849    uint8_t numActionsMod = 0, numActionsRmv = 0;
5850    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
5851    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
5852
5853 /* Unused in case of E2SM-KPM */
5854 #if 0
5855    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
5856 #endif
5857
5858    /* Count number of Actions to be modified or deleted */
5859    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
5860    {
5861       if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD)
5862          numActionsMod++;
5863       else if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL)
5864          numActionsRmv++;
5865    }
5866
5867    /* Count number of IEs to be added to messages */
5868    elementCnt = 2;
5869    if(numActionsMod)
5870       elementCnt++;
5871    if(numActionsRmv)
5872       elementCnt++;
5873
5874    ricSubsModReqd->protocolIEs.list.count = elementCnt;
5875    ricSubsModReqd->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationRequired_IEs_t *);
5876    DU_ALLOC(ricSubsModReqd->protocolIEs.list.array, ricSubsModReqd->protocolIEs.list.size);
5877    if(!ricSubsModReqd->protocolIEs.list.array)
5878    {
5879       DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
5880       return RFAILED;
5881    }
5882
5883    for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
5884    {
5885       DU_ALLOC(ricSubsModReqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRequired_IEs_t));
5886       if(!ricSubsModReqd->protocolIEs.list.array[ieIdx])
5887       {
5888          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
5889          return RFAILED;
5890       }
5891    }
5892
5893    /* RIC Request ID */
5894    ieIdx = 0;
5895    ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
5896    ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICrequestID;
5897    ricSubsModReqdIe->criticality = CriticalityE2_reject;
5898    ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RICrequestID;
5899    ricSubsModReqdIe->value.choice.RICrequestID.ricRequestorID = ricSubscription->requestId.requestorId;
5900    ricSubsModReqdIe->value.choice.RICrequestID.ricInstanceID = ricSubscription->requestId.instanceId;
5901
5902    /* RAN Function ID */
5903    ieIdx++;
5904    ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
5905    ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RANfunctionID;
5906    ricSubsModReqdIe->criticality = CriticalityE2_reject;
5907    ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RANfunctionID;
5908    ricSubsModReqdIe->value.choice.RANfunctionID = ricSubscription->ranFuncId;
5909
5910 /* A RIC Subscription includes RIC subsequent action only for RIC Insert service.
5911  * However, E2SM-KPM supports only RIC Report service.
5912  * Hence there is no subsequent action in RIC subscription that may require modification.
5913  * So commenting the action-modification IEs for the time being
5914  */
5915 #if 0
5916    /* RIC Actions Required to be Modified */
5917    if(numActionsMod)
5918    {
5919       ieIdx++;
5920       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
5921       ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List;
5922       ricSubsModReqdIe->criticality = CriticalityE2_reject;
5923       ricSubsModReqdIe->value.present = \
5924          RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeModified_List;
5925       actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
5926
5927       if(FillActionReqdToBeModList(actionToBeModList, numActionsMod, ricSubscription) != ROK)
5928       {
5929          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill actions required to be modified list", __func__);
5930          return RFAILED;
5931       }
5932    }
5933 #endif
5934
5935    /* RIC Actions Required to be removed */
5936    if(numActionsRmv)
5937    {
5938       ieIdx++;
5939       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
5940       ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List;
5941       ricSubsModReqdIe->criticality = CriticalityE2_reject;
5942       ricSubsModReqdIe->value.present = \
5943          RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeRemoved_List;
5944       actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
5945
5946       if(FillActionReqdToBeRmvList(actionToBeRmvList, numActionsRmv, ricSubscription) != ROK)
5947       {
5948          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill actions required to be removed list", __func__);
5949          return RFAILED;
5950       }
5951    }
5952
5953    return ROK;
5954 }
5955
5956 /*******************************************************************
5957  *
5958  * @brief Builds and Send RIC Subscription Modification Required
5959  *        message
5960  *
5961  * @details
5962  *
5963  *    Function : BuildAndSendRicSubsModRequired
5964  *
5965  * Functionality:  Builds and Send RIC Subscription Modification 
5966  *    Required message
5967  *
5968  * @param  RIC Subscription DB
5969  * @return ROK     - success
5970  *         RFAILED - failure
5971  *
5972  ******************************************************************/
5973 uint8_t BuildAndSendRicSubsModRequired(RicSubscription *ricSubscription)
5974 {
5975    uint8_t ret = RFAILED;
5976    E2AP_PDU_t        *e2apMsg = NULLP;
5977    RICsubscriptionModificationRequired_t  *ricSubsModReqd = NULLP;
5978    asn_enc_rval_t     encRetVal;       /* Encoder return value */
5979
5980    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Required \n");
5981    while(true)
5982    {
5983       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
5984       if(e2apMsg == NULLP)
5985       {
5986          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
5987          break;
5988       }
5989
5990       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
5991       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5992       if(e2apMsg->choice.initiatingMessage == NULLP)
5993       {
5994          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__);
5995          break;
5996       }
5997       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
5998       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired;
5999       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionModificationRequired;
6000
6001       ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired;
6002
6003       if(FillRicSubsModRequired(ricSubsModReqd, ricSubscription) != ROK)
6004       {
6005          DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Subscription Modification Required IEs", __func__);
6006          break;
6007       }
6008       
6009       /* Encode */
6010       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6011
6012       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6013       encBufSize = 0;
6014       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6015       if(encRetVal.encoded == ENCODE_FAIL)
6016       {
6017          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Modifiction Required structure (at %s)\n",\
6018                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6019          break;
6020       }
6021       else
6022       {
6023          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RIC Subscription Modification Required \n");
6024 #ifdef DEBUG_ASN_PRINT
6025          for(int i=0; i< encBufSize; i++)
6026          {
6027             printf("%x",encBuf[i]);
6028          }
6029 #endif
6030       }
6031       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
6032       {
6033          DU_LOG("\nERROR  -->  E2AP : Sending RIC Subscription Modification Required failed");
6034       }
6035
6036       ret = ROK;
6037       break;
6038    }
6039
6040    /* Free RIC Subscription modification required */
6041    FreeRicSubsModRequired(e2apMsg);
6042    return ret;
6043 }
6044
6045 /*******************************************************************
6046  *
6047  * @brief Free APER decoding of RIC Subscription Modification Confirm
6048  *
6049  * @details
6050  *
6051  *    Function : freeAperDecodingOfRicSubsModConfirm
6052  *
6053  * Functionality:  Free APER decoding of RIC Subscription 
6054  *   Modification Confirm
6055  *
6056  * @param  E2AP Message PDU
6057  * @return void
6058  *
6059  ******************************************************************/
6060 void freeAperDecodingOfRicSubsModConfirm(E2AP_PDU_t *e2apMsg)
6061 {
6062    uint8_t ieIdx = 0, arrIdx=0;
6063    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
6064    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
6065    RICactions_ConfirmedForModification_List_t *modCfmList = NULLP;
6066    RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP;
6067    RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP;
6068    RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP;
6069
6070    if(e2apMsg && e2apMsg->choice.successfulOutcome)
6071    {
6072       ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
6073       if(ricSubsModCfm->protocolIEs.list.array)
6074       {
6075          for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++)
6076          {
6077             if(ricSubsModCfm->protocolIEs.list.array[ieIdx])
6078             {
6079                ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
6080                switch(ricSubsModCfmIe->id)
6081                {
6082                   case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List:
6083                      {
6084                         modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List;
6085                         if(modCfmList->list.array)
6086                         {
6087                            for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
6088                            {
6089                               if(modCfmList->list.array[arrIdx])
6090                                  free(modCfmList->list.array[arrIdx]);
6091                            }
6092                            free(modCfmList->list.array);
6093                         }
6094                         break;
6095                      }
6096
6097                   case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List:
6098                      {
6099                         modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List;
6100                         if(modRefusedList->list.array)
6101                         {
6102                            for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
6103                            {
6104                               if(modRefusedList->list.array[arrIdx])
6105                                  free(modRefusedList->list.array[arrIdx]);
6106                            }
6107                            free(modRefusedList->list.array);
6108                         }
6109                         break;
6110                      }
6111
6112                   case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List:
6113                      {
6114                         rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List;
6115                         if(rmvCfmList->list.array)
6116                         {
6117                            for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
6118                            {
6119                               if(rmvCfmList->list.array[arrIdx])
6120                                  free(rmvCfmList->list.array[arrIdx]);
6121                            }
6122                            free(rmvCfmList->list.array);
6123                         }
6124                         break;
6125                      }
6126
6127                   case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List:
6128                      {
6129                         rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List;
6130                         if(rmvFailList->list.array)
6131                         {
6132                            for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
6133                            {
6134                               if(rmvFailList->list.array[arrIdx])
6135                                  free(rmvFailList->list.array[arrIdx]);
6136                            }
6137                            free(rmvFailList->list.array);
6138                         }
6139                         break;
6140                      }
6141
6142                   default:
6143                      break;
6144
6145                }
6146                free(ricSubsModCfmIe);
6147             }
6148          }
6149          free(ricSubsModCfm->protocolIEs.list.array);
6150       }
6151    }
6152 }
6153
6154 /*******************************************************************
6155  *
6156  * @brief Process RIC Subscription Modification Confirm Message
6157  *
6158  * @details
6159  *
6160  *    Function : procRicSubscriptionModificationConfirm
6161  *
6162  * Functionality:  Process RIC Subscription Modification Confirm
6163  *    Message received from RIC. 
6164  *
6165  * @param  E2AP Message PDU
6166  * @return void
6167  *
6168  ******************************************************************/
6169 void procRicSubscriptionModificationConfirm(E2AP_PDU_t *e2apMsg)
6170 {
6171    uint8_t actionId = 0, ieIdx = 0, arrIdx = 0;
6172    uint16_t ranFuncId = 0;
6173    bool procFailure = false;
6174    RicRequestId ricReqId;
6175    RanFunction *ranFuncDb = NULLP;
6176    CmLList *ricSubsNode = NULLP;
6177    RicSubscription *ricSubsDb = NULLP;
6178    ActionInfo *actionDb = NULLP;
6179
6180    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
6181    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
6182
6183 /* Not used in case of E2SM-KPM */
6184 #if 0
6185    RICactions_ConfirmedForModification_List_t *modCfmList = NULLP;
6186    RICaction_ConfirmedForModification_ItemIEs_t *modCfmListItem = NULLP;
6187
6188    RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP;
6189    RICaction_RefusedToBeModified_ItemIEs_t *modRefusedListItem = NULLP;
6190 #endif
6191
6192    RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP;
6193    RICaction_ConfirmedForRemoval_ItemIEs_t *rmvCfmListItem = NULLP;
6194
6195    RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP;
6196    RICaction_RefusedToBeRemoved_ItemIEs_t *rmvFailListItem = NULLP;
6197
6198    DU_LOG("\nINFO   -->  E2AP : %s: Received RIC Subscription Modification Confirm", __func__);
6199
6200    do{
6201       if(!e2apMsg)
6202       {
6203          DU_LOG("\nERROR  -->  E2AP : %s: E2AP Message is NULL", __func__);
6204          break;
6205       }
6206
6207       if(!e2apMsg->choice.successfulOutcome)
6208       {
6209          DU_LOG("\nERROR  -->  E2AP : %s: Successful Outcome in E2AP message is NULL", __func__);
6210          break;
6211       }
6212
6213       ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
6214       if(!ricSubsModCfm->protocolIEs.list.array)
6215       {
6216          DU_LOG("\nERROR  -->  E2AP : %s: Array conatining E2AP message IEs is null", __func__);
6217          break;
6218       }
6219
6220       for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++)
6221       {
6222          if(!ricSubsModCfm->protocolIEs.list.array[ieIdx])
6223          {
6224             DU_LOG("\nERROR  -->  E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx);
6225             break;
6226          }
6227
6228          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
6229          switch(ricSubsModCfmIe->id)
6230          {
6231             case ProtocolIE_IDE2_id_RICrequestID:
6232                {
6233                   memset(&ricReqId, 0, sizeof(RicRequestId));
6234                   ricReqId.requestorId = ricSubsModCfmIe->value.choice.RICrequestID.ricRequestorID;
6235                   ricReqId.instanceId = ricSubsModCfmIe->value.choice.RICrequestID.ricInstanceID;
6236                   break;
6237                }
6238
6239             case ProtocolIE_IDE2_id_RANfunctionID:
6240                {
6241                   ranFuncId = ricSubsModCfmIe->value.choice.RANfunctionID;
6242                   ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
6243                   if(!ranFuncDb)
6244                   {
6245                      DU_LOG("\nERROR  -->  E2AP : %s: RAN Function ID [%d] not found", __func__, ranFuncId);
6246                      procFailure = true;
6247                      break;
6248                   }
6249
6250                   ricSubsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode); 
6251                   if(!ricSubsDb)
6252                   {
6253                      DU_LOG("\nERROR  -->  E2AP : %s: RIC Subscription not found for Requestor_ID [%d] Instance_ID [%d]",\
6254                            __func__, ricReqId.requestorId, ricReqId.instanceId);
6255                      procFailure = true;
6256                      break;
6257                   }
6258
6259                   break;
6260                }
6261
6262 /* A RIC Subscription includes RIC subsequent action only for RIC Insert service. 
6263  * However, E2SM-KPM supports only RIC Report service. 
6264  * Hence there is no subsequent action in RIC subscription that may require modification. 
6265  * So commenting the action-modification IEs for the time being 
6266  */
6267 #if 0
6268             case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List:
6269                {
6270                   modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List;
6271                   for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
6272                   {
6273                      modCfmListItem = (RICaction_ConfirmedForModification_ItemIEs_t *)modCfmList->list.array[arrIdx];
6274                      actionId = modCfmListItem->value.choice.RICaction_ConfirmedForModification_Item.ricActionID;
6275
6276                      actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6277                      if(!actionDb)
6278                      {
6279                         DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6280                      }
6281                      else
6282                      {
6283                         actionDb->action = CONFIG_UNKNOWN;
6284                         /* Further handling can be added here in future once the
6285                          * use case of this procedure is identified */
6286                      }
6287                      actionDb = NULLP;
6288                   }
6289                   break;
6290                }
6291
6292             case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List:
6293                {
6294                   modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List;
6295                   for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
6296                   {
6297                     modRefusedListItem = (RICaction_RefusedToBeModified_ItemIEs_t *)modRefusedList->list.array[arrIdx];
6298                     actionId = modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.ricActionID;
6299                     actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6300                     if(!actionDb)
6301                     {
6302                        DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6303                     }
6304                     else
6305                     {
6306                        /* Spec doesnt mention if in case of failure, DU should retry for modify action 
6307                         * Hence, chaging the action from CONFIG_MOD to CONFIG_UNKNOWN
6308                         */
6309                         actionDb->action = CONFIG_UNKNOWN;
6310                     }
6311                     actionDb = NULLP;
6312                   }
6313                   break;
6314                }
6315 #endif
6316
6317             case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List:
6318                {
6319                   rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List;
6320                   for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
6321                   {
6322                      rmvCfmListItem = (RICaction_ConfirmedForRemoval_ItemIEs_t *)rmvCfmList->list.array[arrIdx];
6323                      actionId = rmvCfmListItem->value.choice.RICaction_ConfirmedForRemoval_Item.ricActionID;
6324                      actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6325                      if(!actionDb)
6326                      {
6327                         DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6328                      }
6329                      else
6330                      {
6331                         deleteActionSequence(actionDb);
6332                         actionDb =NULLP;
6333                         ricSubsDb->numOfActions--;
6334                         /* Further handling can include :
6335                          * Deletion of this action from all DU layers 
6336                          */
6337                      }
6338                      actionDb = NULLP;
6339                   }
6340                   break;
6341                }
6342
6343             case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List:
6344                {
6345                   rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List;
6346                   for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
6347                   {
6348                      rmvFailListItem = (RICaction_RefusedToBeRemoved_ItemIEs_t *)rmvFailList->list.array[arrIdx];
6349                      actionId = rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.ricActionID;
6350                      actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb);
6351                      if(!actionDb)
6352                      {
6353                         DU_LOG("\nERROR  -->  E2AP : %s: Action ID [%d] not found", __func__, actionId);
6354                      }
6355                      else
6356                      {
6357                         actionDb->action = CONFIG_UNKNOWN;
6358                      }
6359                      actionDb = NULLP;
6360                   }
6361                   break;
6362                }
6363
6364             default:
6365                break;
6366          } /* End of switch for Protocol IE Id */
6367
6368          if(procFailure)
6369             break;
6370       } /* End of for loop for Protocol IE list */
6371
6372       break;
6373    }while(true);
6374
6375    freeAperDecodingOfRicSubsModConfirm(e2apMsg);
6376    return;
6377 }
6378
6379 /******************************************************************
6380 * @brief Deallocate the memory allocated for E2 Reset Response
6381 *
6382 * @details
6383 *
6384 *    Function : FreeE2ResetResponse
6385 *
6386 *    Functionality:
6387 *       - freeing the memory allocated for E2ResetResponse
6388 *
6389 * @params[in] E2AP_PDU_t *e2apMsg
6390 * @return ROK     - success
6391 *         RFAILED - failure
6392 *
6393 * ****************************************************************/
6394 void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg)
6395 {
6396    uint8_t ieIdx =0;
6397    ResetResponseE2_t *resetResponse;
6398
6399    if(e2apMsg != NULLP)
6400    {
6401       if(e2apMsg->choice.successfulOutcome != NULLP)
6402       {
6403          resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
6404          if(resetResponse->protocolIEs.list.array)
6405          {
6406             for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
6407             {
6408                if(resetResponse->protocolIEs.list.array[ieIdx])
6409                {
6410                   DU_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
6411                }
6412             }
6413             DU_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
6414          }
6415
6416          DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
6417       }
6418       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
6419    }
6420 }
6421
6422 /*******************************************************************
6423  *
6424  * @brief Buld and send the E2 Reset Response msg
6425  *
6426  * @details
6427  *
6428  *    Function : BuildAndSendE2ResetResponse
6429  *
6430  *    Functionality:
6431  *         - Buld and send the E2 Reset Response Message
6432  *
6433  * @params[in] Trans Id
6434  * @return ROK     - success
6435  *         RFAILED - failure
6436  *
6437  * ****************************************************************/
6438 uint8_t BuildAndSendResetResponse(uint8_t transId)
6439 {
6440    uint8_t           ieIdx = 0, elementCnt = 0;
6441    uint8_t           ret = RFAILED;
6442    E2AP_PDU_t        *e2apMsg = NULLP;
6443    ResetResponseE2_t *resetResponse;
6444    asn_enc_rval_t    encRetVal;       /* Encoder return value */
6445
6446    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
6447    do
6448    {
6449       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
6450       if(e2apMsg == NULLP)
6451       {
6452          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
6453          break;
6454       }
6455       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
6456
6457       DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
6458       if(e2apMsg->choice.successfulOutcome == NULLP)
6459       {
6460          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
6461          break;
6462       }
6463
6464       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
6465       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
6466       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
6467       resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
6468
6469       elementCnt = 1;
6470       resetResponse->protocolIEs.list.count = elementCnt;
6471       resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
6472       DU_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
6473       if(!resetResponse->protocolIEs.list.array)
6474       {
6475          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
6476          break;
6477       }
6478
6479       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
6480       {
6481          DU_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
6482          if(!resetResponse->protocolIEs.list.array[ieIdx])
6483          {
6484             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
6485             break;
6486          }
6487       }
6488       if(ieIdx < elementCnt)
6489          break;
6490
6491       ieIdx = 0;
6492       resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
6493       resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6494       resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
6495       resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
6496
6497       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6498
6499       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6500       encBufSize = 0;
6501       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6502       if(encRetVal.encoded == ENCODE_FAIL)
6503       {
6504          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
6505                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6506          break;
6507       }
6508       else
6509       {
6510          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
6511          for(int i=0; i< encBufSize; i++)
6512          {
6513             DU_LOG("%x",encBuf[i]);
6514          }
6515       }
6516
6517       /* Sending msg */
6518       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
6519       {
6520          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
6521          break;
6522       }
6523
6524       ret = ROK;
6525       break;
6526    }while(true);
6527
6528    FreeE2ResetResponse(e2apMsg);
6529    return ret;
6530 }
6531
6532 /******************************************************************
6533  *
6534  * @brief Deallocation of memory allocated by aper decoder for reset req
6535  *
6536  * @details
6537  *
6538  *    Function : freeAperDecodingOfE2ResetReq
6539  *
6540  *    Functionality: Deallocation of memory allocated by aper decoder for
6541  *    reset req
6542  *
6543  * @params[in] Pointer to resetReq
6544  * @return void
6545  *
6546  * ****************************************************************/
6547 void freeAperDecodingOfE2ResetReq(ResetRequestE2_t *resetReq)
6548 {
6549    uint8_t arrIdx=0;
6550
6551    if(resetReq)
6552    {
6553       if(resetReq->protocolIEs.list.array)
6554       {
6555          for(arrIdx=0; arrIdx<resetReq->protocolIEs.list.count; arrIdx++)
6556          {
6557             if(resetReq->protocolIEs.list.array[arrIdx])
6558             {
6559                free(resetReq->protocolIEs.list.array[arrIdx]);
6560             }
6561          }
6562          free(resetReq->protocolIEs.list.array);
6563       }
6564    }
6565 }
6566
6567 /*******************************************************************
6568  *
6569  * @brief Process reset req received from RIC
6570  *
6571  * @details
6572  *
6573  *    Function : procE2ResetRequest
6574  *
6575  * Functionality: Process reset req received from RIC
6576  *
6577  * @param  E2AP_PDU_t  *e2apMsg
6578  * @return void
6579  *
6580  ******************************************************************/
6581
6582 void procE2ResetRequest(E2AP_PDU_t  *e2apMsg)
6583 {
6584    uint16_t ranFuncIdx=0;
6585    uint8_t arrIdx =0, transId =0;
6586    ResetRequestE2_t *resetReq;
6587
6588    DU_LOG("\nINFO   -->  E2AP : E2 Reset request received");
6589    resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
6590
6591    for(arrIdx=0; arrIdx<resetReq->protocolIEs.list.count; arrIdx++)
6592    {
6593       switch(resetReq->protocolIEs.list.array[arrIdx]->id)
6594       {
6595          case ProtocolIE_IDE2_id_TransactionID:
6596             {
6597                transId = resetReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
6598                break;
6599             }
6600
6601          case ProtocolIE_IDE2_id_CauseE2:
6602             {
6603                for(ranFuncIdx=0; ranFuncIdx<MAX_RAN_FUNCTION; ranFuncIdx++)
6604                {
6605                   if(duCb.e2apDb.ranFunction[ranFuncIdx].id >0)
6606                   {
6607                      deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList));
6608                      memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo));
6609                   }
6610                }
6611                break;
6612             }
6613       }
6614    }
6615    if(BuildAndSendResetResponse(transId) != ROK)
6616    {
6617       DU_LOG("\nERROR  -->  E2AP : Failed to build and send reset response");
6618    }
6619    freeAperDecodingOfE2ResetReq(resetReq);
6620 }
6621
6622 /*******************************************************************
6623  *
6624  * @brief Free APER decoding of RIC Subscription Modification Refuse
6625  *
6626  * @details
6627  *
6628  *    Function : freeAperDecodingOfRicSubsModRefuse
6629  *
6630  * Functionality:  Free APER decoding of RIC Subscription 
6631  *   Modification Refuse
6632  *
6633  * @param  E2AP Message PDU
6634  * @return void
6635  *
6636  ******************************************************************/
6637 void freeAperDecodingOfRicSubsModRefuse(E2AP_PDU_t *e2apMsg)
6638 {
6639    uint8_t ieIdx =0;
6640    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
6641
6642    if(e2apMsg && e2apMsg->choice.unsuccessfulOutcome)
6643    {
6644       ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
6645       if(ricSubsModRefuse->protocolIEs.list.array)
6646       {
6647          for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++)
6648          {
6649             if(ricSubsModRefuse->protocolIEs.list.array[ieIdx])
6650                free(ricSubsModRefuse->protocolIEs.list.array[ieIdx]);
6651          }
6652          free(ricSubsModRefuse->protocolIEs.list.array);
6653       }
6654    }
6655 }
6656
6657 /*******************************************************************
6658  *
6659  * @brief Process RIC Subscription Modification Refuse Message
6660  *
6661  * @details
6662  *
6663  *    Function : procRicSubscriptionModificationRefuse
6664  *
6665  * Functionality:  Process RIC Subscription Modification Refuse
6666  *    Message received from RIC. 
6667  *
6668  * @param  E2AP Message PDU
6669  * @return void
6670  *
6671  ******************************************************************/
6672 void procRicSubscriptionModificationRefuse(E2AP_PDU_t *e2apMsg)
6673 {
6674    uint8_t ieIdx = 0;
6675    uint16_t ranFuncId = 0;
6676    RicRequestId ricReqId;
6677    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
6678    RICsubscriptionModificationRefuse_IEs_t *ricSubsModRefuseIe = NULLP;
6679    CauseE2_t *cause = NULLP;
6680
6681    DU_LOG("\nINFO   -->  E2AP : %s: Received RIC Subscription Modification Refuse", __func__);
6682
6683    do{
6684       if(!e2apMsg)
6685       {
6686          DU_LOG("\nERROR  -->  E2AP : %s: E2AP Message is NULL", __func__);
6687          break;
6688       }
6689
6690       if(!e2apMsg->choice.unsuccessfulOutcome)
6691       {
6692          DU_LOG("\nERROR  -->  E2AP : %s: Unsuccessful Outcome in E2AP message is NULL", __func__);
6693          break;
6694       }
6695
6696       ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
6697       if(!ricSubsModRefuse->protocolIEs.list.array)
6698       {
6699          DU_LOG("\nERROR  -->  E2AP : %s: Array conatining E2AP message IEs is null", __func__);
6700          break;
6701       }
6702
6703       for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++)
6704       {
6705          if(!ricSubsModRefuse->protocolIEs.list.array[ieIdx])
6706          {
6707             DU_LOG("\nERROR  -->  E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx);
6708             break;
6709          }
6710
6711          ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
6712          switch(ricSubsModRefuseIe->id)
6713          {
6714             case ProtocolIE_IDE2_id_RICrequestID:
6715                {
6716                   memset(&ricReqId, 0, sizeof(RicRequestId));
6717                   ricReqId.requestorId = ricSubsModRefuseIe->value.choice.RICrequestID.ricRequestorID;
6718                   ricReqId.instanceId = ricSubsModRefuseIe->value.choice.RICrequestID.ricInstanceID;
6719                   break;
6720                }
6721
6722             case ProtocolIE_IDE2_id_RANfunctionID:
6723                {
6724                   ranFuncId = ricSubsModRefuseIe->value.choice.RANfunctionID;
6725                   break;
6726                }
6727
6728             case ProtocolIE_IDE2_id_CauseE2:
6729                {
6730                   DU_LOG("\nDEBUG  -->  E2AP : %s: RIC subscriptiom modification refused for RIC_Requestor_ID [%d] \
6731                         RIC_Instance_ID [%d] RAN_Function_ID [%d] ", __func__, ricReqId.requestorId, \
6732                         ricReqId.instanceId, ranFuncId);
6733
6734                   cause = &ricSubsModRefuseIe->value.choice.CauseE2;
6735                   printE2ErrorCause(cause);
6736                }
6737
6738             default:
6739                break;
6740          } /* End of switch for Protocol IE Id */
6741       } /* End of for loop for Protocol IE list */
6742
6743       break;
6744    }while(true);
6745
6746    freeAperDecodingOfRicSubsModRefuse(e2apMsg);
6747    return;
6748 }
6749
6750 /*******************************************************************
6751  *
6752  * @brief Handles received E2AP message and sends back response  
6753  *
6754  * @details
6755  *
6756  *    Function : E2APMsgHdlr
6757  *
6758  *    Functionality:
6759  *         - Decodes received E2AP control message
6760  *         - Prepares response message, encodes and sends to SCTP
6761  *
6762  * @params[in] 
6763  * @return ROK     - success
6764  *         RFAILED - failure
6765  *
6766  * ****************************************************************/
6767 void E2APMsgHdlr(Buffer *mBuf)
6768 {
6769    int i =0;
6770    char *recvBuf = NULLP;
6771    MsgLen copyCnt =0;
6772    MsgLen recvBufLen =0;
6773    E2AP_PDU_t *e2apMsg = NULLP;
6774    asn_dec_rval_t rval ={0}; /* Decoder return value */
6775    E2AP_PDU_t e2apasnmsg={0} ;
6776
6777    DU_LOG("\nDEBUG   -->  E2AP : Received E2AP message buffer");
6778    ODU_PRINT_MSG(mBuf, 0,0);
6779
6780    /* Copy mBuf into char array to decode it */
6781    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
6782    DU_ALLOC(recvBuf, (Size)recvBufLen);
6783
6784    if(recvBuf == NULLP)
6785    {
6786       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
6787       return;
6788    }
6789    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
6790    {
6791       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
6792       return;
6793    }
6794
6795 #ifdef DEBUG_ASN_PRINT
6796    printf("\nDEBUG   -->  E2AP : Received flat buffer to be decoded : ");
6797    for(i=0; i< recvBufLen; i++)
6798    {
6799       printf("%x",recvBuf[i]);
6800    }
6801 #endif
6802
6803    /* Decoding flat buffer into E2AP messsage */
6804    e2apMsg = &e2apasnmsg;
6805    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
6806
6807    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
6808    DU_FREE(recvBuf, (Size)recvBufLen);
6809
6810    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
6811    {
6812       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
6813       return;
6814    }
6815    printf("\n");
6816    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6817
6818    switch(e2apMsg->present)
6819    {
6820       case E2AP_PDU_PR_unsuccessfulOutcome:
6821          {
6822             switch(e2apMsg->choice.unsuccessfulOutcome->value.present)
6823             {
6824                case UnsuccessfulOutcomeE2__value_PR_E2setupFailure:
6825                   {
6826                      procE2SetupFailure(e2apMsg);
6827                      break;
6828                   }
6829                case UnsuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateFailure:
6830                   {
6831                      procE2NodeConfigUpdateFailure(e2apMsg);
6832                      break;
6833                   }
6834                case UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure:
6835                   {
6836                      procRicServiceUpdateFailure(e2apMsg);
6837                      break;
6838                   }
6839                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionModificationRefuse:
6840                   {
6841                      procRicSubscriptionModificationRefuse(e2apMsg);
6842                      break;
6843                   }
6844                default:
6845                   {
6846                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome  [%d]",\
6847                            e2apMsg->choice.unsuccessfulOutcome->value.present);
6848                      return;
6849                   }
6850             }
6851             free(e2apMsg->choice.unsuccessfulOutcome);
6852             break;
6853          }
6854       case E2AP_PDU_PR_successfulOutcome:
6855          {
6856             switch(e2apMsg->choice.successfulOutcome->value.present)
6857             {
6858                case SuccessfulOutcomeE2__value_PR_E2setupResponse:
6859                   {
6860                      if(!duCb.e2Status)
6861                      {
6862                         procE2SetupRsp(e2apMsg);
6863                      }
6864                      break;
6865                   }
6866                case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge:
6867                   {
6868                      DU_LOG("\nDEBUG   -->  E2AP : E2 node Config update ack message recevied");
6869                      break;
6870                   }
6871                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
6872                   {
6873                      procResetResponse(e2apMsg);
6874                      break;
6875                   }
6876                case SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge:
6877                   {
6878                      procRicServiceUpdateAck(e2apMsg);
6879                      break;
6880                   }
6881                case SuccessfulOutcomeE2__value_PR_RICsubscriptionModificationConfirm:
6882                   {
6883                      procRicSubscriptionModificationConfirm(e2apMsg);
6884                      break;
6885                   }
6886
6887                default:
6888                   {
6889                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome  [%d]",\
6890                            e2apMsg->choice.successfulOutcome->value.present);
6891                      return;
6892                   }
6893             }/* End of switch(successfulOutcome) */
6894             free(e2apMsg->choice.successfulOutcome);
6895             break;
6896          }
6897
6898       case E2AP_PDU_PR_initiatingMessage:
6899          {
6900             switch(e2apMsg->choice.initiatingMessage->value.present)
6901             {
6902                case InitiatingMessageE2__value_PR_RICsubscriptionRequest: 
6903                   {
6904                      procRicSubscriptionRequest(e2apMsg);
6905                      break;
6906                   }
6907                case InitiatingMessageE2__value_PR_RICserviceQuery:
6908                   {
6909                      procRicServiceQuery(e2apMsg);
6910                      break;
6911                   }
6912                case InitiatingMessageE2__value_PR_ErrorIndicationE2:
6913                   {
6914                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
6915                      break;
6916                   }
6917                case InitiatingMessageE2__value_PR_ResetRequestE2:
6918                   {
6919                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
6920                      procE2ResetRequest(e2apMsg);
6921                      break;
6922                   }
6923                default:
6924                   {
6925                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\
6926                            e2apMsg->choice.initiatingMessage->value.present);
6927                      return;
6928                   }
6929             }/* End of switch(initiatingMessage) */
6930             free(e2apMsg->choice.initiatingMessage);
6931             break;
6932          }
6933       default:
6934          {
6935             DU_LOG("\nERROR  -->  E2AP : Invalid type of e2apMsg->present [%d]",e2apMsg->present);
6936             return;
6937          }
6938          free(e2apMsg);
6939
6940    }/* End of switch(e2apMsg->present) */
6941
6942 } /* End of E2APMsgHdlr */
6943
6944 /**********************************************************************
6945   End of file
6946  **********************************************************************/