[Epic-ID: ODUHIGH-516][Task-ID: 526] Handling of RIC Service Acknowledge and Failure
[o-du/l2.git] / src / ric_stub / ric_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
19 /* This file contains E2AP message handler functions */
20 #include "common_def.h"
21 #include "OCTET_STRING.h"
22 #include "BIT_STRING.h"
23 #include "odu_common_codec.h"
24 #include "ric_stub_sctp.h"
25 #include "ric_stub.h"
26 #include "ric_e2ap_msg_hdl.h"
27 #include "GlobalE2node-gNB-ID.h"
28 #include "ProtocolIE-FieldE2.h"
29 #include "InitiatingMessageE2.h"
30 #include "SuccessfulOutcomeE2.h"
31 #include "UnsuccessfulOutcomeE2.h"
32 #include "E2AP-PDU.h"
33 #include "du_log.h"
34 #include "E2nodeComponentInterfaceF1.h"
35 #include "E2SM-KPM-RANfunction-Description.h"
36 #include "RANfunction-Name.h"
37 #include "RIC-EventTriggerStyle-Item.h"
38 #include "RIC-ReportStyle-Item.h"
39 #include "MeasurementInfo-Action-Item.h"
40 #include "MeasurementInfoItem.h"
41 #include "E2SM-KPM-ActionDefinition-Format1.h"
42 #include "E2SM-KPM-ActionDefinition.h"
43 #include "E2SM-KPM-EventTriggerDefinition-Format1.h"
44 #include "E2SM-KPM-EventTriggerDefinition.h"
45
46
47 /*******************************************************************
48  *
49  * @brief Assigns new transaction id to RIC initiated procedure
50  *
51  * @details
52  *
53  *    Function : assignTransactionId
54  *
55  *    Functionality: Assigns new transaction id to a RIC initiated
56  *       procedure
57  *
58  * @params[in] Region region
59  *             Pool pool
60  * @return ROK     - success
61  *         RFAILED - failure
62  *
63  * ****************************************************************/
64
65 uint8_t assignTransactionId(DuDb *duDb)
66 {
67    uint8_t currTransId = duDb->ricTransIdCounter;
68
69    /* Update to next valid value */
70    duDb->ricTransIdCounter++;
71    if(duDb->ricTransIdCounter == MAX_NUM_TRANSACTION)
72       duDb->ricTransIdCounter = 0;
73
74    return currTransId;
75 }
76
77 /*******************************************************************
78 *
79 * @brief Sends E2 msg over SCTP
80 *
81 * @details
82 *
83 *    Function : SendE2APMsg
84 *
85 *    Functionality: Sends E2 msg over SCTP
86 *
87 * @params[in] Region region
88 *             Pool pool
89 * @return ROK     - success
90 *         RFAILED - failure
91 *
92 * ****************************************************************/
93
94 uint8_t SendE2APMsg(Region region, Pool pool, uint32_t duId)
95 {
96    Buffer *mBuf;
97
98    if(ODU_GET_MSG_BUF(region, pool, &mBuf) == ROK)
99    {
100       if(ODU_ADD_POST_MSG_MULT((Data *)encBuf, encBufSize, mBuf) == ROK)
101       {
102          ODU_PRINT_MSG(mBuf, 0,0);
103  
104          if(sctpSend(duId, mBuf) != ROK)
105          {
106             DU_LOG("\nERROR  -->  E2AP : SCTP Send for E2  failed");
107             ODU_PUT_MSG_BUF(mBuf);
108             return RFAILED;
109          }
110       }
111       else
112       {
113          DU_LOG("\nERROR  -->  E2AP : ODU_ADD_POST_MSG_MULT failed");
114          ODU_PUT_MSG_BUF(mBuf);
115          return RFAILED;
116       }
117       ODU_PUT_MSG_BUF(mBuf);
118    }
119    else
120    {
121       DU_LOG("\nERROR  -->  E2AP : Failed to allocate memory");
122       return RFAILED;
123    }
124  
125    return ROK;
126 } /* SendE2APMsg */
127
128 /*******************************************************************
129  *
130  * @brief Builds Global RIC Id Params
131  *
132  * @details
133  *
134  *    Function : BuildGlobalRicId
135  *
136  *    Functionality: Building the Plmn and ric id
137  *
138  * @params[in] GlobalRIC_ID_t *ricId
139  * @return ROK     - success
140  *         RFAILED - failure
141  *
142  * ****************************************************************/
143
144 uint8_t BuildGlobalRicId(GlobalRIC_ID_t *ricId)
145 {
146    uint8_t unused = 4;
147    uint8_t byteSize = 3;
148    uint8_t ricVal= 1;
149    if(ricId != NULLP)
150    {
151       ricId->pLMN_Identity.size = byteSize * sizeof(uint8_t);
152       RIC_ALLOC(ricId->pLMN_Identity.buf,  ricId->pLMN_Identity.size);
153       buildPlmnId(ricCb.ricCfgParams.plmn , ricId->pLMN_Identity.buf);
154       /* fill ric Id */
155       ricId->ric_ID.size = byteSize * sizeof(uint8_t);
156       RIC_ALLOC(ricId->ric_ID.buf, ricId->ric_ID.size);
157       fillBitString(&ricId->ric_ID, unused, byteSize, ricVal);
158    }
159    return ROK;   
160 }
161
162 /*******************************************************************
163  *
164  * @brief deallocate the memory allocated in E2SetupResponse
165  *
166  * @details
167  *
168  *    Function : FreeE2SetupRsp 
169  *
170  *    Functionality: deallocate the memory allocated in E2SetupResponse 
171  *
172  * @params[in] E2AP_PDU_t *e2apMsg
173  *
174  * @return void
175  * ****************************************************************/
176 void FreeE2SetupRsp(E2AP_PDU_t *e2apMsg)
177 {
178    uint8_t arrIdx = 0, e2NodeConfigIdx=0, ranFuncIdx=0;
179    RANfunctionsID_List_t *ranFuncAcceptedList=NULL;
180    E2setupResponse_t  *e2SetupRsp=NULL;
181    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItemIe=NULL;
182    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList=NULL;
183    E2nodeComponentInterfaceF1_t *f1InterfaceInfo=NULL;
184    
185    if(e2apMsg)
186    {
187       if(e2apMsg->choice.successfulOutcome)
188       {
189          e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
190          if(e2SetupRsp->protocolIEs.list.array)
191          {
192             for(arrIdx=0; arrIdx<e2SetupRsp->protocolIEs.list.count; arrIdx++)
193             {
194                switch(e2SetupRsp->protocolIEs.list.array[arrIdx]->id)
195                {
196                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
197                   {
198                      ranFuncAcceptedList= &e2SetupRsp->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
199                      if(ranFuncAcceptedList->list.array)
200                      {
201                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAcceptedList->list.count; ranFuncIdx++)
202                         {
203                            if(ranFuncAcceptedList->list.array[ranFuncIdx])
204                            {
205                               RIC_FREE(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
206                            }
207                         }
208                         RIC_FREE(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
209                      }
210                      break;
211                   }
212                   case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
213                   {
214                      e2NodeConfigAdditionAckList =&e2SetupRsp->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
215                      if(e2NodeConfigAdditionAckList->list.count)
216                      {
217                         for(e2NodeConfigIdx=0; e2NodeConfigIdx<e2NodeConfigAdditionAckList->list.count; e2NodeConfigIdx++)
218                         {
219                            e2NodeAddAckItemIe = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[e2NodeConfigIdx];
220                            if(e2NodeAddAckItemIe)
221                            {
222                               f1InterfaceInfo = e2NodeAddAckItemIe->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1; 
223                               if(f1InterfaceInfo)
224                               {
225                                  RIC_FREE(f1InterfaceInfo->gNB_DU_ID.buf, f1InterfaceInfo->gNB_DU_ID.size);
226                                  RIC_FREE(f1InterfaceInfo, sizeof(E2nodeComponentInterfaceF1_t));
227                               }
228                               RIC_FREE(e2NodeAddAckItemIe, sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
229                            }
230                         }
231                         RIC_FREE(e2NodeConfigAdditionAckList->list.array, e2NodeConfigAdditionAckList->list.size);
232                      }
233                      break;
234                   }
235                }
236                RIC_FREE(e2SetupRsp->protocolIEs.list.array[arrIdx], sizeof(E2setupResponseIEs_t)); 
237             }
238             RIC_FREE(e2SetupRsp->protocolIEs.list.array, e2SetupRsp->protocolIEs.list.size);
239          }
240          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
241       }
242       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
243    }
244 }
245
246 /*******************************************************************
247  *
248  * @brief Build E2node Component config addition ack list
249  *
250  * @details
251  *
252  *    Function :  BuildE2nodeComponentConfigAdditionAck
253  *
254  *    Functionality: deallocate the memory allocated in E2SetupResponse 
255  *
256  * @params[in] E2nodeComponentConfigAdditionAck_List_t
257  * *e2NodeConfigAdditionAckList
258  *
259  * @return ROK - success
260  *         RFAILED - failure
261  * ****************************************************************/
262
263 uint8_t BuildE2nodeComponentConfigAdditionAck(E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList, DuDb *duDb)
264 {
265    uint8_t arrIdx = 0;
266    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem;
267    
268    e2NodeConfigAdditionAckList->list.count = 1;
269    e2NodeConfigAdditionAckList->list.size = e2NodeConfigAdditionAckList->list.count * sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t*);
270    RIC_ALLOC(e2NodeConfigAdditionAckList->list.array, e2NodeConfigAdditionAckList->list.size);
271    if(e2NodeConfigAdditionAckList->list.array == NULLP)
272    {
273       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
274       return RFAILED;
275    }
276
277    for(arrIdx = 0; arrIdx< e2NodeConfigAdditionAckList->list.count; arrIdx++)
278    {
279       RIC_ALLOC(e2NodeConfigAdditionAckList->list.array[arrIdx], sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
280       if(e2NodeConfigAdditionAckList->list.array[arrIdx] == NULLP)
281       {
282          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
283          return RFAILED;
284       }
285    }
286    e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[0];
287    e2NodeAddAckItem->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck_Item;
288    e2NodeAddAckItem->criticality = CriticalityE2_reject;
289    e2NodeAddAckItem->value.present = E2nodeComponentConfigAdditionAck_ItemIEs__value_PR_E2nodeComponentConfigAdditionAck_Item;
290    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentInterfaceType = duDb->e2NodeComponent.interfaceType;
291
292    /* >E2 Node Component ID */
293    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1;
294    RIC_ALLOC(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\
295          sizeof(E2nodeComponentInterfaceF1_t));
296    if(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1 == NULLP)
297    {
298       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
299       return RFAILED;
300    }
301    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t);
302    RIC_ALLOC(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
303          e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
304
305    if(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP)
306    {
307       DU_LOG("\nERROR  -->list.  E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
308       return RFAILED;
309    }
310    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]  = duDb->e2NodeComponent.componentId;
311    
312    /* >E2 Node Component Configuration Acknowledge*/
313    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentConfigurationAck.updateOutcome = \
314    E2nodeComponentConfigurationAck__updateOutcome_success;
315    
316    return ROK;  
317 }
318
319 /*******************************************************************
320  *
321  * @brief Build RAN function accepted list
322  *
323  * @details
324  *
325  *    Function : BuildRanFunctionAcceptedList
326  *
327  *    Functionality: Build RAN function accepted list 
328  *     ->For ProcedureCodeE2_id_E2setup or ProcedureCodeE2_id_RICserviceQuery  
329  *     we add all the RAN Function list which is present in RIC database.
330  *     ->For any other procedures, we just fill the RAN functions whose ID 
331  *     is present in the recvList
332  *
333  * @params[in] 
334  *    Stored DU databse 
335  *    Count of ran functions to be accepted in the list 
336  *    Received list of RAN functions
337  *    RAN Function list  
338  *    Procedure Code 
339  *
340  * @return ROK - success
341  *         RFAILED - failure
342  * ****************************************************************/
343
344 uint8_t BuildRanFunctionAcceptedList(DuDb *duDb, uint8_t count, RanFunction *ranFunAcceptedList, RANfunctionsID_List_t *ranFuncAcceptedList, uint8_t procedureCode)
345 {
346    uint8_t ranFuncIdx = 0;
347    RANfunctionID_ItemIEs_t *ranFuncAcceptedItemIe=NULL;
348    
349    /* For ProcedureCodeE2_id_E2setup and ProcedureCodeE2_id_RICserviceQuery, 
350     * the number of RAN function list items is equal to the number of 
351     * ran function entries stored in the database.
352     * For any other procedure, the RAN function list count is equal
353     * to the count of ran functions obtained from the function's caller */
354
355    if((procedureCode == ProcedureCodeE2_id_RICserviceQuery)||(procedureCode == ProcedureCodeE2_id_E2setup))
356       ranFuncAcceptedList->list.count = duDb->numOfRanFunction;
357    else
358       ranFuncAcceptedList->list.count = count;
359    
360    ranFuncAcceptedList->list.size = ranFuncAcceptedList->list.count*sizeof(RANfunctionID_ItemIEs_t*);
361    RIC_ALLOC(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
362    if(ranFuncAcceptedList->list.array)
363    {
364       for(ranFuncIdx = 0; ranFuncIdx< ranFuncAcceptedList->list.count; ranFuncIdx++)
365       {
366          RIC_ALLOC(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
367          if(ranFuncAcceptedList->list.array[ranFuncIdx] == NULLP)
368          {
369             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function added list array item");
370             return RFAILED;
371          }
372          ranFuncAcceptedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAcceptedList->list.array[ranFuncIdx];
373          ranFuncAcceptedItemIe->id = ProtocolIE_IDE2_id_RANfunctionID_Item;
374          ranFuncAcceptedItemIe->criticality= CriticalityE2_ignore;
375          ranFuncAcceptedItemIe->value.present = RANfunctionID_ItemIEs__value_PR_RANfunctionID_Item;
376          if((procedureCode == ProcedureCodeE2_id_RICserviceQuery)||(procedureCode == ProcedureCodeE2_id_E2setup))
377          {
378             /* filling the RAN function information with the help of DuDb */
379             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionID = duDb->ranFunction[ranFuncIdx].id;
380             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision= duDb->ranFunction[ranFuncIdx].revisionCounter;
381          }
382          else
383          {
384             /* filling the the RAN function information with the help received list of RAN functions */
385             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionID = ranFunAcceptedList[ranFuncIdx].id;
386             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision= ranFunAcceptedList[ranFuncIdx].revisionCounter;
387          }
388       }
389    }
390    else
391    {
392       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function added list array");
393       return RFAILED;
394    }
395    return ROK;
396 }
397
398 /*******************************************************************
399  *
400  * @brief Builds and sends the E2SetupResponse
401  *
402  * @details
403  *
404  *    Function : BuildAndSendE2SetupRsp
405  *
406  *    Functionality: Constructs the F1SetupResponse message and sends
407  *                   it back to the DU through SCTP.
408  *
409  * @params[in] void **buf,Buffer to which encoded pattern is written into
410  * @params[in] int *size,size of buffer
411  *
412  * @return ROK     - success
413  *         RFAILED - failure
414  *
415  * ****************************************************************/
416
417 uint8_t BuildAndSendE2SetupRsp(DuDb *duDb, uint8_t transId)
418 {
419    E2AP_PDU_t         *e2apMsg = NULL;
420    E2setupResponse_t  *e2SetupRsp;
421    asn_enc_rval_t     encRetVal; 
422    uint8_t            idx;
423    uint8_t            elementCnt;
424    bool  memAllocFailed = false;
425  
426    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup Response\n");
427    while(true)
428    {
429       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); 
430       if(e2apMsg == NULLP)
431       {
432          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
433          break;
434       }
435       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
436       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
437       if(e2apMsg->choice.successfulOutcome == NULLP)
438       {
439          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
440          break;  
441       }
442
443       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
444       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
445       e2apMsg->choice.successfulOutcome->value.present = \
446                                                          SuccessfulOutcomeE2__value_PR_E2setupResponse;
447       e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
448
449       elementCnt = 3;
450       /* Fill Accepted RAN function IE If Ran function information is stored in databse */
451       if(duDb->numOfRanFunction)
452          elementCnt++;
453
454       e2SetupRsp->protocolIEs.list.count = elementCnt;
455       e2SetupRsp->protocolIEs.list.size  = elementCnt * sizeof(E2setupResponseIEs_t*);
456
457       RIC_ALLOC(e2SetupRsp->protocolIEs.list.array, e2SetupRsp->protocolIEs.list.size);
458       if(e2SetupRsp->protocolIEs.list.array == NULLP)
459       {
460          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");
461          break;  
462       }
463
464       for(idx=0; idx<elementCnt; idx++)
465       {
466          RIC_ALLOC(e2SetupRsp->protocolIEs.list.array[idx], sizeof(E2setupResponseIEs_t)); 
467          if(e2SetupRsp->protocolIEs.list.array[idx] == NULLP)
468          { 
469             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");
470             memAllocFailed = true;
471             break;
472          }    
473       }
474       
475       if(memAllocFailed == true)
476       {
477           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");    
478           break;
479       }
480       /* Trans Id */
481       idx = 0;
482       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_TransactionID;
483       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
484       e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_TransactionID; 
485       e2SetupRsp->protocolIEs.list.array[idx]->value.choice.TransactionID  = transId;
486
487       /* Global RIC ID */
488       idx++;
489       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_GlobalRIC_ID;
490       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
491       e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_GlobalRIC_ID;
492
493       if(BuildGlobalRicId(&(e2SetupRsp->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID))!=ROK)
494       {
495          DU_LOG("\nERROR  -->  E2AP : Failed to build Global Ric Id");
496          break;
497       }
498       
499       if(duDb->numOfRanFunction)
500       {
501          /* Accepted RAN function Id */
502          idx++;
503          e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
504          e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
505          e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_RANfunctionsID_List;
506          if(BuildRanFunctionAcceptedList(duDb, 0, NULL, &e2SetupRsp->protocolIEs.list.array[idx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_E2setup)!=ROK)
507          {
508             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
509             break;         
510          }
511       }
512
513       /* E2 Node Component Configuration Addition Acknowledge List*/
514       idx++;
515       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck;
516       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
517       e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
518          E2setupResponseIEs__value_PR_E2nodeComponentConfigAdditionAck_List;
519       if(BuildE2nodeComponentConfigAdditionAck(&e2SetupRsp->protocolIEs.list.array[idx]->\
520          value.choice.E2nodeComponentConfigAdditionAck_List, duDb) != ROK)
521       {
522          DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config addition ack list");
523          break;
524       }
525
526       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
527       memset(encBuf, 0, ENC_BUF_MAX_LEN);
528       encBufSize = 0;
529       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
530
531       /* Check encode results */
532       if(encRetVal.encoded == ENCODE_FAIL)
533       {
534          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupResponse structure (at %s)\n",\
535                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
536          break;   
537       } 
538       else 
539       {
540          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SetupResponse\n");
541          for(int i=0; i< encBufSize; i++)
542          {
543             DU_LOG("%x",encBuf[i]);
544          } 
545       }
546
547       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
548       {
549          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Response failed");      
550          break;   
551       }
552       break;
553    }
554
555    FreeE2SetupRsp(e2apMsg);
556    BuildAndSendRicSubscriptionReq(duDb);
557    return ROK;
558 }
559
560 /*******************************************************************
561  *
562  * @brief Free RIC Subscription Details
563  *
564  * @details
565  *
566  *    Function : FreeRicSubsDetails
567  *
568  *    Functionality: Free the RIC Subscription Details
569  *
570  * @params[in] RICsubscriptionDetails_t *subsDetails
571  * @return void
572  *
573  * ****************************************************************/
574 void FreeRicSubsDetails(RICsubscriptionDetails_t *subsDetails)
575 {
576    uint8_t elementIdx = 0;
577    RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
578
579    RIC_FREE(subsDetails->ricEventTriggerDefinition.buf, subsDetails->ricEventTriggerDefinition.size);
580
581    if(subsDetails->ricAction_ToBeSetup_List.list.array)
582    {
583       for(elementIdx = 0; elementIdx < subsDetails->ricAction_ToBeSetup_List.list.count; elementIdx++)
584       {
585          if(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
586          {
587             actionItem = (RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx];
588             if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
589             {
590                RIC_FREE(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf, \
591                   actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->size);
592                RIC_FREE(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, sizeof(RICactionDefinition_t));
593             }
594             RIC_FREE(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], sizeof(RICaction_ToBeSetup_ItemIEs_t))
595          }
596       }
597       RIC_FREE(subsDetails->ricAction_ToBeSetup_List.list.array, subsDetails->ricAction_ToBeSetup_List.list.size);
598    }
599 }
600
601 /*******************************************************************
602  *
603  * @brief Free RIC Subscription Request
604  *
605  * @details
606  *
607  *    Function : FreeRicSubscriptionReq
608  *
609  * Functionality : Free RIC Subscription Request
610  *
611  * @return ROK     - success
612  *         RFAILED - failure
613  *
614  ******************************************************************/
615 void FreeRicSubscriptionReq(E2AP_PDU_t *e2apRicMsg)
616 {
617    uint8_t idx = 0;
618    RICsubscriptionRequest_t   *ricSubscriptionReq;
619
620    if(e2apRicMsg)
621    {
622       if(e2apRicMsg->choice.initiatingMessage)
623       {
624          ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
625          if(ricSubscriptionReq->protocolIEs.list.array)
626          {
627             for(idx=0; idx < ricSubscriptionReq->protocolIEs.list.count; idx++)
628             {
629                switch(ricSubscriptionReq->protocolIEs.list.array[idx]->id)
630                {
631                   case ProtocolIE_IDE2_id_RICsubscriptionDetails:
632                      {
633                         FreeRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails));
634                         break;
635                      }
636                }               
637                RIC_FREE(ricSubscriptionReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionRequest_IEs_t));
638             }
639             RIC_FREE(ricSubscriptionReq->protocolIEs.list.array, ricSubscriptionReq->protocolIEs.list.size);
640          }
641          RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
642       }
643       RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
644    }
645 }
646
647 /*******************************************************************
648  *
649  * @brief Builds Ric Request Id
650  *
651  * @details
652  *
653  *    Function : BuildNewRicRequestId
654  *
655  *    Functionality: Assign new Ric Request ID
656  *
657  * @params[in] RIC request ID to be sent
658  *             RIC request ID stored in DB
659  * @return ROK     - success
660  *         RFAILED - failure
661  *
662  * ****************************************************************/
663
664 uint8_t BuildNewRicRequestId(RICrequestID_t *ricReqId, RicRequestId *reqIdDb)
665 {
666    static uint16_t requestorId = 0;
667    static uint16_t instanceId = 0;
668
669    if(ricReqId != NULLP)
670    {
671       ricReqId->ricRequestorID = ++requestorId;
672       ricReqId->ricInstanceID  = ++instanceId;
673
674       reqIdDb->requestorId = ricReqId->ricRequestorID;
675       reqIdDb->instanceId = ricReqId->ricInstanceID;
676    }
677    return ROK;
678 }
679
680 /*******************************************************************
681  *
682  * @brief Free RIC Action Definition
683  *
684  * @details
685  *
686  *    Function : FreeRicActionDefinition
687  *
688  *    Functionality: Free RIC Action Definition
689  *
690  * @params[in] E2SM-KPM Action definition
691  * @return void
692  *
693  * ****************************************************************/
694 void  FreeRicActionDefinition(E2SM_KPM_ActionDefinition_t actionDef)
695 {
696    uint8_t  elementIdx = 0;
697    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
698    MeasurementInfoItem_t *measItem = NULLP;
699
700    switch(actionDef.actionDefinition_formats.present)
701    {
702       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
703          {
704             if(actionDef.actionDefinition_formats.choice.actionDefinition_Format1)
705             {
706                actionFormat1 = actionDef.actionDefinition_formats.choice.actionDefinition_Format1;
707                if(actionFormat1->measInfoList.list.array)
708                {
709                   for(elementIdx = 0; elementIdx < actionFormat1->measInfoList.list.count; elementIdx++)
710                   {
711                      if(actionFormat1->measInfoList.list.array[elementIdx])
712                      {
713                         measItem = actionFormat1->measInfoList.list.array[elementIdx];
714                         switch(measItem->measType.present)
715                         {
716                            case MeasurementType_PR_NOTHING:
717                            case MeasurementType_PR_measID:
718                               break;
719                            case MeasurementType_PR_measName:
720                            {
721                               RIC_FREE(measItem->measType.choice.measName.buf, measItem->measType.choice.measName.size)
722                               break;
723                            }
724                         }
725                         RIC_FREE(measItem, sizeof(MeasurementInfoItem_t));
726                      }
727                   }
728                   RIC_FREE(actionFormat1->measInfoList.list.array, actionFormat1->measInfoList.list.size);
729                }
730                RIC_FREE(actionFormat1, sizeof(E2SM_KPM_ActionDefinition_Format1_t));
731             }
732             break;
733          }
734
735       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format2:
736       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format3:
737       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format4:
738       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format5:
739       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_NOTHING:
740          break;
741    }
742 }
743
744 /*******************************************************************
745  *
746  * @brief Fill RIC Action Definition
747  *
748  * @details
749  *
750  *    Function : fillRicActionDef
751  *
752  *    Functionality: Fill RIC Action Definition
753  *
754  * @params[in] RIC Action definition
755  * @return ROK 
756  *         RFAILED
757  *
758  * ****************************************************************/
759 uint8_t fillRicActionDef(RICactionDefinition_t *ricActionDef)
760 {
761    uint8_t ret = RFAILED;
762    asn_enc_rval_t  encRetVal;
763    uint8_t elementCnt = 0, elementIdx = 0;
764    char    *measurementTypeName[] = {"RRU.PrbTotDl", "RRU.PrbTotUl"};
765    E2SM_KPM_ActionDefinition_t actionDef;
766    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
767    MeasurementInfoItem_t *measItem = NULLP;
768    
769    while(true)
770    {
771       /* Fill E2SM-KPM Action Definition Format 1 */
772
773       /* RIC Stype Type */
774       actionDef.ric_Style_Type = RIC_STYLE_TYPE;
775
776       /* RIC Action Definition Format 1 */
777       actionDef.actionDefinition_formats.present = \
778            E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1;
779
780       RIC_ALLOC(actionDef.actionDefinition_formats.choice.actionDefinition_Format1, \
781             sizeof(E2SM_KPM_ActionDefinition_Format1_t));
782       if(actionDef.actionDefinition_formats.choice.actionDefinition_Format1 == NULLP)
783       {
784          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
785          break;
786       }
787       actionFormat1 = actionDef.actionDefinition_formats.choice.actionDefinition_Format1;
788
789       /* Measurement Info List */
790       elementCnt = 2;
791       actionFormat1->measInfoList.list.count = elementCnt;
792       actionFormat1->measInfoList.list.size = elementCnt * sizeof(MeasurementInfoItem_t *);
793       RIC_ALLOC(actionFormat1->measInfoList.list.array, actionFormat1->measInfoList.list.size);
794       if(actionFormat1->measInfoList.list.array == NULL)
795       {
796          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
797          break;
798       }
799
800       for(elementIdx = 0; elementIdx < elementCnt; elementIdx++)
801       {
802          RIC_ALLOC(actionFormat1->measInfoList.list.array[elementIdx], sizeof(MeasurementInfoItem_t));
803          if(actionFormat1->measInfoList.list.array[elementIdx] == NULLP)
804          {
805             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
806             break;
807          }
808
809          measItem = actionFormat1->measInfoList.list.array[elementIdx];
810          measItem->measType.present = MeasurementType_PR_measName;
811
812          measItem->measType.choice.measName.size = strlen(measurementTypeName[elementIdx]);
813          RIC_ALLOC(measItem->measType.choice.measName.buf, measItem->measType.choice.measName.size);
814          if(measItem->measType.choice.measName.buf == NULLP)
815          {
816             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
817             break;
818          }
819          memcpy(measItem->measType.choice.measName.buf, measurementTypeName[elementIdx], measItem->measType.choice.measName.size);
820       }
821       if(elementIdx < elementCnt)
822          break;
823
824       /* Granularity Period */
825       actionFormat1->granulPeriod = RIC_ACTION_GRANULARITY_PERIOD; /* In ms */
826
827       /* Prints the Msg formed */
828       xer_fprint(stdout, &asn_DEF_E2SM_KPM_ActionDefinition, &actionDef);
829
830       /* Encode E2SM-KPM RIC Action Definition */
831       memset(encBuf, 0, ENC_BUF_MAX_LEN);
832       encBufSize = 0;
833       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_ActionDefinition, 0, &actionDef, PrepFinalEncBuf, encBuf);
834       if(encRetVal.encoded == ENCODE_FAIL)
835       {
836          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM action definition structure (at %s)\n",\
837                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
838          break;
839       }
840
841       /* Copty encoded E2SM-KPM RIC action definition to E2AP octet string buffer */
842       ricActionDef->size = encBufSize;
843       RIC_ALLOC(ricActionDef->buf, encBufSize);
844       if(ricActionDef->buf == NULLP)
845       {
846          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
847          break;
848       }
849       memcpy(ricActionDef->buf, encBuf, encBufSize);
850
851       ret = ROK;
852       break;
853    }
854
855    FreeRicActionDefinition(actionDef);
856    return ret;
857 }
858
859 /*******************************************************************
860  *
861  * @brief Fills RIC Action To Be Setup Item
862  *
863  * @details
864  *
865  *    Function : fillActionToBeSetup
866  *
867  *    Functionality: Fill the RIC Action To Be Setup Ite,
868  *                   RIC subscription DB
869  *
870  * @params[in] RICaction_ToBeSetup_ItemIEs_t *items
871  * @return ROK     - success
872  *         RFAILED - failure
873  *
874  * ****************************************************************/
875 uint8_t fillActionToBeSetup(RICaction_ToBeSetup_ItemIEs_t *actionItem, RicSubscription *ricSubsDb)
876 {
877    static uint8_t ricActionId = 0;
878
879    if(actionItem == NULLP)
880    {
881       DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
882       return RFAILED;
883    }
884
885    while(true)
886    {
887       actionItem->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item;
888       actionItem->criticality   =  CriticalityE2_ignore;
889       actionItem->value.present =  RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
890       
891       /* RIC Action ID */
892       actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID = ++ricActionId;
893       ricSubsDb->actionSequence[ricSubsDb->numOfActions].id = \
894          actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
895
896       /* RIC Action Type */
897       actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType = RICactionType_report;
898
899       /* RIC Action Definition */
900       RIC_ALLOC(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, sizeof(RICactionDefinition_t));
901       if(!actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
902       {
903          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
904          break;
905       }
906       if(fillRicActionDef(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition) != ROK)
907       {
908          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
909          break;
910       }
911       
912       ricSubsDb->numOfActions++;
913       return ROK;
914    }
915
916    memset(&ricSubsDb->actionSequence[ricSubsDb->numOfActions], 0, sizeof(ActionInfo));
917    return RFAILED;
918 }
919
920 /*******************************************************************
921  *
922  * @brief Free Event Trigger Definition
923  *
924  * @details
925  *
926  *    Function : FreeEventTriggerDef
927  *
928  *    Functionality: Free Event Trigger Definition
929  *
930  * @params[in] E2SM-KPM Event Trigger Definition
931  * @return void
932  *
933  * ****************************************************************/
934 void  FreeEventTriggerDef(E2SM_KPM_EventTriggerDefinition_t *eventTiggerDef)
935 {
936    if(eventTiggerDef)
937    {
938       switch(eventTiggerDef->eventDefinition_formats.present)
939       {
940          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING:
941             break;
942          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1: 
943             RIC_FREE(eventTiggerDef->eventDefinition_formats.choice.eventDefinition_Format1, \
944                   sizeof(E2SM_KPM_EventTriggerDefinition_Format1_t));
945             break;                  
946       }         
947    }
948 }
949
950 /*******************************************************************
951  *
952  * @brief Fill Event Trigger Definition
953  *
954  * @details
955  *
956  *    Function : fillEventTriggerDef
957  *
958  *    Functionality: Fill Event Trigger Definition
959  *
960  * @params[in] RIC Event Trigger Definition
961  * @return ROK
962  *         RFAILED
963  *
964  * ****************************************************************/
965 uint8_t fillEventTriggerDef(RICeventTriggerDefinition_t *ricEventTriggerDef)
966 {
967    uint8_t ret = RFAILED;
968    asn_enc_rval_t  encRetVal;
969    E2SM_KPM_EventTriggerDefinition_t eventTiggerDef;
970
971    while(true)
972    {
973       /* Fill E2SM-KPM Event Trigger Definition Format 1 */
974       eventTiggerDef.eventDefinition_formats.present = \
975        E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1;
976
977       RIC_ALLOC(eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1, \
978             sizeof(E2SM_KPM_EventTriggerDefinition_Format1_t));
979       if(eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1 == NULLP)
980       {
981          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
982          break;
983       }
984
985       eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1->reportingPeriod = 1000; /* In ms */
986
987       /* Prints the Msg formed */
988       xer_fprint(stdout, &asn_DEF_E2SM_KPM_EventTriggerDefinition, &eventTiggerDef);
989
990       /* Encode E2SM-KPM Event Trigger Definition */
991       memset(encBuf, 0, ENC_BUF_MAX_LEN);
992       encBufSize = 0;
993       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_EventTriggerDefinition, 0, &eventTiggerDef, PrepFinalEncBuf, encBuf);
994       if(encRetVal.encoded == ENCODE_FAIL)
995       {
996          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM event trigger definition structure (at %s)\n",\
997                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
998          break;
999       }
1000
1001       /* Copy encoded E2SM-KPM event trigger definition to E2AP octet string buffer */
1002       ricEventTriggerDef->size = encBufSize;
1003       RIC_ALLOC(ricEventTriggerDef->buf, encBufSize);
1004       if(ricEventTriggerDef->buf == NULLP)
1005       {
1006          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1007          break;
1008       }
1009       memcpy(ricEventTriggerDef->buf, encBuf, encBufSize);
1010
1011       ret = ROK;
1012       break;
1013    }
1014
1015    FreeEventTriggerDef(&eventTiggerDef);
1016    return ret;
1017 }
1018
1019 /*******************************************************************
1020  *
1021  * @brief builds RIC Subscription Details
1022  *
1023  * @details
1024  *
1025  *    Function : BuildsRicSubsDetails
1026  *
1027  *    Functionality: Builds the RIC Subscription Details
1028  *
1029  * @params[in] RIC Subscription details to be filled
1030  *             RIC subscriotion DB
1031  * @return ROK     - success
1032  *         RFAILED - failure
1033  *
1034  * ****************************************************************/
1035
1036 uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails, RicSubscription *ricSubsDb)
1037 {
1038    uint8_t elementCnt = 0;
1039    uint8_t elementIdx = 0;
1040
1041    if(subsDetails == NULLP)
1042    {
1043       DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1044       return RFAILED;
1045    }
1046
1047    while(true)
1048    {
1049       /* RIC Event Trigger Definition */
1050       if(fillEventTriggerDef(&subsDetails->ricEventTriggerDefinition) != ROK)
1051       {
1052          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1053          break;
1054       }
1055
1056       /* RIC Actions To Be Setup List */
1057       elementCnt = 1;
1058       subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt;
1059       subsDetails->ricAction_ToBeSetup_List.list.size = elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t *);
1060       RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, subsDetails->ricAction_ToBeSetup_List.list.size);
1061       if(subsDetails->ricAction_ToBeSetup_List.list.array  == NULLP)
1062       {
1063          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICactionToBeSetup Items failed");
1064          break;
1065       } 
1066
1067       for(elementIdx = 0; elementIdx < elementCnt; elementIdx++)
1068       {
1069          RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], sizeof(RICaction_ToBeSetup_ItemIEs_t));
1070          if(!subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
1071          {
1072             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1073             break;
1074          }
1075       }
1076       if(elementIdx < elementCnt)
1077          break;
1078
1079       elementIdx = 0;
1080       if(fillActionToBeSetup((RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], \
1081          ricSubsDb) != ROK)
1082       {
1083          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1084          break;
1085       }
1086
1087       return ROK;
1088    }
1089    return RFAILED;
1090 }
1091
1092 /*******************************************************************
1093  *
1094  * @brief Builds and Send the RicSubscriptionReq
1095  *
1096  * @details
1097  *
1098  *    Function : BuildAndSendRicSubscriptionReq
1099  *
1100  * Functionality:Fills the RicSubscriptionReq
1101  *
1102  * @return ROK     - success
1103  *         RFAILED - failure
1104  *
1105  ******************************************************************/
1106 uint8_t BuildAndSendRicSubscriptionReq(DuDb *duDb)
1107 {
1108    uint8_t         ret = RFAILED;
1109    E2AP_PDU_t                 *e2apRicMsg = NULL;
1110    RICsubscriptionRequest_t   *ricSubscriptionReq;
1111    uint8_t         elementCnt;
1112    uint8_t         idx;
1113    uint8_t         ieId;
1114    asn_enc_rval_t  encRetVal;        /* Encoder return value */
1115    RanFunction     *ranFuncDb = &duDb->ranFunction[0];
1116
1117    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Request\n");
1118
1119    while(true)
1120    {
1121       RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
1122       if(e2apRicMsg == NULLP)
1123       {
1124          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1125          break;
1126       }
1127
1128       e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
1129       RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1130       if(e2apRicMsg->choice.initiatingMessage == NULLP)
1131       {
1132          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1133          break;
1134       }
1135       e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
1136       e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
1137       e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
1138
1139       ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
1140
1141       elementCnt = 3;
1142       ricSubscriptionReq->protocolIEs.list.count = elementCnt;
1143       ricSubscriptionReq->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
1144
1145       /* Initialize the subscription members */
1146       RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, ricSubscriptionReq->protocolIEs.list.size);
1147       if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
1148       {
1149          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1150          break;
1151       }
1152
1153       for(idx=0; idx<elementCnt; idx++)
1154       {
1155          RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionRequest_IEs_t));
1156          if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
1157          {
1158             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1159             break;
1160          }
1161       }
1162       if(idx < elementCnt)
1163          break;
1164
1165       /* Filling RIC Request Id */
1166       idx = 0;
1167       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
1168       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1169       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
1170                                                                       RICsubscriptionRequest_IEs__value_PR_RICrequestID;
1171       if(BuildNewRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID, \
1172          &ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription].requestId) != ROK)
1173       {
1174          DU_LOG("\nERROR  -->  E2AP : Failed at [%d] : Line [%d]", __func__, __LINE__);
1175          break;
1176       }
1177
1178
1179       /* Filling RAN Function Id */
1180       idx++;
1181       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
1182       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1183       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
1184                                                                       RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
1185       ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ranFuncDb->id;
1186
1187       /* Filling RIC Subscription Details */
1188       idx++;
1189       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
1190       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1191       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
1192                                                                       RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
1193       if(BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails),\
1194          &ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription]) != ROK)
1195       {
1196          DU_LOG("\nERROR  -->  E2AP : Failed at [%d] : Line [%d]", __func__, __LINE__);
1197          break;
1198       }
1199
1200       /* Prints the Msg formed */
1201       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
1202
1203       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1204       encBufSize = 0;
1205       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf, encBuf);
1206       if(encRetVal.encoded == ENCODE_FAIL)
1207       {
1208          DU_LOG("\nERROR  -->  E2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
1209                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1210          break;               
1211       }
1212       else
1213       {
1214          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
1215          for(int i=0; i< encBufSize; i++)
1216          {
1217             DU_LOG("%x",encBuf[i]);
1218          } 
1219       }
1220
1221       /* Sending msg */
1222       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
1223       {
1224          DU_LOG("\nERROR  -->  E2AP : Sending RIC subscription Request failed");
1225          break;
1226       }
1227
1228       ranFuncDb->numOfSubscription++;
1229       ret = ROK;
1230       break;
1231    }
1232
1233    if(ret == RFAILED)
1234       memset(&ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription], 0, sizeof(RicSubscription));
1235    FreeRicSubscriptionReq(e2apRicMsg);
1236    return ret;
1237 }
1238
1239 /*******************************************************************
1240  *
1241  * @brief Process RicSubscriptionResponse
1242  *
1243  * @details
1244  *
1245  *    Function : ProcRicSubscriptionRsp
1246  *
1247  * Functionality: Processes RicSubscriptionRsp
1248  *
1249  * @return ROK     - void
1250  *
1251  ******************************************************************/
1252
1253 void ProcRicSubscriptionResponse(uint32_t duId)
1254 {
1255    uint8_t duIdx = 0;
1256    DuDb *duDb;
1257
1258    DU_LOG("\nINFO  -->  E2AP : RICsubscriptionResponse Msg Acknowledged");
1259
1260    SEARCH_DU_DB(duIdx, duId, duDb);
1261    if(duDb)
1262       duDb->ricSubscribedToDu = true;
1263 }
1264
1265 /*******************************************************************
1266  *
1267  * @brief deallocate the memory allocated in E2SetupFailure
1268  *
1269  * @details
1270  *
1271  *    Function : FreeE2SetupFailure 
1272  *
1273  *    Functionality: deallocate the memory allocated in E2SetupFailure 
1274  *
1275  * @params[in] E2AP_PDU_t *e2apMsg
1276  *
1277  * @return void
1278  * ****************************************************************/
1279 void FreeE2SetupFailure(E2AP_PDU_t *e2apMsg)
1280 {
1281    uint8_t arrIdx = 0;
1282    E2setupFailure_t  *e2SetupFail;
1283
1284    if(e2apMsg)
1285    {
1286       if(e2apMsg->choice.unsuccessfulOutcome)
1287       {
1288          e2SetupFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
1289          if(e2SetupFail->protocolIEs.list.array)
1290          {
1291             for(arrIdx=0; arrIdx<e2SetupFail->protocolIEs.list.count; arrIdx++)
1292             {
1293                RIC_FREE(e2SetupFail->protocolIEs.list.array[arrIdx], sizeof(E2setupFailureIEs_t)); 
1294             }
1295             RIC_FREE(e2SetupFail->protocolIEs.list.array, e2SetupFail->protocolIEs.list.size);
1296          }
1297          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
1298       }
1299       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1300    }
1301 }
1302
1303 /*******************************************************************
1304  *
1305  * @brief Buld and send the E2 Setup failure
1306  *
1307  * @details
1308  *
1309  *    Function : BuildAndSendE2SetupFailure
1310  *
1311  *    Functionality:
1312  *         - Buld and send the E2 Setup failure
1313  * @return ROK     - success
1314  *         RFAILED - failure
1315  *
1316  * ****************************************************************/
1317
1318 uint8_t BuildAndSendE2SetupFailure(uint32_t duId, uint8_t transId)
1319 {
1320    E2AP_PDU_t         *e2apMsg = NULL;
1321    E2setupFailure_t   *e2SetupFailure;
1322    asn_enc_rval_t     encRetVal;
1323    uint8_t            arrIdx;
1324    uint8_t            elementCnt;
1325    bool  memAllocFailed = false;
1326
1327    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup failure\n");
1328    while(true)
1329    {
1330       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1331       if(e2apMsg == NULLP)
1332       {
1333          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1334          break;
1335       }
1336       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
1337       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
1338       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
1339       {
1340          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1341          break;
1342       }
1343
1344       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
1345       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
1346       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2setupFailure;
1347       e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
1348
1349       elementCnt = 3;
1350       e2SetupFailure->protocolIEs.list.count = elementCnt;
1351       e2SetupFailure->protocolIEs.list.size  = elementCnt * sizeof(struct E2setupFailureIEs *);
1352
1353       RIC_ALLOC(e2SetupFailure->protocolIEs.list.array, e2SetupFailure->protocolIEs.list.size);
1354       if(e2SetupFailure->protocolIEs.list.array == NULLP)
1355       {
1356          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
1357          break;
1358       }
1359
1360       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
1361       {
1362          RIC_ALLOC(e2SetupFailure->protocolIEs.list.array[arrIdx], sizeof(struct E2setupFailureIEs));
1363          if(e2SetupFailure->protocolIEs.list.array[arrIdx] == NULLP)
1364          {
1365             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
1366             memAllocFailed = true;
1367             break;
1368          }
1369       }
1370
1371       if(memAllocFailed == true)
1372       {
1373           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
1374           break;
1375       }
1376
1377       /* Trans Id */
1378       arrIdx = 0;
1379       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
1380       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1381       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TransactionID;
1382       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
1383
1384       arrIdx++;
1385       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
1386       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1387       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_CauseE2;
1388       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.present = CauseE2_PR_protocol;
1389       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.protocol = CauseE2Protocol_unspecified;
1390
1391       arrIdx++;
1392       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
1393       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
1394       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TimeToWaitE2;
1395       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
1396
1397       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1398       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1399       encBufSize = 0;
1400       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
1401
1402       /* Check encode results */
1403       if(encRetVal.encoded == ENCODE_FAIL)
1404       {
1405          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Setup failure structure (at %s)\n",\
1406                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1407          break;
1408       }
1409       else
1410       {
1411          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Setup Failure\n");
1412          for(int i=0; i< encBufSize; i++)
1413          {
1414             DU_LOG("%x",encBuf[i]);
1415          }
1416       }
1417
1418       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
1419       {
1420          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Failure failed");
1421          break;
1422       }
1423       break;
1424    }
1425
1426    FreeE2SetupFailure(e2apMsg);
1427 }
1428
1429 /*******************************************************************
1430  *
1431  * @brief process the e2setup request 
1432  *
1433  * @details
1434  *
1435  *    Function : ProcE2SetupReq
1436  *
1437  * Functionality: process the e2setup request
1438  *
1439  * @return ROK     - success
1440  *         RFAILED - failure
1441  *
1442  ******************************************************************/
1443
1444 uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
1445 {
1446    uint8_t arrIdx = 0, e2NodeAddListIdx =0, duIdx = 0, transId =0, ranFuncIdx;
1447    DuDb    *duDb = NULLP;
1448    E2nodeComponentConfigAddition_List_t *e2NodeAddList;
1449    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
1450    RANfunction_ItemIEs_t *ranFuncItemIe;
1451    RANfunction_Item_t  *ranFunItem;
1452    RANfunctions_List_t *ranFunctionsList;
1453
1454    if(e2SetupReq)
1455    {
1456       if(e2SetupReq->protocolIEs.list.array)      
1457       {
1458          for(arrIdx=0; arrIdx<e2SetupReq->protocolIEs.list.count; arrIdx++)
1459          {
1460             if(e2SetupReq->protocolIEs.list.array[arrIdx])
1461             {
1462                switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
1463                {
1464                   case ProtocolIE_IDE2_id_TransactionID:
1465                      {
1466                         transId = e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; 
1467                         break;
1468                      }
1469                   case ProtocolIE_IDE2_id_GlobalE2node_ID:
1470                      {
1471                         if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID)
1472                         {
1473                             *duId =e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID->buf[0];
1474
1475                             SEARCH_DU_DB(duIdx, *duId, duDb); 
1476                             if(duDb == NULLP)
1477                             {
1478                                duDb = &ricCb.duInfo[ricCb.numDu];
1479                                ricCb.numDu++;
1480                             }
1481                             memset(duDb, 0, sizeof(DuDb));
1482                             duDb->duId = *duId;
1483                         }
1484                         break;
1485                      }
1486                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
1487                      {
1488                         ranFunctionsList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
1489
1490                         if(ranFunctionsList->list.array)
1491                         {
1492                            for(ranFuncIdx=0;ranFuncIdx<ranFunctionsList->list.count; ranFuncIdx++)
1493                            {
1494                               ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncIdx]; 
1495                               ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
1496                               duDb->ranFunction[duDb->numOfRanFunction].id = ranFunItem->ranFunctionID; 
1497                               duDb->ranFunction[duDb->numOfRanFunction].revisionCounter = ranFunItem->ranFunctionRevision; 
1498                               duDb->numOfRanFunction++;
1499                            }
1500                         }
1501                         break;
1502                      }
1503                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
1504                      {
1505                         e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;      
1506                         if(e2NodeAddList->list.array)
1507                         {
1508                            for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
1509                            {
1510                               if(e2NodeAddList->list.array[e2NodeAddListIdx])
1511                               {
1512                                  e2NodeAddItem = \
1513                                     (E2nodeComponentConfigAddition_ItemIEs_t *)e2NodeAddList->list.array[e2NodeAddListIdx];
1514                                  if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.\
1515                                     choice.e2nodeComponentInterfaceTypeF1)
1516                                  {
1517                                     duDb->e2NodeComponent.interfaceType = F1; 
1518                                     duDb->e2NodeComponent.componentId = \
1519                                        e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.\
1520                                        choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]; 
1521                                  }
1522                               }
1523                            }
1524                         }
1525                         break;
1526                      }
1527                      default:
1528                         break;
1529                   }
1530                }
1531             }
1532         }
1533    }
1534    
1535    if(BuildAndSendE2SetupRsp(duDb, transId) !=ROK)
1536    {
1537       DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 setup response");
1538       return RFAILED;
1539    }
1540    return ROK;   
1541 }
1542
1543 /*******************************************************************
1544  *
1545  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
1546  *
1547  * @details
1548  *
1549  *    Function : FreeE2NodeConfigUpdate 
1550  *
1551  *    Functionality:
1552  *       - freeing the memory allocated for E2nodeConfigurationUpdate
1553  *
1554  * @params[in] E2AP_PDU_t *e2apMsg 
1555  * @return ROK     - success
1556  *         RFAILED - failure
1557  *
1558  * ****************************************************************/
1559 void FreeE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg)
1560 {
1561    uint8_t arrIdx =0;
1562    E2nodeConfigurationUpdate_t *e2NodeConfigUpdateAck;
1563
1564    if(e2apMsg != NULLP)
1565    {
1566       if(e2apMsg->choice.successfulOutcome != NULLP)
1567       {
1568          e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
1569          if(e2NodeConfigUpdateAck->protocolIEs.list.array != NULLP)
1570          {
1571             for(arrIdx = 0; arrIdx < e2NodeConfigUpdateAck->protocolIEs.list.count; arrIdx++)
1572             {
1573                RIC_FREE(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_t));
1574             }
1575             RIC_FREE(e2NodeConfigUpdateAck->protocolIEs.list.array, e2NodeConfigUpdateAck->protocolIEs.list.size);
1576          }
1577          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1578       }
1579       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1580    }
1581 }
1582
1583 /*******************************************************************
1584  *
1585  * @brief Buld and send the E2 node config update msg 
1586  *
1587  * @details
1588  *
1589  *    Function : BuildAndSendE2NodeConfigUpdate
1590  *
1591  *    Functionality:
1592  *         - Buld and send the E2 node config update msg
1593  * @return ROK     - success
1594  *         RFAILED - failure
1595  *
1596  * ****************************************************************/
1597
1598 uint8_t BuildAndSendE2NodeConfigUpdateAck(uint32_t duId)
1599 {
1600    uint8_t arrIdx = 0,elementCnt = 1;
1601    uint8_t ret = ROK;
1602    E2AP_PDU_t        *e2apMsg = NULLP;
1603    E2nodeConfigurationUpdateAcknowledge_t *e2NodeConfigUpdateAck = NULLP;
1604    asn_enc_rval_t     encRetVal;       /* Encoder return value */
1605
1606    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update Ack Message\n");
1607    do
1608    {
1609       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1610       if(e2apMsg == NULLP)
1611       {
1612          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1613          break;
1614       }
1615       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
1616       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1617       if(e2apMsg->choice.successfulOutcome == NULLP)
1618       {
1619          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1620          RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1621          return RFAILED;
1622       }
1623       
1624       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
1625       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
1626       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge;
1627       e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
1628
1629       e2NodeConfigUpdateAck->protocolIEs.list.count = elementCnt;
1630       e2NodeConfigUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t*);
1631       /* Initialize the Ric Indication members */
1632       RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array, \
1633             e2NodeConfigUpdateAck->protocolIEs.list.size);
1634       if(e2NodeConfigUpdateAck->protocolIEs.list.array == NULLP)
1635       {
1636          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdateAck failed");
1637          break;
1638       }
1639       
1640       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
1641       {
1642          RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t));
1643          if(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
1644          {
1645             
1646             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdateAck failed");
1647             break;
1648          }
1649       }
1650
1651       arrIdx = 0;
1652       /* TransactionID */
1653       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
1654       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1655       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_TransactionID;
1656       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = TRANS_ID;
1657
1658
1659       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1660
1661       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1662       encBufSize = 0;
1663       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
1664             encBuf);
1665       if(encRetVal.encoded == ENCODE_FAIL)
1666       {
1667          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Node config update ack structure (at %s)\n",\
1668                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1669          return RFAILED;
1670       }
1671       else
1672       {
1673          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Node config update ack \n");
1674          for(int i=0; i< encBufSize; i++)
1675          {
1676             DU_LOG("%x",encBuf[i]);
1677          } 
1678       }
1679
1680
1681       /* Sending msg */
1682       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
1683       {
1684          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Node config update ack ");
1685          return RFAILED;
1686       }
1687
1688       break;
1689    }while(true);
1690    
1691    FreeE2NodeConfigUpdateAck(e2apMsg);
1692    return ret;
1693 }
1694
1695 /*******************************************************************
1696  *
1697  * @brief Deallocate the memory allocated for E2 Reset Response
1698  *
1699  * @details
1700  *
1701  *    Function : FreeE2ResetResponse
1702  *
1703  *    Functionality:
1704  *       - freeing the memory allocated for E2ResetResponse
1705  *
1706  * @params[in] E2AP_PDU_t *e2apMsg
1707  * @return ROK     - success
1708  *         RFAILED - failure
1709  *
1710  * ****************************************************************/
1711 void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg)
1712 {
1713    uint8_t ieIdx =0;
1714    ResetResponseE2_t *resetResponse;
1715
1716    if(e2apMsg != NULLP)
1717    {
1718       if(e2apMsg->choice.successfulOutcome != NULLP)
1719       {
1720          resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
1721          if(resetResponse->protocolIEs.list.array)
1722          {
1723             for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
1724             {
1725                if(resetResponse->protocolIEs.list.array[ieIdx])
1726                {
1727                   RIC_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
1728                }
1729             }
1730             RIC_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
1731          }
1732          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1733       }
1734       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1735    }
1736 }
1737
1738 /*******************************************************************
1739  *
1740  * @brief Buld and send the E2 Reset Response msg
1741  *
1742  * @details
1743  *
1744  *    Function : BuildAndSendE2ResetResponse
1745  *
1746  *    Functionality:
1747  *         - Buld and send the E2 Reset Response Message
1748  * @return ROK     - success
1749  *         RFAILED - failure
1750  *
1751  * ****************************************************************/
1752 uint8_t BuildAndSendResetResponse(uint32_t duId, uint8_t transId)
1753 {
1754    uint8_t           ieIdx = 0, elementCnt = 0;
1755    uint8_t           ret = RFAILED;
1756    E2AP_PDU_t        *e2apMsg = NULLP;
1757    ResetResponseE2_t *resetResponse;
1758    asn_enc_rval_t    encRetVal;       /* Encoder return value */
1759
1760    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
1761    do
1762    {
1763       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1764       if(e2apMsg == NULLP)
1765       {
1766          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
1767          break;
1768       }
1769       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
1770
1771       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1772       if(e2apMsg->choice.successfulOutcome == NULLP)
1773       {
1774          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
1775          RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1776          return RFAILED;
1777       }
1778  
1779       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
1780       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
1781       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
1782       resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
1783
1784       elementCnt = 1;
1785       resetResponse->protocolIEs.list.count = elementCnt;
1786       resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
1787       RIC_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
1788       if(!resetResponse->protocolIEs.list.array)
1789       {
1790          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
1791          break;
1792       }
1793
1794       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
1795       {
1796          RIC_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
1797          if(!resetResponse->protocolIEs.list.array[ieIdx])
1798          {
1799             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
1800             break;
1801          }
1802       }
1803       if(ieIdx < elementCnt)
1804          break;
1805
1806       ieIdx = 0; 
1807       resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
1808       resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
1809       resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
1810       resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
1811
1812       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1813
1814       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1815       encBufSize = 0;
1816       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
1817       if(encRetVal.encoded == ENCODE_FAIL)
1818       {
1819          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
1820                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1821          return RFAILED;
1822       }
1823       else
1824       {
1825          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
1826          for(int i=0; i< encBufSize; i++)
1827          {
1828             DU_LOG("%x",encBuf[i]);
1829          }
1830       }
1831
1832       /* Sending msg */
1833       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
1834       {
1835          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
1836          return RFAILED;
1837       }
1838
1839       ret = ROK;
1840       break;
1841    }while(true);
1842
1843    FreeE2ResetResponse(e2apMsg);
1844    return ROK;
1845 }
1846
1847 /*******************************************************************
1848  *
1849  * @brief process the E2 Reset Request
1850  *
1851  * @details
1852  *
1853  *    Function : ProcE2ResetReq
1854  *
1855  * Functionality: Process E2 Reset Request
1856  *
1857  * @return ROK     - success
1858  *         RFAILED - failure
1859  *
1860  ******************************************************************/
1861
1862 uint8_t ProcE2ResetReq(uint32_t duId, ResetRequestE2_t  *resetReq)
1863 {
1864    uint8_t ieIdx = 0, duIdx = 0;
1865    uint8_t transId = 0, cause = 0;
1866    DuDb    *duDb = NULLP;
1867
1868    if(resetReq)
1869    {
1870       if(resetReq->protocolIEs.list.array)
1871       {
1872          for(ieIdx=0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
1873          {
1874             if(resetReq->protocolIEs.list.array[ieIdx])
1875             {
1876                switch(resetReq->protocolIEs.list.array[ieIdx]->id)
1877                {
1878                   case ProtocolIE_IDE2_id_TransactionID:
1879                      transId = resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
1880                      break;
1881                   case ProtocolIE_IDE2_id_CauseE2:
1882                      DU_LOG("\nDEBUG  -->  E2AP : Reset reason %d", resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present);
1883                      switch(resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present)
1884                      {
1885                         case CauseE2_PR_NOTHING:
1886                            break;
1887                         case CauseE2_PR_ricRequest:
1888                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricRequest;
1889                            break;
1890                         case CauseE2_PR_ricService:
1891                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricService;
1892                            break;
1893                         case CauseE2_PR_e2Node:
1894                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.e2Node;
1895                            break;
1896                         case CauseE2_PR_transport:
1897                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.transport;
1898                            break;
1899                         case CauseE2_PR_protocol:
1900                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.protocol;
1901                            break;
1902                         case CauseE2_PR_misc:
1903                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.misc;
1904                            break;
1905                      }
1906                      DU_LOG("\nDEBUG  -->  E2AP : Reset cause %d", cause);
1907                      break;
1908                }
1909             }
1910          }
1911       }
1912    }
1913    BuildAndSendResetResponse(duId, transId);
1914    return ROK;
1915 }
1916
1917 /*******************************************************************
1918  *
1919  * @brief deallocate the memory allocated in building the
1920  *    Service Query message
1921  *
1922  * @details
1923  *
1924  *    Function : FreeRicServiceQuery 
1925  *
1926  *    Functionality: deallocate the memory allocated in building
1927  *    Ric Service Query message
1928  *
1929  * @params[in] E2AP_PDU_t *e2apMsg
1930  *
1931  * @return void
1932  * ****************************************************************/
1933
1934 void FreeRicServiceQuery(E2AP_PDU_t *e2apMsg)
1935 {
1936    uint8_t arrIdx = 0, ranFuncIdx=0;
1937    RANfunctionsID_List_t *ranFuncAcceptedList=NULL;
1938    RICserviceQuery_t *ricServiceQuery=NULL;
1939    
1940    if(e2apMsg)
1941    {
1942       if(e2apMsg->choice.initiatingMessage)
1943       {
1944          ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
1945          if(ricServiceQuery->protocolIEs.list.array)
1946          {
1947             for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
1948             {
1949                if(ricServiceQuery->protocolIEs.list.array[arrIdx])
1950                {
1951                   switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
1952                   {
1953                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
1954                         {
1955                            ranFuncAcceptedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
1956                            if(ranFuncAcceptedList->list.array)
1957                            {
1958                               for(ranFuncIdx=0;ranFuncIdx<ranFuncAcceptedList->list.count; ranFuncIdx++)
1959                               {
1960                                  RIC_FREE(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
1961                               }
1962                               RIC_FREE(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
1963                            }
1964                            break;
1965                         }
1966                      case RICserviceQuery_IEs__value_PR_TransactionID:
1967                         {
1968                            break;
1969                         }
1970                   }
1971                   RIC_FREE(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t)); 
1972                }
1973             }
1974             RIC_FREE(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
1975          }
1976          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1977       }
1978       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1979    }
1980 }
1981
1982 /*******************************************************************
1983  *
1984  * @brief build and send the ric service Query 
1985  *
1986  * @details
1987  *
1988  *    Function : BuildAndSendRicServiceQuery
1989  *
1990  * Functionality: build and send the ric service Query 
1991  * @return ROK     - success
1992  *         RFAILED - Acknowledge
1993  *
1994  ******************************************************************/
1995
1996 uint8_t BuildAndSendRicServiceQuery(DuDb *duDb)
1997 {
1998    uint8_t arrIdx;
1999    uint8_t elementCnt;
2000    uint8_t ret = RFAILED;
2001    bool  memAllocFailed = false;
2002    E2AP_PDU_t     *e2apMsg = NULL;
2003    asn_enc_rval_t encRetVal;
2004    RICserviceQuery_t *ricServiceQuery;
2005
2006    DU_LOG("\nINFO   -->  E2AP : Building Ric service Query\n");
2007    while(true)
2008    {
2009       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2010       if(e2apMsg == NULLP)
2011       {
2012          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2013          break;
2014       }
2015       e2apMsg->present =  E2AP_PDU_PR_initiatingMessage;
2016       RIC_ALLOC(e2apMsg->choice.initiatingMessage , sizeof(struct InitiatingMessageE2));
2017       if(e2apMsg->choice.initiatingMessage == NULLP)
2018       {
2019          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2020          break;
2021       }
2022
2023       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceQuery;
2024       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2025       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceQuery;
2026       ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
2027
2028       elementCnt = 1;
2029       /* Fill Accepted RAN function IE If Ran function information is stored in databse */
2030       if(duDb->numOfRanFunction)
2031          elementCnt++;
2032
2033       ricServiceQuery->protocolIEs.list.count = elementCnt;
2034       ricServiceQuery->protocolIEs.list.size  = elementCnt * sizeof(RICserviceQuery_IEs_t*);
2035
2036       RIC_ALLOC(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
2037       if(ricServiceQuery->protocolIEs.list.array == NULLP)
2038       {
2039          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2040          break;
2041       }
2042
2043       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2044       {
2045          RIC_ALLOC(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t));
2046          if(ricServiceQuery->protocolIEs.list.array[arrIdx] == NULLP)
2047          {
2048             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2049             memAllocFailed = true;
2050             break;
2051          }
2052       }
2053       if(memAllocFailed == true)
2054       {
2055          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2056          break;
2057       }
2058
2059       /* Trans Id */
2060       arrIdx = 0;
2061       ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2062       ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2063       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_TransactionID;
2064       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = assignTransactionId(duDb);
2065       
2066       if(duDb->numOfRanFunction)
2067       {
2068          /* Accepted RAN function Id */
2069          arrIdx++;
2070          ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
2071          ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2072          ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_RANfunctionsID_List;
2073          if(BuildRanFunctionAcceptedList(duDb, 0, NULL, &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceQuery)!=ROK)
2074          {
2075             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
2076             break;         
2077          }
2078       }
2079       
2080       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2081       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2082       encBufSize = 0;
2083       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2084
2085       /* Check encode results */
2086       if(encRetVal.encoded == ENCODE_FAIL)
2087       {
2088          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service Query structure (at %s)\n",\
2089                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2090          break;
2091       }
2092       else
2093       {
2094          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service Query\n");
2095          for(int i=0; i< encBufSize; i++)
2096          {
2097             DU_LOG("%x",encBuf[i]);
2098          }
2099       }
2100
2101       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
2102       {
2103          DU_LOG("\nERROR  -->  E2AP : Sending of RIC service  Query failed");
2104          break;
2105       }
2106
2107       ret =ROK;
2108       break;
2109    }
2110    FreeRicServiceQuery(e2apMsg);
2111    return ret;
2112 }
2113
2114 /*******************************************************************
2115  *
2116  * @brief deallocate the memory allocated in RicServiceUpdateFailure
2117  *
2118  * @details
2119  *
2120  *    Function : FreeRicServiceUpdateFailure 
2121  *
2122  *    Functionality: deallocate the memory allocated in RicServiceUpdatefailure
2123  *
2124  * @params[in] E2AP_PDU_t *e2apMsg
2125  *
2126  * @return void
2127  * ****************************************************************/
2128
2129 void FreeRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
2130 {
2131    uint8_t arrIdx = 0;
2132    RICserviceUpdateFailure_t *ricServiceUpdateFailure=NULL;
2133    
2134    if(e2apMsg)
2135    {
2136       if(e2apMsg->choice.unsuccessfulOutcome)
2137       {
2138          ricServiceUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
2139          if(ricServiceUpdateFailure->protocolIEs.list.array)
2140          {
2141             for(arrIdx=0; arrIdx<ricServiceUpdateFailure->protocolIEs.list.count; arrIdx++)
2142             {
2143                RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t)); 
2144             }
2145             RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array, ricServiceUpdateFailure->protocolIEs.list.size);
2146          }
2147          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
2148       }
2149       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2150    }
2151 }
2152
2153 /*******************************************************************
2154  *
2155  * @brief fill E2 failure cause 
2156  *
2157  * @details
2158  *
2159  *    Function : fillE2FailureCause
2160  *
2161  * Functionality: fill E2 failure cause
2162  * @return ROK     - success
2163  *         RFAILED - failure
2164  *
2165  ******************************************************************/
2166
2167 void fillE2FailureCause(CauseE2_t *cause, CauseE2_PR causePresent, uint8_t reason)
2168 {
2169    cause->present = causePresent;
2170
2171    switch(cause->present)
2172    {
2173       case CauseE2_PR_ricRequest:
2174          cause->choice.ricRequest = reason;
2175          break;
2176       case CauseE2_PR_ricService:
2177          cause->choice.ricService = reason;
2178          break;
2179       case CauseE2_PR_e2Node:
2180          cause->choice.e2Node = reason;
2181          break;
2182       case CauseE2_PR_transport:
2183          cause->choice.transport = reason;
2184          break;
2185       case CauseE2_PR_protocol:
2186          cause->choice.protocol = reason;
2187          break;
2188       case CauseE2_PR_misc:
2189          cause->choice.misc = reason;
2190          break;
2191       default:
2192          cause->choice.misc = CauseE2Misc_unspecified;
2193          break;
2194    }
2195 }
2196
2197 /*******************************************************************
2198  *
2199  * @brief build and send the ric service update failure 
2200  *
2201  * @details
2202  *
2203  *    Function : BuildAndSendRicServiceUpdateFailure
2204  *
2205  * Functionality: build and send the ric service update failure 
2206  * @return ROK     - success
2207  *         RFAILED - failure
2208  *
2209  ******************************************************************/
2210
2211 uint8_t BuildAndSendRicServiceUpdateFailure(uint32_t duId, int8_t transId, CauseE2_PR causePresent, uint8_t reason)
2212 {
2213
2214    E2AP_PDU_t         *e2apMsg = NULL;
2215    asn_enc_rval_t     encRetVal;
2216    uint8_t            ret = RFAILED;
2217    uint8_t            arrIdx=0;
2218    uint8_t            elementCnt=0;
2219    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
2220
2221    DU_LOG("\nINFO   -->  E2AP : Building Ric service update failure\n");
2222    while(true)
2223    {
2224       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2225       if(e2apMsg == NULLP)
2226       {
2227          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2228          break;
2229       }
2230       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
2231       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
2232       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
2233       {
2234          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2235          break;
2236       }
2237
2238       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
2239       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
2240       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure;
2241       ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
2242
2243       elementCnt = 3;
2244       ricServiceFailure->protocolIEs.list.count = elementCnt;
2245       ricServiceFailure->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateFailure_IEs_t *);
2246
2247       RIC_ALLOC(ricServiceFailure->protocolIEs.list.array, ricServiceFailure->protocolIEs.list.size);
2248       if(ricServiceFailure->protocolIEs.list.array == NULLP)
2249       {
2250          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2251          break;
2252       }
2253
2254       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2255       {
2256          RIC_ALLOC(ricServiceFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t));
2257          if(ricServiceFailure->protocolIEs.list.array[arrIdx] == NULLP)
2258          {
2259             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2260             break;
2261          }
2262       }
2263       if(arrIdx<elementCnt)
2264       {
2265          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2266          break;
2267       }
2268
2269       /* Trans Id */
2270       arrIdx = 0;
2271       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2272       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2273       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TransactionID;
2274       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
2275
2276       arrIdx++;
2277       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
2278       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2279       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_CauseE2;
2280       fillE2FailureCause(&ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, causePresent, reason);
2281
2282       arrIdx++;
2283       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
2284       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
2285       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TimeToWaitE2;
2286       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
2287
2288       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2289       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2290       encBufSize = 0;
2291       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2292
2293       /* Check encode results */
2294       if(encRetVal.encoded == ENCODE_FAIL)
2295       {
2296          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update failure structure (at %s)\n",\
2297                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2298          break;
2299       }
2300       else
2301       {
2302          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Failure\n");
2303          for(int i=0; i< encBufSize; i++)
2304          {
2305             DU_LOG("%x",encBuf[i]);
2306          }
2307       }
2308
2309       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
2310       {
2311          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update failed");
2312          break;
2313       }
2314       ret = ROK;
2315       break;
2316    }
2317
2318    FreeRicServiceUpdateFailure(e2apMsg);
2319    return ret;
2320 }
2321
2322
2323 /*******************************************************************
2324  *
2325  * @brief deallocate the memory allocated in RicServiceUpdateAck(
2326  *
2327  * @details
2328  *
2329  *    Function : FreeRicServiceUpdateAck 
2330  *
2331  *    Functionality: deallocate the memory allocated in RicServiceUpdateAck
2332  *
2333  * @params[in] E2AP_PDU_t *e2apMsg
2334  *
2335  * @return void
2336  * ****************************************************************/
2337
2338 void FreeRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
2339 {
2340    uint8_t arrIdx = 0, ranFuncIdx=0;
2341    RANfunctionsID_List_t *acceptedList=NULL;
2342    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
2343    RANfunctionsIDcause_List_t  *rejectedList=NULL;
2344
2345    if(e2apMsg)
2346    {
2347       if(e2apMsg->choice.successfulOutcome)
2348       {
2349          ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
2350          if(ricServiceUpdateAck->protocolIEs.list.array)
2351          {
2352             for(arrIdx=0; arrIdx<ricServiceUpdateAck->protocolIEs.list.count; arrIdx++)
2353             {
2354                if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx])
2355                {
2356                   switch(ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id)
2357                   {
2358                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
2359                         {
2360                            acceptedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
2361                            if(acceptedList->list.array)
2362                            {
2363                               for(ranFuncIdx=0;ranFuncIdx<acceptedList->list.count; ranFuncIdx++)
2364                               {
2365                                  RIC_FREE(acceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
2366                               }
2367                               RIC_FREE(acceptedList->list.array, acceptedList->list.size);
2368                            }
2369                            break;
2370                         }
2371
2372                      case ProtocolIE_IDE2_id_RANfunctionsRejected:
2373                         {
2374                            rejectedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
2375                            if(rejectedList->list.array)
2376                            {
2377                               for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
2378                               {
2379                                  RIC_FREE(rejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
2380                               }
2381                               RIC_FREE(rejectedList->list.array, rejectedList->list.size);
2382                            }
2383                            break;
2384                         }
2385                   }
2386                   RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t)); 
2387                }
2388             }
2389             RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
2390          }
2391          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2392       }
2393       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2394    }
2395 }
2396
2397 /*******************************************************************
2398  *
2399  * @brief Build RAN function rejected list
2400  *
2401  * @details
2402  *
2403  *    Function : BuildRanFunctionRejectedList
2404  *
2405  *    Functionality: Build RAN function rejected list 
2406  *
2407  * @params[in] 
2408  *    Count of ran functions to be rejected in the list 
2409  *    Received list of RAN functions
2410  *
2411  * @return ROK - success
2412  *         RFAILED - failure
2413  * ****************************************************************/
2414
2415 uint8_t BuildRanFunctionRejectedList(uint8_t count, RanFunction *ranFunRejectedList, RANfunctionsIDcause_List_t *ranFuncRejectedList)
2416 {
2417    uint8_t ranFuncIdx = 0;
2418    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
2419    
2420    ranFuncRejectedList->list.count = count;
2421    
2422    ranFuncRejectedList->list.size = ranFuncRejectedList->list.count*sizeof(RANfunctionIDcause_ItemIEs_t*);
2423    RIC_ALLOC(ranFuncRejectedList->list.array, ranFuncRejectedList->list.size);
2424    if(ranFuncRejectedList->list.array == NULLP)
2425    {
2426       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array");
2427       return RFAILED;
2428    }
2429    
2430    for(ranFuncIdx = 0; ranFuncIdx< ranFuncRejectedList->list.count; ranFuncIdx++)
2431    {
2432       RIC_ALLOC(ranFuncRejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
2433       if(ranFuncRejectedList->list.array[ranFuncIdx] == NULLP)
2434       {
2435          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array item");
2436          return RFAILED;
2437       }
2438       ranFuncRejectedItemIe = (RANfunctionIDcause_ItemIEs_t*)ranFuncRejectedList->list.array[ranFuncIdx];
2439       ranFuncRejectedItemIe->id = ProtocolIE_IDE2_id_RANfunctionIEcause_Item;
2440       ranFuncRejectedItemIe->criticality= CriticalityE2_ignore;
2441       ranFuncRejectedItemIe->value.present = RANfunctionIDcause_ItemIEs__value_PR_RANfunctionIDcause_Item;
2442       ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID = ranFunRejectedList[ranFuncIdx].id;
2443       fillE2FailureCause(&ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.cause, CauseE2_PR_ricService,\
2444             CauseE2RICservice_ran_function_not_supported);
2445    }
2446    
2447    return ROK;
2448 }
2449
2450 /*******************************************************************
2451  *
2452  * @brief build and send the ric service update Acknowledge 
2453  *
2454  * @details
2455  *
2456  *    Function : BuildAndSendRicServiceUpdateAcknowledge
2457  *
2458  * Functionality: build and send the ric service update Acknowledge 
2459  * @return ROK     - success
2460  *         RFAILED - Acknowledge
2461  *
2462  ******************************************************************/
2463
2464 uint8_t BuildAndSendRicServiceUpdateAcknowledge(DuDb *duDb, int8_t transId, RicTmpRanFunList ricRanFuncList)
2465 {
2466    E2AP_PDU_t         *e2apMsg = NULL;
2467    asn_enc_rval_t     encRetVal;
2468    uint8_t  arrIdx=0, elementCnt=0, ret=RFAILED;;
2469    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
2470
2471    DU_LOG("\nINFO   -->  E2AP : Building Ric service update Acknowledge\n");
2472    while(true)
2473    {
2474       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2475       if(e2apMsg == NULLP)
2476       {
2477          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2478          break;
2479       }
2480       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
2481       RIC_ALLOC(e2apMsg->choice.successfulOutcome , sizeof(struct SuccessfulOutcomeE2));
2482       if(e2apMsg->choice.successfulOutcome == NULLP)
2483       {
2484          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2485          break;
2486       }
2487
2488       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
2489       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
2490       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge;
2491       ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
2492
2493       elementCnt = 1;
2494       if(ricRanFuncList.numOfRanFunAccepted)
2495          elementCnt++;
2496       if(ricRanFuncList.numOfRanFuneRejected)
2497          elementCnt++;
2498       
2499
2500       ricServiceUpdateAck->protocolIEs.list.count = elementCnt;
2501       ricServiceUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateAcknowledge_IEs_t*);
2502
2503       RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
2504       if(ricServiceUpdateAck->protocolIEs.list.array == NULLP)
2505       {
2506          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2507          break;
2508       }
2509
2510       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2511       {
2512          RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t));
2513          if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
2514          {
2515             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2516             break;
2517          }
2518       }
2519       if(arrIdx<elementCnt)
2520       {
2521          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2522          break;
2523       }
2524
2525       /* Trans Id */
2526       arrIdx = 0;
2527       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2528       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2529       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_TransactionID;
2530       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
2531
2532       if(ricRanFuncList.numOfRanFunAccepted)
2533       {
2534          /* Accepted RAN function List */
2535          arrIdx++;
2536          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
2537          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2538          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsID_List;
2539          if(BuildRanFunctionAcceptedList(duDb, ricRanFuncList.numOfRanFunAccepted, ricRanFuncList.ranFunAcceptedList,\
2540          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceUpdate)!=ROK)       
2541          {
2542             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
2543             break;         
2544          }
2545       }
2546       
2547       if(ricRanFuncList.numOfRanFuneRejected)
2548       {
2549          /* RAN Functions Rejected List */
2550          arrIdx++;
2551          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsRejected;
2552          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2553          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsIDcause_List;
2554          if(BuildRanFunctionRejectedList(ricRanFuncList.numOfRanFuneRejected, ricRanFuncList.ranFunRejectedList, \
2555          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List)!=ROK)       
2556          {
2557             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function rejected list");
2558             break;         
2559          }
2560       }
2561       
2562       
2563       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2564       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2565       encBufSize = 0;
2566       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2567
2568       /* Check encode results */
2569       if(encRetVal.encoded == ENCODE_FAIL)
2570       {
2571          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update Acknowledge structure (at %s)\n",\
2572                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2573          break;
2574       }
2575       else
2576       {
2577          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Acknowledge\n");
2578          for(int i=0; i< encBufSize; i++)
2579          {
2580             DU_LOG("%x",encBuf[i]);
2581          }
2582       }
2583
2584       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
2585       {
2586          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update ack failed");
2587          break;
2588       }
2589       ret =ROK;
2590       break;
2591    }
2592    FreeRicServiceUpdateAck(e2apMsg);
2593    return ret; 
2594 }
2595
2596 /*******************************************************************
2597  *
2598  * @brief process the RIC service update 
2599  *
2600  * @details
2601  *
2602  *    Function : ProcRicserviceUpdate 
2603  *
2604  * Functionality: process the RIC service update 
2605  *
2606  * @return ROK     - success
2607  *         RFAILED - failure
2608  *
2609  ******************************************************************/
2610
2611 void ProcRicServiceUpdate(uint32_t duId, RICserviceUpdate_t *ricServiceUpdate)
2612 {
2613    RicTmpRanFunList ricRanFuncList;
2614    DuDb    *duDb = NULLP;
2615    int8_t transId =-1;
2616    uint8_t duIdx = 0, elementCnt =0, arrIdx = 0; 
2617    uint16_t ranFuncIdx = 0, failedRanFuncCount=0, recvdRanFuncCount=0;
2618    RANfunction_ItemIEs_t *ranFuncItemIe =NULL;
2619    RANfunction_Item_t  *ranFuncItem =NULL;
2620    RANfunctionID_Item_t  *ranFuncIdItem=NULL;
2621    RANfunctions_List_t *ranFuncList=NULL;
2622    RANfunctionsID_List_t *deleteList=NULL;
2623    RANfunctionID_ItemIEs_t *delRanFuncItem=NULL;
2624
2625    SEARCH_DU_DB(duIdx, duId, duDb); 
2626    if(duDb == NULLP)
2627    {
2628       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
2629       return;
2630    }
2631    memset(&ricRanFuncList, 0, sizeof(RicTmpRanFunList)); 
2632
2633    if(!ricServiceUpdate)
2634    {
2635       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate pointer is null"); 
2636       return;
2637    }
2638
2639    if(!ricServiceUpdate->protocolIEs.list.array)      
2640    {
2641       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array pointer is null");
2642       return;
2643    }
2644    elementCnt = ricServiceUpdate->protocolIEs.list.count;
2645    for(arrIdx=0; arrIdx<ricServiceUpdate->protocolIEs.list.count; arrIdx++)
2646    {
2647       if(!ricServiceUpdate->protocolIEs.list.array[arrIdx])
2648       {
2649          DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array idx %d pointer is null",arrIdx);
2650          return;
2651       }
2652
2653       switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
2654       {
2655          case ProtocolIE_IDE2_id_TransactionID:
2656             {
2657                transId = ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
2658
2659                if(transId < 0 || transId > 255)
2660                {
2661                   DU_LOG("\nERROR  -->  E2AP : Received invalid transId %d",transId);
2662                   return;
2663                }
2664                break;
2665             }
2666
2667          case ProtocolIE_IDE2_id_RANfunctionsAdded:
2668             {
2669                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
2670
2671                if(ranFuncList->list.array)
2672                {
2673                   for(ranFuncIdx=0;ranFuncIdx<ranFuncList->list.count; ranFuncIdx++)
2674                   {
2675                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx]; 
2676                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
2677
2678                      /* Adding the ran function in temporary list */
2679                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
2680                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
2681                      ricRanFuncList.numOfRanFunAccepted++;
2682
2683                      /* Adding the new ran function in DB*/
2684                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].id = ranFuncItem->ranFunctionID;
2685                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
2686                      duDb->numOfRanFunction++;
2687
2688                      /* Calculating total number of ran fuctions which are received for addition */
2689                      recvdRanFuncCount++;
2690                   }
2691                }
2692                break;
2693             }
2694
2695          case ProtocolIE_IDE2_id_RANfunctionsModified:
2696             {
2697
2698                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List; 
2699                if(ranFuncList->list.array)
2700                {
2701                   for(ranFuncIdx = 0; ranFuncIdx< ranFuncList->list.count; ranFuncIdx++)
2702                   {
2703                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx];
2704                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
2705                      if(duDb->ranFunction[ranFuncItem->ranFunctionID-1].id != ranFuncItem->ranFunctionID)
2706                      {
2707                         /* Calculating total number of ran fuctions which are not present */
2708                         failedRanFuncCount++;
2709
2710                         /* Adding the ran function in temporary list */
2711                         ricRanFuncList.ranFunRejectedList[ricRanFuncList.numOfRanFuneRejected].id =  ranFuncItem->ranFunctionID; 
2712                         ricRanFuncList.numOfRanFuneRejected++;
2713                      }
2714                      else
2715                      {
2716
2717                         /* Adding the ran function in temporary list */
2718                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
2719                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
2720                         ricRanFuncList.numOfRanFunAccepted++;
2721
2722                         /* Updating the new ran function in DB*/
2723                         duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
2724                      }
2725                      /* Calculating total number of ran fuctions which are received for modification */
2726                      recvdRanFuncCount++;
2727                   }
2728                }
2729                break;
2730             }
2731          case ProtocolIE_IDE2_id_RANfunctionsDeleted:
2732             {
2733
2734                deleteList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List; 
2735                if(deleteList->list.array)
2736                {
2737                   for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
2738                   {
2739                      delRanFuncItem  = (RANfunctionID_ItemIEs_t*) deleteList->list.array[ranFuncIdx];
2740                      ranFuncIdItem = &delRanFuncItem->value.choice.RANfunctionID_Item;
2741                      if(duDb->ranFunction[ranFuncIdItem->ranFunctionID-1].id == ranFuncIdItem->ranFunctionID)
2742                      {
2743                         memset(&duDb->ranFunction[ranFuncIdItem->ranFunctionID-1], 0, sizeof(RanFunction));
2744                         duDb->numOfRanFunction--; 
2745                      }
2746
2747                      /* Calculating total number of ran fuctions which are received for deletion */
2748                      recvdRanFuncCount++;
2749                   }
2750                }
2751                break;
2752             }
2753
2754          default:
2755             {
2756                DU_LOG("\nERROR  -->  E2AP : IE [%ld] is not supported",ricServiceUpdate->protocolIEs.list.array[arrIdx]->id);
2757                break;
2758             }
2759       }
2760    }
2761    
2762    /* Sending RIC Service Update Failed if all RAN Functions received fail or if any IE processing fails
2763     * Else sending RIC Service Update Acknowledge */  
2764    if((elementCnt > arrIdx) ||((recvdRanFuncCount > 0) && (recvdRanFuncCount == failedRanFuncCount)))
2765    {
2766       if(BuildAndSendRicServiceUpdateFailure(duDb->duId, transId, CauseE2_PR_misc, CauseE2Misc_unspecified) != ROK)
2767       {
2768          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update Failure");
2769          return;
2770       }
2771    }
2772    else
2773    {
2774       if(BuildAndSendRicServiceUpdateAcknowledge(duDb, transId, ricRanFuncList) != ROK)
2775       {
2776          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update acknowledge");
2777          return;
2778       }
2779    }
2780 }
2781
2782
2783 /*******************************************************************
2784 *
2785 * @brief Handles received E2AP message and sends back response  
2786 *
2787 * @details
2788 *
2789 *    Function : E2APMsgHdlr
2790 *
2791 *    Functionality:
2792 *         - Decodes received E2AP control message
2793 *         - Prepares response message, encodes and sends to SCTP
2794 *
2795 * @params[in] 
2796 * @return ROK     - success
2797 *         RFAILED - failure
2798 *
2799 * ****************************************************************/
2800 void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
2801 {
2802    int             i;
2803    char            *recvBuf;
2804    MsgLen          copyCnt;
2805    MsgLen          recvBufLen;
2806    E2AP_PDU_t      *e2apMsg;
2807    asn_dec_rval_t  rval; /* Decoder return value */
2808    E2AP_PDU_t      e2apasnmsg ;
2809  
2810    DU_LOG("\nINFO  -->  E2AP : Received E2AP message buffer");
2811    ODU_PRINT_MSG(mBuf, 0,0);
2812  
2813    /* Copy mBuf into char array to decode it */
2814    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
2815    RIC_ALLOC(recvBuf, (Size)recvBufLen);
2816
2817    if(recvBuf == NULLP)
2818    {
2819       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
2820       return;
2821    }
2822    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
2823    {
2824       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
2825       return;
2826    }
2827
2828    DU_LOG("\nDEBUG  -->  E2AP : Received flat buffer to be decoded : ");
2829    for(i=0; i< recvBufLen; i++)
2830    {
2831         DU_LOG("%x",recvBuf[i]);
2832    }
2833
2834    /* Decoding flat buffer into E2AP messsage */
2835    e2apMsg = &e2apasnmsg;
2836    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
2837
2838    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
2839    RIC_FREE(recvBuf, (Size)recvBufLen);
2840
2841    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
2842    {
2843       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
2844       return;
2845    }
2846    DU_LOG("\n");
2847    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2848
2849    switch(e2apMsg->present)
2850    {
2851       case E2AP_PDU_PR_initiatingMessage:
2852          {
2853             switch(e2apMsg->choice.initiatingMessage->value.present)
2854             {
2855                case InitiatingMessageE2__value_PR_E2setupRequest:
2856                   {
2857                      DU_LOG("\nINFO  -->  E2AP : E2 setup request received");
2858                      ProcE2SetupReq(duId, &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest);
2859                      break;
2860                   }
2861                case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate:
2862                   {
2863                      DU_LOG("\nINFO  -->  E2AP : E2 node config update received");
2864                      BuildAndSendE2NodeConfigUpdateAck(*duId);
2865                      break;
2866                   }
2867                case InitiatingMessageE2__value_PR_ResetRequestE2:
2868                   {
2869                      DU_LOG("\nINFO  -->  E2AP : E2 Reset Request received");
2870                      ProcE2ResetReq(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2);
2871                      break;
2872                   }
2873                case InitiatingMessageE2__value_PR_RICindication:
2874                   {
2875                      DU_LOG("\nINFO  -->  E2AP : RIC Indication Acknowledged");
2876                      break;
2877                   }
2878                case InitiatingMessageE2__value_PR_RICserviceUpdate:
2879                   {
2880                      DU_LOG("\nINFO  -->  E2AP : RIC Service update received");
2881                      ProcRicServiceUpdate(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate);
2882                      break;
2883                   }
2884
2885                default:
2886                   {
2887                      DU_LOG("\nERROR  -->  E2AP : Invalid type of intiating message [%d]",e2apMsg->choice.initiatingMessage->value.present);
2888                      return;
2889                   }
2890             }/* End of switch(initiatingMessage) */
2891             break;
2892          }
2893       case E2AP_PDU_PR_successfulOutcome: 
2894          {
2895             switch(e2apMsg->choice.successfulOutcome->value.present)
2896             {
2897                case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:  
2898                   {
2899                      ProcRicSubscriptionResponse(*duId);
2900                      break;
2901                   }
2902                default:
2903                   {
2904                      DU_LOG("\nERROR  -->  E2AP : Invalid type of successfulOutcome message [%d]",e2apMsg->choice.successfulOutcome->value.present);
2905                      return;
2906                   }
2907                   break;
2908             }
2909             break; 
2910          }
2911       default:
2912          {
2913             DU_LOG("\nERROR  -->  E2AP : Invalid type message type ");
2914             return;
2915          }
2916
2917    }/* End of switch(e2apMsg->present) */
2918 } /* End of E2APMsgHdlr */
2919
2920
2921 /**********************************************************************
2922   End of file
2923  **********************************************************************/