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