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