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