[Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-528] RIC Subscription Response
[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[ricActionId-1].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[ricActionId-1], 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    asn_enc_rval_t  encRetVal;        /* Encoder return value */
1114    RanFunction     *ranFuncDb = &duDb->ranFunction[0];
1115
1116    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Request\n");
1117
1118    while(true)
1119    {
1120       RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
1121       if(e2apRicMsg == NULLP)
1122       {
1123          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1124          break;
1125       }
1126
1127       e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
1128       RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1129       if(e2apRicMsg->choice.initiatingMessage == NULLP)
1130       {
1131          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1132          break;
1133       }
1134       e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
1135       e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
1136       e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
1137
1138       ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
1139
1140       elementCnt = 3;
1141       ricSubscriptionReq->protocolIEs.list.count = elementCnt;
1142       ricSubscriptionReq->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
1143
1144       /* Initialize the subscription members */
1145       RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, ricSubscriptionReq->protocolIEs.list.size);
1146       if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
1147       {
1148          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1149          break;
1150       }
1151
1152       for(idx=0; idx<elementCnt; idx++)
1153       {
1154          RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionRequest_IEs_t));
1155          if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
1156          {
1157             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1158             break;
1159          }
1160       }
1161       if(idx < elementCnt)
1162          break;
1163
1164       /* Filling RIC Request Id */
1165       idx = 0;
1166       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
1167       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1168       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
1169                                                                       RICsubscriptionRequest_IEs__value_PR_RICrequestID;
1170       if(BuildNewRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID, \
1171          &ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription].requestId) != ROK)
1172       {
1173          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : Line [%d]", __func__, __LINE__);
1174          break;
1175       }
1176
1177
1178       /* Filling RAN Function Id */
1179       idx++;
1180       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
1181       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1182       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
1183                                                                       RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
1184       ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ranFuncDb->id;
1185
1186       /* Filling RIC Subscription Details */
1187       idx++;
1188       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
1189       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1190       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
1191                                                                       RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
1192       if(BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails),\
1193          &ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription]) != ROK)
1194       {
1195          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : Line [%d]", __func__, __LINE__);
1196          break;
1197       }
1198
1199       /* Prints the Msg formed */
1200       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
1201
1202       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1203       encBufSize = 0;
1204       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf, encBuf);
1205       if(encRetVal.encoded == ENCODE_FAIL)
1206       {
1207          DU_LOG("\nERROR  -->  E2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
1208                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1209          break;               
1210       }
1211       else
1212       {
1213          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
1214          for(int i=0; i< encBufSize; i++)
1215          {
1216             DU_LOG("%x",encBuf[i]);
1217          } 
1218       }
1219
1220       /* Sending msg */
1221       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
1222       {
1223          DU_LOG("\nERROR  -->  E2AP : Sending RIC subscription Request failed");
1224          break;
1225       }
1226
1227       ranFuncDb->numOfSubscription++;
1228       ret = ROK;
1229       break;
1230    }
1231
1232    if(ret == RFAILED)
1233       memset(&ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription], 0, sizeof(RicSubscription));
1234    FreeRicSubscriptionReq(e2apRicMsg);
1235    return ret;
1236 }
1237
1238 /*******************************************************************
1239  *
1240  * @brief Process RicSubscriptionResponse
1241  *
1242  * @details
1243  *
1244  *    Function : ProcRicSubscriptionRsp
1245  *
1246  * Functionality: Processes RicSubscriptionRsp
1247  *
1248  * @return ROK     - void
1249  *
1250  ******************************************************************/
1251
1252 void ProcRicSubscriptionResponse(uint32_t duId, RICsubscriptionResponse_t  *ricSubscriptionRsp)
1253 {
1254    uint8_t duIdx = 0, ieIdx = 0,subsIdx = 0, notAdmitIdx = 0;
1255    uint8_t ranFuncId = 0, actionId = 0;
1256    DuDb *duDb = NULLP;
1257    bool ricReqIdDecoded = false;
1258    RicRequestId ricReqId;
1259    RanFunction  *ranFuncDb = NULLP;
1260    RICsubscriptionResponse_IEs_t *ricSubsRspIe = NULLP;
1261    RICaction_NotAdmitted_List_t *notAdmitList = NULLP;
1262
1263    DU_LOG("\nINFO  -->  E2AP : RIC Subscription Response received");
1264
1265    /* Fetch DU DB */
1266    SEARCH_DU_DB(duIdx, duId, duDb);
1267    if(duDb == NULLP)
1268    {
1269       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
1270       return;
1271    }
1272
1273    memset(&ricReqId, 0, sizeof(RicRequestId));
1274    if(ricSubscriptionRsp)
1275    {
1276       if(ricSubscriptionRsp->protocolIEs.list.array)
1277       {
1278          for(ieIdx=0; ieIdx<ricSubscriptionRsp->protocolIEs.list.count; ieIdx++)
1279          {
1280             if(ricSubscriptionRsp->protocolIEs.list.array[ieIdx])
1281             {
1282                ricSubsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
1283                switch(ricSubscriptionRsp->protocolIEs.list.array[ieIdx]->id)
1284                {
1285                   case ProtocolIE_IDE2_id_RICrequestID:
1286                      {
1287                         ricReqId.requestorId = ricSubsRspIe->value.choice.RICrequestID.ricRequestorID;
1288                         ricReqId.instanceId = ricSubsRspIe->value.choice.RICrequestID.ricInstanceID;
1289                         ricReqIdDecoded = true;
1290                         break;
1291                      }
1292                   case ProtocolIE_IDE2_id_RANfunctionID:
1293                      {
1294                         ranFuncId = ricSubsRspIe->value.choice.RANfunctionID;
1295                         if(duDb->ranFunction[ranFuncId-1].id == ranFuncId)
1296                         {
1297                            ranFuncDb = &duDb->ranFunction[ranFuncId-1];
1298                         }
1299                         else
1300                         {
1301                            DU_LOG("\nERROR  -->  E2AP : ProcRicSubscriptionResponse: RAN Function ID [%d] not found", ranFuncId);
1302                            return;
1303                         }
1304                         break; 
1305                      }
1306                   case ProtocolIE_IDE2_id_RICactions_Admitted:
1307                      {
1308                         break;
1309                      }
1310                   case ProtocolIE_IDE2_id_RICactions_NotAdmitted:
1311                      {
1312                         if(!(ranFuncDb && ricReqIdDecoded))
1313                            return;
1314
1315                         notAdmitList = &ricSubsRspIe->value.choice.RICaction_NotAdmitted_List;
1316                         for(notAdmitIdx = 0; notAdmitIdx < notAdmitList->list.count; notAdmitIdx++)
1317                         {
1318                            actionId = ((RICaction_NotAdmitted_ItemIEs_t *)(notAdmitList->list.array[notAdmitIdx]))->\
1319                               value.choice.RICaction_NotAdmitted_Item.ricActionID;
1320
1321                               /* Remove action from RAN Function's subscription list */
1322                               for(subsIdx = 0; subsIdx < ranFuncDb->numOfSubscription; subsIdx++)
1323                               {
1324                                  if((ranFuncDb->subscriptionList[subsIdx].requestId.requestorId == ricReqId.requestorId) &&
1325                                        (ranFuncDb->subscriptionList[subsIdx].requestId.instanceId == ricReqId.instanceId))
1326                                  {
1327                                     if(ranFuncDb->subscriptionList[subsIdx].actionSequence[actionId-1].id == actionId)
1328                                     {
1329                                        memset(&ranFuncDb->subscriptionList[subsIdx].actionSequence[actionId-1], 0, \
1330                                           sizeof(ActionInfo));
1331                                        ranFuncDb->subscriptionList[subsIdx].numOfActions--;
1332                                        break;
1333                                     }
1334                                  }
1335                               }
1336                         }
1337                         break;
1338                      }
1339                }
1340             }
1341          }
1342       }
1343    } 
1344 }
1345
1346 /*******************************************************************
1347  *
1348  * @brief deallocate the memory allocated in E2SetupFailure
1349  *
1350  * @details
1351  *
1352  *    Function : FreeE2SetupFailure 
1353  *
1354  *    Functionality: deallocate the memory allocated in E2SetupFailure 
1355  *
1356  * @params[in] E2AP_PDU_t *e2apMsg
1357  *
1358  * @return void
1359  * ****************************************************************/
1360 void FreeE2SetupFailure(E2AP_PDU_t *e2apMsg)
1361 {
1362    uint8_t arrIdx = 0;
1363    E2setupFailure_t  *e2SetupFail;
1364
1365    if(e2apMsg)
1366    {
1367       if(e2apMsg->choice.unsuccessfulOutcome)
1368       {
1369          e2SetupFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
1370          if(e2SetupFail->protocolIEs.list.array)
1371          {
1372             for(arrIdx=0; arrIdx<e2SetupFail->protocolIEs.list.count; arrIdx++)
1373             {
1374                RIC_FREE(e2SetupFail->protocolIEs.list.array[arrIdx], sizeof(E2setupFailureIEs_t)); 
1375             }
1376             RIC_FREE(e2SetupFail->protocolIEs.list.array, e2SetupFail->protocolIEs.list.size);
1377          }
1378          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
1379       }
1380       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1381    }
1382 }
1383
1384 /*******************************************************************
1385  *
1386  * @brief Buld and send the E2 Setup failure
1387  *
1388  * @details
1389  *
1390  *    Function : BuildAndSendE2SetupFailure
1391  *
1392  *    Functionality:
1393  *         - Buld and send the E2 Setup failure
1394  * @return ROK     - success
1395  *         RFAILED - failure
1396  *
1397  * ****************************************************************/
1398
1399 uint8_t BuildAndSendE2SetupFailure(uint32_t duId, uint8_t transId)
1400 {
1401    E2AP_PDU_t         *e2apMsg = NULL;
1402    E2setupFailure_t   *e2SetupFailure;
1403    asn_enc_rval_t     encRetVal;
1404    uint8_t            arrIdx;
1405    uint8_t            elementCnt;
1406    bool  memAllocFailed = false;
1407
1408    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup failure\n");
1409    while(true)
1410    {
1411       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1412       if(e2apMsg == NULLP)
1413       {
1414          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1415          break;
1416       }
1417       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
1418       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
1419       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
1420       {
1421          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1422          break;
1423       }
1424
1425       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
1426       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
1427       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2setupFailure;
1428       e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
1429
1430       elementCnt = 3;
1431       e2SetupFailure->protocolIEs.list.count = elementCnt;
1432       e2SetupFailure->protocolIEs.list.size  = elementCnt * sizeof(struct E2setupFailureIEs *);
1433
1434       RIC_ALLOC(e2SetupFailure->protocolIEs.list.array, e2SetupFailure->protocolIEs.list.size);
1435       if(e2SetupFailure->protocolIEs.list.array == NULLP)
1436       {
1437          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
1438          break;
1439       }
1440
1441       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
1442       {
1443          RIC_ALLOC(e2SetupFailure->protocolIEs.list.array[arrIdx], sizeof(struct E2setupFailureIEs));
1444          if(e2SetupFailure->protocolIEs.list.array[arrIdx] == NULLP)
1445          {
1446             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
1447             memAllocFailed = true;
1448             break;
1449          }
1450       }
1451
1452       if(memAllocFailed == true)
1453       {
1454           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
1455           break;
1456       }
1457
1458       /* Trans Id */
1459       arrIdx = 0;
1460       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
1461       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1462       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TransactionID;
1463       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
1464
1465       arrIdx++;
1466       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
1467       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1468       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_CauseE2;
1469       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.present = CauseE2_PR_protocol;
1470       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.protocol = CauseE2Protocol_unspecified;
1471
1472       arrIdx++;
1473       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
1474       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
1475       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TimeToWaitE2;
1476       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
1477
1478       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1479       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1480       encBufSize = 0;
1481       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
1482
1483       /* Check encode results */
1484       if(encRetVal.encoded == ENCODE_FAIL)
1485       {
1486          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Setup failure structure (at %s)\n",\
1487                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1488          break;
1489       }
1490       else
1491       {
1492          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Setup Failure\n");
1493          for(int i=0; i< encBufSize; i++)
1494          {
1495             DU_LOG("%x",encBuf[i]);
1496          }
1497       }
1498
1499       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
1500       {
1501          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Failure failed");
1502          break;
1503       }
1504       break;
1505    }
1506
1507    FreeE2SetupFailure(e2apMsg);
1508 }
1509
1510 /*******************************************************************
1511  *
1512  * @brief process the e2setup request 
1513  *
1514  * @details
1515  *
1516  *    Function : ProcE2SetupReq
1517  *
1518  * Functionality: process the e2setup request
1519  *
1520  * @return ROK     - success
1521  *         RFAILED - failure
1522  *
1523  ******************************************************************/
1524
1525 uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
1526 {
1527    uint8_t arrIdx = 0, e2NodeAddListIdx =0, duIdx = 0, transId =0, ranFuncIdx;
1528    DuDb    *duDb = NULLP;
1529    E2nodeComponentConfigAddition_List_t *e2NodeAddList;
1530    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
1531    RANfunction_ItemIEs_t *ranFuncItemIe;
1532    RANfunction_Item_t  *ranFunItem;
1533    RANfunctions_List_t *ranFunctionsList;
1534
1535    if(e2SetupReq)
1536    {
1537       if(e2SetupReq->protocolIEs.list.array)      
1538       {
1539          for(arrIdx=0; arrIdx<e2SetupReq->protocolIEs.list.count; arrIdx++)
1540          {
1541             if(e2SetupReq->protocolIEs.list.array[arrIdx])
1542             {
1543                switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
1544                {
1545                   case ProtocolIE_IDE2_id_TransactionID:
1546                      {
1547                         transId = e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; 
1548                         break;
1549                      }
1550                   case ProtocolIE_IDE2_id_GlobalE2node_ID:
1551                      {
1552                         if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID)
1553                         {
1554                             *duId =e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID->buf[0];
1555
1556                             SEARCH_DU_DB(duIdx, *duId, duDb); 
1557                             if(duDb == NULLP)
1558                             {
1559                                duDb = &ricCb.duInfo[ricCb.numDu];
1560                                ricCb.numDu++;
1561                             }
1562                             memset(duDb, 0, sizeof(DuDb));
1563                             duDb->duId = *duId;
1564                         }
1565                         break;
1566                      }
1567                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
1568                      {
1569                         ranFunctionsList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
1570
1571                         if(ranFunctionsList->list.array)
1572                         {
1573                            for(ranFuncIdx=0;ranFuncIdx<ranFunctionsList->list.count; ranFuncIdx++)
1574                            {
1575                               ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncIdx]; 
1576                               ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
1577                               duDb->ranFunction[ranFunItem->ranFunctionID-1].id = ranFunItem->ranFunctionID; 
1578                               duDb->ranFunction[ranFunItem->ranFunctionID-1].revisionCounter = ranFunItem->ranFunctionRevision; 
1579                               duDb->numOfRanFunction++;
1580                            }
1581                         }
1582                         break;
1583                      }
1584                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
1585                      {
1586                         e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;      
1587                         if(e2NodeAddList->list.array)
1588                         {
1589                            for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
1590                            {
1591                               if(e2NodeAddList->list.array[e2NodeAddListIdx])
1592                               {
1593                                  e2NodeAddItem = \
1594                                     (E2nodeComponentConfigAddition_ItemIEs_t *)e2NodeAddList->list.array[e2NodeAddListIdx];
1595                                  if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.\
1596                                     choice.e2nodeComponentInterfaceTypeF1)
1597                                  {
1598                                     duDb->e2NodeComponent.interfaceType = F1; 
1599                                     duDb->e2NodeComponent.componentId = \
1600                                        e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.\
1601                                        choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]; 
1602                                  }
1603                               }
1604                            }
1605                         }
1606                         break;
1607                      }
1608                      default:
1609                         break;
1610                   }
1611                }
1612             }
1613         }
1614    }
1615    
1616    if(BuildAndSendE2SetupRsp(duDb, transId) !=ROK)
1617    {
1618       DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 setup response");
1619       return RFAILED;
1620    }
1621    return ROK;   
1622 }
1623
1624 /*******************************************************************
1625  *
1626  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
1627  *
1628  * @details
1629  *
1630  *    Function : FreeE2NodeConfigUpdate 
1631  *
1632  *    Functionality:
1633  *       - freeing the memory allocated for E2nodeConfigurationUpdate
1634  *
1635  * @params[in] E2AP_PDU_t *e2apMsg 
1636  * @return ROK     - success
1637  *         RFAILED - failure
1638  *
1639  * ****************************************************************/
1640 void FreeE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg)
1641 {
1642    uint8_t arrIdx =0;
1643    E2nodeConfigurationUpdate_t *e2NodeConfigUpdateAck;
1644
1645    if(e2apMsg != NULLP)
1646    {
1647       if(e2apMsg->choice.successfulOutcome != NULLP)
1648       {
1649          e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
1650          if(e2NodeConfigUpdateAck->protocolIEs.list.array != NULLP)
1651          {
1652             for(arrIdx = 0; arrIdx < e2NodeConfigUpdateAck->protocolIEs.list.count; arrIdx++)
1653             {
1654                RIC_FREE(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_t));
1655             }
1656             RIC_FREE(e2NodeConfigUpdateAck->protocolIEs.list.array, e2NodeConfigUpdateAck->protocolIEs.list.size);
1657          }
1658          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1659       }
1660       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1661    }
1662 }
1663
1664 /*******************************************************************
1665  *
1666  * @brief Buld and send the E2 node config update msg 
1667  *
1668  * @details
1669  *
1670  *    Function : BuildAndSendE2NodeConfigUpdate
1671  *
1672  *    Functionality:
1673  *         - Buld and send the E2 node config update msg
1674  * @return ROK     - success
1675  *         RFAILED - failure
1676  *
1677  * ****************************************************************/
1678
1679 uint8_t BuildAndSendE2NodeConfigUpdateAck(uint32_t duId)
1680 {
1681    uint8_t arrIdx = 0,elementCnt = 1;
1682    uint8_t ret = ROK;
1683    E2AP_PDU_t        *e2apMsg = NULLP;
1684    E2nodeConfigurationUpdateAcknowledge_t *e2NodeConfigUpdateAck = NULLP;
1685    asn_enc_rval_t     encRetVal;       /* Encoder return value */
1686
1687    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update Ack Message\n");
1688    do
1689    {
1690       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1691       if(e2apMsg == NULLP)
1692       {
1693          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1694          break;
1695       }
1696       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
1697       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1698       if(e2apMsg->choice.successfulOutcome == NULLP)
1699       {
1700          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1701          RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1702          return RFAILED;
1703       }
1704       
1705       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
1706       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
1707       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge;
1708       e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
1709
1710       e2NodeConfigUpdateAck->protocolIEs.list.count = elementCnt;
1711       e2NodeConfigUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t*);
1712       /* Initialize the Ric Indication members */
1713       RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array, \
1714             e2NodeConfigUpdateAck->protocolIEs.list.size);
1715       if(e2NodeConfigUpdateAck->protocolIEs.list.array == NULLP)
1716       {
1717          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdateAck failed");
1718          break;
1719       }
1720       
1721       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
1722       {
1723          RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t));
1724          if(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
1725          {
1726             
1727             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdateAck failed");
1728             break;
1729          }
1730       }
1731
1732       arrIdx = 0;
1733       /* TransactionID */
1734       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
1735       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1736       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_TransactionID;
1737       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = TRANS_ID;
1738
1739
1740       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1741
1742       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1743       encBufSize = 0;
1744       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
1745             encBuf);
1746       if(encRetVal.encoded == ENCODE_FAIL)
1747       {
1748          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Node config update ack structure (at %s)\n",\
1749                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1750          return RFAILED;
1751       }
1752       else
1753       {
1754          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Node config update ack \n");
1755          for(int i=0; i< encBufSize; i++)
1756          {
1757             DU_LOG("%x",encBuf[i]);
1758          } 
1759       }
1760
1761
1762       /* Sending msg */
1763       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
1764       {
1765          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Node config update ack ");
1766          return RFAILED;
1767       }
1768
1769       break;
1770    }while(true);
1771    
1772    FreeE2NodeConfigUpdateAck(e2apMsg);
1773    return ret;
1774 }
1775
1776 /*******************************************************************
1777  *
1778  * @brief Deallocate the memory allocated for E2 Reset Response
1779  *
1780  * @details
1781  *
1782  *    Function : FreeE2ResetResponse
1783  *
1784  *    Functionality:
1785  *       - freeing the memory allocated for E2ResetResponse
1786  *
1787  * @params[in] E2AP_PDU_t *e2apMsg
1788  * @return ROK     - success
1789  *         RFAILED - failure
1790  *
1791  * ****************************************************************/
1792 void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg)
1793 {
1794    uint8_t ieIdx =0;
1795    ResetResponseE2_t *resetResponse;
1796
1797    if(e2apMsg != NULLP)
1798    {
1799       if(e2apMsg->choice.successfulOutcome != NULLP)
1800       {
1801          resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
1802          if(resetResponse->protocolIEs.list.array)
1803          {
1804             for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
1805             {
1806                if(resetResponse->protocolIEs.list.array[ieIdx])
1807                {
1808                   RIC_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
1809                }
1810             }
1811             RIC_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
1812          }
1813          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1814       }
1815       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1816    }
1817 }
1818
1819 /*******************************************************************
1820  *
1821  * @brief Buld and send the E2 Reset Response msg
1822  *
1823  * @details
1824  *
1825  *    Function : BuildAndSendE2ResetResponse
1826  *
1827  *    Functionality:
1828  *         - Buld and send the E2 Reset Response Message
1829  * @return ROK     - success
1830  *         RFAILED - failure
1831  *
1832  * ****************************************************************/
1833 uint8_t BuildAndSendResetResponse(uint32_t duId, uint8_t transId)
1834 {
1835    uint8_t           ieIdx = 0, elementCnt = 0;
1836    uint8_t           ret = RFAILED;
1837    E2AP_PDU_t        *e2apMsg = NULLP;
1838    ResetResponseE2_t *resetResponse;
1839    asn_enc_rval_t    encRetVal;       /* Encoder return value */
1840
1841    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
1842    do
1843    {
1844       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1845       if(e2apMsg == NULLP)
1846       {
1847          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
1848          break;
1849       }
1850       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
1851
1852       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1853       if(e2apMsg->choice.successfulOutcome == NULLP)
1854       {
1855          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
1856          RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1857          return RFAILED;
1858       }
1859  
1860       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
1861       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
1862       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
1863       resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
1864
1865       elementCnt = 1;
1866       resetResponse->protocolIEs.list.count = elementCnt;
1867       resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
1868       RIC_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
1869       if(!resetResponse->protocolIEs.list.array)
1870       {
1871          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
1872          break;
1873       }
1874
1875       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
1876       {
1877          RIC_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
1878          if(!resetResponse->protocolIEs.list.array[ieIdx])
1879          {
1880             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
1881             break;
1882          }
1883       }
1884       if(ieIdx < elementCnt)
1885          break;
1886
1887       ieIdx = 0; 
1888       resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
1889       resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
1890       resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
1891       resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
1892
1893       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1894
1895       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1896       encBufSize = 0;
1897       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
1898       if(encRetVal.encoded == ENCODE_FAIL)
1899       {
1900          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
1901                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1902          return RFAILED;
1903       }
1904       else
1905       {
1906          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
1907          for(int i=0; i< encBufSize; i++)
1908          {
1909             DU_LOG("%x",encBuf[i]);
1910          }
1911       }
1912
1913       /* Sending msg */
1914       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
1915       {
1916          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
1917          return RFAILED;
1918       }
1919
1920       ret = ROK;
1921       break;
1922    }while(true);
1923
1924    FreeE2ResetResponse(e2apMsg);
1925    return ROK;
1926 }
1927
1928 /*******************************************************************
1929  *
1930  * @brief process the E2 Reset Request
1931  *
1932  * @details
1933  *
1934  *    Function : ProcE2ResetReq
1935  *
1936  * Functionality: Process E2 Reset Request
1937  *
1938  * @return ROK     - success
1939  *         RFAILED - failure
1940  *
1941  ******************************************************************/
1942
1943 uint8_t ProcE2ResetReq(uint32_t duId, ResetRequestE2_t  *resetReq)
1944 {
1945    uint8_t ieIdx = 0, duIdx = 0;
1946    uint8_t transId = 0, cause = 0;
1947    DuDb    *duDb = NULLP;
1948
1949    if(resetReq)
1950    {
1951       if(resetReq->protocolIEs.list.array)
1952       {
1953          for(ieIdx=0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
1954          {
1955             if(resetReq->protocolIEs.list.array[ieIdx])
1956             {
1957                switch(resetReq->protocolIEs.list.array[ieIdx]->id)
1958                {
1959                   case ProtocolIE_IDE2_id_TransactionID:
1960                      transId = resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
1961                      break;
1962                   case ProtocolIE_IDE2_id_CauseE2:
1963                      DU_LOG("\nDEBUG  -->  E2AP : Reset reason %d", resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present);
1964                      switch(resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present)
1965                      {
1966                         case CauseE2_PR_NOTHING:
1967                            break;
1968                         case CauseE2_PR_ricRequest:
1969                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricRequest;
1970                            break;
1971                         case CauseE2_PR_ricService:
1972                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricService;
1973                            break;
1974                         case CauseE2_PR_e2Node:
1975                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.e2Node;
1976                            break;
1977                         case CauseE2_PR_transport:
1978                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.transport;
1979                            break;
1980                         case CauseE2_PR_protocol:
1981                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.protocol;
1982                            break;
1983                         case CauseE2_PR_misc:
1984                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.misc;
1985                            break;
1986                      }
1987                      DU_LOG("\nDEBUG  -->  E2AP : Reset cause %d", cause);
1988                      break;
1989                }
1990             }
1991          }
1992       }
1993    }
1994    BuildAndSendResetResponse(duId, transId);
1995    return ROK;
1996 }
1997
1998 /*******************************************************************
1999  *
2000  * @brief deallocate the memory allocated in building the
2001  *    Service Query message
2002  *
2003  * @details
2004  *
2005  *    Function : FreeRicServiceQuery 
2006  *
2007  *    Functionality: deallocate the memory allocated in building
2008  *    Ric Service Query message
2009  *
2010  * @params[in] E2AP_PDU_t *e2apMsg
2011  *
2012  * @return void
2013  * ****************************************************************/
2014
2015 void FreeRicServiceQuery(E2AP_PDU_t *e2apMsg)
2016 {
2017    uint8_t arrIdx = 0, ranFuncIdx=0;
2018    RANfunctionsID_List_t *ranFuncAcceptedList=NULL;
2019    RICserviceQuery_t *ricServiceQuery=NULL;
2020    
2021    if(e2apMsg)
2022    {
2023       if(e2apMsg->choice.initiatingMessage)
2024       {
2025          ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
2026          if(ricServiceQuery->protocolIEs.list.array)
2027          {
2028             for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
2029             {
2030                if(ricServiceQuery->protocolIEs.list.array[arrIdx])
2031                {
2032                   switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
2033                   {
2034                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
2035                         {
2036                            ranFuncAcceptedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
2037                            if(ranFuncAcceptedList->list.array)
2038                            {
2039                               for(ranFuncIdx=0;ranFuncIdx<ranFuncAcceptedList->list.count; ranFuncIdx++)
2040                               {
2041                                  RIC_FREE(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
2042                               }
2043                               RIC_FREE(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
2044                            }
2045                            break;
2046                         }
2047                      case RICserviceQuery_IEs__value_PR_TransactionID:
2048                         {
2049                            break;
2050                         }
2051                   }
2052                   RIC_FREE(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t)); 
2053                }
2054             }
2055             RIC_FREE(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
2056          }
2057          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2058       }
2059       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2060    }
2061 }
2062
2063 /*******************************************************************
2064  *
2065  * @brief build and send the ric service Query 
2066  *
2067  * @details
2068  *
2069  *    Function : BuildAndSendRicServiceQuery
2070  *
2071  * Functionality: build and send the ric service Query 
2072  * @return ROK     - success
2073  *         RFAILED - Acknowledge
2074  *
2075  ******************************************************************/
2076
2077 uint8_t BuildAndSendRicServiceQuery(DuDb *duDb)
2078 {
2079    uint8_t arrIdx;
2080    uint8_t elementCnt;
2081    uint8_t ret = RFAILED;
2082    bool  memAllocFailed = false;
2083    E2AP_PDU_t     *e2apMsg = NULL;
2084    asn_enc_rval_t encRetVal;
2085    RICserviceQuery_t *ricServiceQuery;
2086
2087    DU_LOG("\nINFO   -->  E2AP : Building Ric service Query\n");
2088    while(true)
2089    {
2090       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2091       if(e2apMsg == NULLP)
2092       {
2093          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2094          break;
2095       }
2096       e2apMsg->present =  E2AP_PDU_PR_initiatingMessage;
2097       RIC_ALLOC(e2apMsg->choice.initiatingMessage , sizeof(struct InitiatingMessageE2));
2098       if(e2apMsg->choice.initiatingMessage == NULLP)
2099       {
2100          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2101          break;
2102       }
2103
2104       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceQuery;
2105       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2106       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceQuery;
2107       ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
2108
2109       elementCnt = 1;
2110       /* Fill Accepted RAN function IE If Ran function information is stored in databse */
2111       if(duDb->numOfRanFunction)
2112          elementCnt++;
2113
2114       ricServiceQuery->protocolIEs.list.count = elementCnt;
2115       ricServiceQuery->protocolIEs.list.size  = elementCnt * sizeof(RICserviceQuery_IEs_t*);
2116
2117       RIC_ALLOC(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
2118       if(ricServiceQuery->protocolIEs.list.array == NULLP)
2119       {
2120          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2121          break;
2122       }
2123
2124       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2125       {
2126          RIC_ALLOC(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t));
2127          if(ricServiceQuery->protocolIEs.list.array[arrIdx] == NULLP)
2128          {
2129             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2130             memAllocFailed = true;
2131             break;
2132          }
2133       }
2134       if(memAllocFailed == true)
2135       {
2136          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2137          break;
2138       }
2139
2140       /* Trans Id */
2141       arrIdx = 0;
2142       ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2143       ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2144       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_TransactionID;
2145       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = assignTransactionId(duDb);
2146       
2147       if(duDb->numOfRanFunction)
2148       {
2149          /* Accepted RAN function Id */
2150          arrIdx++;
2151          ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
2152          ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2153          ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_RANfunctionsID_List;
2154          if(BuildRanFunctionAcceptedList(duDb, 0, NULL, &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceQuery)!=ROK)
2155          {
2156             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
2157             break;         
2158          }
2159       }
2160       
2161       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2162       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2163       encBufSize = 0;
2164       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2165
2166       /* Check encode results */
2167       if(encRetVal.encoded == ENCODE_FAIL)
2168       {
2169          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service Query structure (at %s)\n",\
2170                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2171          break;
2172       }
2173       else
2174       {
2175          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service Query\n");
2176          for(int i=0; i< encBufSize; i++)
2177          {
2178             DU_LOG("%x",encBuf[i]);
2179          }
2180       }
2181
2182       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
2183       {
2184          DU_LOG("\nERROR  -->  E2AP : Sending of RIC service  Query failed");
2185          break;
2186       }
2187
2188       ret =ROK;
2189       break;
2190    }
2191    FreeRicServiceQuery(e2apMsg);
2192    return ret;
2193 }
2194
2195 /*******************************************************************
2196  *
2197  * @brief deallocate the memory allocated in RicServiceUpdateFailure
2198  *
2199  * @details
2200  *
2201  *    Function : FreeRicServiceUpdateFailure 
2202  *
2203  *    Functionality: deallocate the memory allocated in RicServiceUpdatefailure
2204  *
2205  * @params[in] E2AP_PDU_t *e2apMsg
2206  *
2207  * @return void
2208  * ****************************************************************/
2209
2210 void FreeRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
2211 {
2212    uint8_t arrIdx = 0;
2213    RICserviceUpdateFailure_t *ricServiceUpdateFailure=NULL;
2214    
2215    if(e2apMsg)
2216    {
2217       if(e2apMsg->choice.unsuccessfulOutcome)
2218       {
2219          ricServiceUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
2220          if(ricServiceUpdateFailure->protocolIEs.list.array)
2221          {
2222             for(arrIdx=0; arrIdx<ricServiceUpdateFailure->protocolIEs.list.count; arrIdx++)
2223             {
2224                RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t)); 
2225             }
2226             RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array, ricServiceUpdateFailure->protocolIEs.list.size);
2227          }
2228          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
2229       }
2230       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2231    }
2232 }
2233
2234 /*******************************************************************
2235  *
2236  * @brief fill E2 failure cause 
2237  *
2238  * @details
2239  *
2240  *    Function : fillE2FailureCause
2241  *
2242  * Functionality: fill E2 failure cause
2243  * @return ROK     - success
2244  *         RFAILED - failure
2245  *
2246  ******************************************************************/
2247
2248 void fillE2FailureCause(CauseE2_t *cause, CauseE2_PR causePresent, uint8_t reason)
2249 {
2250    cause->present = causePresent;
2251
2252    switch(cause->present)
2253    {
2254       case CauseE2_PR_ricRequest:
2255          cause->choice.ricRequest = reason;
2256          break;
2257       case CauseE2_PR_ricService:
2258          cause->choice.ricService = reason;
2259          break;
2260       case CauseE2_PR_e2Node:
2261          cause->choice.e2Node = reason;
2262          break;
2263       case CauseE2_PR_transport:
2264          cause->choice.transport = reason;
2265          break;
2266       case CauseE2_PR_protocol:
2267          cause->choice.protocol = reason;
2268          break;
2269       case CauseE2_PR_misc:
2270          cause->choice.misc = reason;
2271          break;
2272       default:
2273          cause->choice.misc = CauseE2Misc_unspecified;
2274          break;
2275    }
2276 }
2277
2278 /*******************************************************************
2279  *
2280  * @brief build and send the ric service update failure 
2281  *
2282  * @details
2283  *
2284  *    Function : BuildAndSendRicServiceUpdateFailure
2285  *
2286  * Functionality: build and send the ric service update failure 
2287  * @return ROK     - success
2288  *         RFAILED - failure
2289  *
2290  ******************************************************************/
2291
2292 uint8_t BuildAndSendRicServiceUpdateFailure(uint32_t duId, int8_t transId, CauseE2_PR causePresent, uint8_t reason)
2293 {
2294
2295    E2AP_PDU_t         *e2apMsg = NULL;
2296    asn_enc_rval_t     encRetVal;
2297    uint8_t            ret = RFAILED;
2298    uint8_t            arrIdx=0;
2299    uint8_t            elementCnt=0;
2300    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
2301
2302    DU_LOG("\nINFO   -->  E2AP : Building Ric service update failure\n");
2303    while(true)
2304    {
2305       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2306       if(e2apMsg == NULLP)
2307       {
2308          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2309          break;
2310       }
2311       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
2312       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
2313       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
2314       {
2315          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2316          break;
2317       }
2318
2319       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
2320       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
2321       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure;
2322       ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
2323
2324       elementCnt = 3;
2325       ricServiceFailure->protocolIEs.list.count = elementCnt;
2326       ricServiceFailure->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateFailure_IEs_t *);
2327
2328       RIC_ALLOC(ricServiceFailure->protocolIEs.list.array, ricServiceFailure->protocolIEs.list.size);
2329       if(ricServiceFailure->protocolIEs.list.array == NULLP)
2330       {
2331          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2332          break;
2333       }
2334
2335       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2336       {
2337          RIC_ALLOC(ricServiceFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t));
2338          if(ricServiceFailure->protocolIEs.list.array[arrIdx] == NULLP)
2339          {
2340             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2341             break;
2342          }
2343       }
2344       if(arrIdx<elementCnt)
2345       {
2346          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2347          break;
2348       }
2349
2350       /* Trans Id */
2351       arrIdx = 0;
2352       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2353       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2354       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TransactionID;
2355       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
2356
2357       arrIdx++;
2358       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
2359       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2360       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_CauseE2;
2361       fillE2FailureCause(&ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, causePresent, reason);
2362
2363       arrIdx++;
2364       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
2365       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
2366       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TimeToWaitE2;
2367       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
2368
2369       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2370       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2371       encBufSize = 0;
2372       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2373
2374       /* Check encode results */
2375       if(encRetVal.encoded == ENCODE_FAIL)
2376       {
2377          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update failure structure (at %s)\n",\
2378                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2379          break;
2380       }
2381       else
2382       {
2383          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Failure\n");
2384          for(int i=0; i< encBufSize; i++)
2385          {
2386             DU_LOG("%x",encBuf[i]);
2387          }
2388       }
2389
2390       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
2391       {
2392          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update failed");
2393          break;
2394       }
2395       ret = ROK;
2396       break;
2397    }
2398
2399    FreeRicServiceUpdateFailure(e2apMsg);
2400    return ret;
2401 }
2402
2403
2404 /*******************************************************************
2405  *
2406  * @brief deallocate the memory allocated in RicServiceUpdateAck(
2407  *
2408  * @details
2409  *
2410  *    Function : FreeRicServiceUpdateAck 
2411  *
2412  *    Functionality: deallocate the memory allocated in RicServiceUpdateAck
2413  *
2414  * @params[in] E2AP_PDU_t *e2apMsg
2415  *
2416  * @return void
2417  * ****************************************************************/
2418
2419 void FreeRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
2420 {
2421    uint8_t arrIdx = 0, ranFuncIdx=0;
2422    RANfunctionsID_List_t *acceptedList=NULL;
2423    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
2424    RANfunctionsIDcause_List_t  *rejectedList=NULL;
2425
2426    if(e2apMsg)
2427    {
2428       if(e2apMsg->choice.successfulOutcome)
2429       {
2430          ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
2431          if(ricServiceUpdateAck->protocolIEs.list.array)
2432          {
2433             for(arrIdx=0; arrIdx<ricServiceUpdateAck->protocolIEs.list.count; arrIdx++)
2434             {
2435                if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx])
2436                {
2437                   switch(ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id)
2438                   {
2439                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
2440                         {
2441                            acceptedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
2442                            if(acceptedList->list.array)
2443                            {
2444                               for(ranFuncIdx=0;ranFuncIdx<acceptedList->list.count; ranFuncIdx++)
2445                               {
2446                                  RIC_FREE(acceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
2447                               }
2448                               RIC_FREE(acceptedList->list.array, acceptedList->list.size);
2449                            }
2450                            break;
2451                         }
2452
2453                      case ProtocolIE_IDE2_id_RANfunctionsRejected:
2454                         {
2455                            rejectedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
2456                            if(rejectedList->list.array)
2457                            {
2458                               for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
2459                               {
2460                                  RIC_FREE(rejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
2461                               }
2462                               RIC_FREE(rejectedList->list.array, rejectedList->list.size);
2463                            }
2464                            break;
2465                         }
2466                   }
2467                   RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t)); 
2468                }
2469             }
2470             RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
2471          }
2472          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2473       }
2474       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2475    }
2476 }
2477
2478 /*******************************************************************
2479  *
2480  * @brief Build RAN function rejected list
2481  *
2482  * @details
2483  *
2484  *    Function : BuildRanFunctionRejectedList
2485  *
2486  *    Functionality: Build RAN function rejected list 
2487  *
2488  * @params[in] 
2489  *    Count of ran functions to be rejected in the list 
2490  *    Received list of RAN functions
2491  *
2492  * @return ROK - success
2493  *         RFAILED - failure
2494  * ****************************************************************/
2495
2496 uint8_t BuildRanFunctionRejectedList(uint8_t count, RanFunction *ranFunRejectedList, RANfunctionsIDcause_List_t *ranFuncRejectedList)
2497 {
2498    uint8_t ranFuncIdx = 0;
2499    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
2500    
2501    ranFuncRejectedList->list.count = count;
2502    
2503    ranFuncRejectedList->list.size = ranFuncRejectedList->list.count*sizeof(RANfunctionIDcause_ItemIEs_t*);
2504    RIC_ALLOC(ranFuncRejectedList->list.array, ranFuncRejectedList->list.size);
2505    if(ranFuncRejectedList->list.array == NULLP)
2506    {
2507       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array");
2508       return RFAILED;
2509    }
2510    
2511    for(ranFuncIdx = 0; ranFuncIdx< ranFuncRejectedList->list.count; ranFuncIdx++)
2512    {
2513       RIC_ALLOC(ranFuncRejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
2514       if(ranFuncRejectedList->list.array[ranFuncIdx] == NULLP)
2515       {
2516          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array item");
2517          return RFAILED;
2518       }
2519       ranFuncRejectedItemIe = (RANfunctionIDcause_ItemIEs_t*)ranFuncRejectedList->list.array[ranFuncIdx];
2520       ranFuncRejectedItemIe->id = ProtocolIE_IDE2_id_RANfunctionIEcause_Item;
2521       ranFuncRejectedItemIe->criticality= CriticalityE2_ignore;
2522       ranFuncRejectedItemIe->value.present = RANfunctionIDcause_ItemIEs__value_PR_RANfunctionIDcause_Item;
2523       ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID = ranFunRejectedList[ranFuncIdx].id;
2524       fillE2FailureCause(&ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.cause, CauseE2_PR_ricService,\
2525             CauseE2RICservice_ran_function_not_supported);
2526    }
2527    
2528    return ROK;
2529 }
2530
2531 /*******************************************************************
2532  *
2533  * @brief build and send the ric service update Acknowledge 
2534  *
2535  * @details
2536  *
2537  *    Function : BuildAndSendRicServiceUpdateAcknowledge
2538  *
2539  * Functionality: build and send the ric service update Acknowledge 
2540  * @return ROK     - success
2541  *         RFAILED - Acknowledge
2542  *
2543  ******************************************************************/
2544
2545 uint8_t BuildAndSendRicServiceUpdateAcknowledge(DuDb *duDb, int8_t transId, RicTmpRanFunList ricRanFuncList)
2546 {
2547    E2AP_PDU_t         *e2apMsg = NULL;
2548    asn_enc_rval_t     encRetVal;
2549    uint8_t  arrIdx=0, elementCnt=0, ret=RFAILED;;
2550    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
2551
2552    DU_LOG("\nINFO   -->  E2AP : Building Ric service update Acknowledge\n");
2553    while(true)
2554    {
2555       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2556       if(e2apMsg == NULLP)
2557       {
2558          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2559          break;
2560       }
2561       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
2562       RIC_ALLOC(e2apMsg->choice.successfulOutcome , sizeof(struct SuccessfulOutcomeE2));
2563       if(e2apMsg->choice.successfulOutcome == NULLP)
2564       {
2565          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2566          break;
2567       }
2568
2569       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
2570       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
2571       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge;
2572       ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
2573
2574       elementCnt = 1;
2575       if(ricRanFuncList.numOfRanFunAccepted)
2576          elementCnt++;
2577       if(ricRanFuncList.numOfRanFuneRejected)
2578          elementCnt++;
2579       
2580
2581       ricServiceUpdateAck->protocolIEs.list.count = elementCnt;
2582       ricServiceUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateAcknowledge_IEs_t*);
2583
2584       RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
2585       if(ricServiceUpdateAck->protocolIEs.list.array == NULLP)
2586       {
2587          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2588          break;
2589       }
2590
2591       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2592       {
2593          RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t));
2594          if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
2595          {
2596             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2597             break;
2598          }
2599       }
2600       if(arrIdx<elementCnt)
2601       {
2602          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2603          break;
2604       }
2605
2606       /* Trans Id */
2607       arrIdx = 0;
2608       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2609       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2610       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_TransactionID;
2611       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
2612
2613       if(ricRanFuncList.numOfRanFunAccepted)
2614       {
2615          /* Accepted RAN function List */
2616          arrIdx++;
2617          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
2618          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2619          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsID_List;
2620          if(BuildRanFunctionAcceptedList(duDb, ricRanFuncList.numOfRanFunAccepted, ricRanFuncList.ranFunAcceptedList,\
2621          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceUpdate)!=ROK)       
2622          {
2623             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
2624             break;         
2625          }
2626       }
2627       
2628       if(ricRanFuncList.numOfRanFuneRejected)
2629       {
2630          /* RAN Functions Rejected List */
2631          arrIdx++;
2632          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsRejected;
2633          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2634          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsIDcause_List;
2635          if(BuildRanFunctionRejectedList(ricRanFuncList.numOfRanFuneRejected, ricRanFuncList.ranFunRejectedList, \
2636          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List)!=ROK)       
2637          {
2638             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function rejected list");
2639             break;         
2640          }
2641       }
2642       
2643       
2644       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2645       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2646       encBufSize = 0;
2647       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2648
2649       /* Check encode results */
2650       if(encRetVal.encoded == ENCODE_FAIL)
2651       {
2652          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update Acknowledge structure (at %s)\n",\
2653                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2654          break;
2655       }
2656       else
2657       {
2658          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Acknowledge\n");
2659          for(int i=0; i< encBufSize; i++)
2660          {
2661             DU_LOG("%x",encBuf[i]);
2662          }
2663       }
2664
2665       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
2666       {
2667          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update ack failed");
2668          break;
2669       }
2670       ret =ROK;
2671       break;
2672    }
2673    FreeRicServiceUpdateAck(e2apMsg);
2674    return ret; 
2675 }
2676
2677 /*******************************************************************
2678  *
2679  * @brief process the RIC service update 
2680  *
2681  * @details
2682  *
2683  *    Function : ProcRicserviceUpdate 
2684  *
2685  * Functionality: process the RIC service update 
2686  *
2687  * @return ROK     - success
2688  *         RFAILED - failure
2689  *
2690  ******************************************************************/
2691
2692 void ProcRicServiceUpdate(uint32_t duId, RICserviceUpdate_t *ricServiceUpdate)
2693 {
2694    RicTmpRanFunList ricRanFuncList;
2695    DuDb    *duDb = NULLP;
2696    int8_t transId =-1;
2697    uint8_t duIdx = 0, elementCnt =0, arrIdx = 0; 
2698    uint16_t ranFuncIdx = 0, failedRanFuncCount=0, recvdRanFuncCount=0;
2699    RANfunction_ItemIEs_t *ranFuncItemIe =NULL;
2700    RANfunction_Item_t  *ranFuncItem =NULL;
2701    RANfunctionID_Item_t  *ranFuncIdItem=NULL;
2702    RANfunctions_List_t *ranFuncList=NULL;
2703    RANfunctionsID_List_t *deleteList=NULL;
2704    RANfunctionID_ItemIEs_t *delRanFuncItem=NULL;
2705
2706    SEARCH_DU_DB(duIdx, duId, duDb); 
2707    if(duDb == NULLP)
2708    {
2709       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
2710       return;
2711    }
2712    memset(&ricRanFuncList, 0, sizeof(RicTmpRanFunList)); 
2713
2714    if(!ricServiceUpdate)
2715    {
2716       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate pointer is null"); 
2717       return;
2718    }
2719
2720    if(!ricServiceUpdate->protocolIEs.list.array)      
2721    {
2722       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array pointer is null");
2723       return;
2724    }
2725    elementCnt = ricServiceUpdate->protocolIEs.list.count;
2726    for(arrIdx=0; arrIdx<ricServiceUpdate->protocolIEs.list.count; arrIdx++)
2727    {
2728       if(!ricServiceUpdate->protocolIEs.list.array[arrIdx])
2729       {
2730          DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array idx %d pointer is null",arrIdx);
2731          return;
2732       }
2733
2734       switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
2735       {
2736          case ProtocolIE_IDE2_id_TransactionID:
2737             {
2738                transId = ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
2739
2740                if(transId < 0 || transId > 255)
2741                {
2742                   DU_LOG("\nERROR  -->  E2AP : Received invalid transId %d",transId);
2743                   return;
2744                }
2745                break;
2746             }
2747
2748          case ProtocolIE_IDE2_id_RANfunctionsAdded:
2749             {
2750                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
2751
2752                if(ranFuncList->list.array)
2753                {
2754                   for(ranFuncIdx=0;ranFuncIdx<ranFuncList->list.count; ranFuncIdx++)
2755                   {
2756                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx]; 
2757                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
2758
2759                      /* Adding the ran function in temporary list */
2760                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
2761                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
2762                      ricRanFuncList.numOfRanFunAccepted++;
2763
2764                      /* Adding the new ran function in DB*/
2765                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].id = ranFuncItem->ranFunctionID;
2766                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
2767                      duDb->numOfRanFunction++;
2768
2769                      /* Calculating total number of ran fuctions which are received for addition */
2770                      recvdRanFuncCount++;
2771                   }
2772                }
2773                break;
2774             }
2775
2776          case ProtocolIE_IDE2_id_RANfunctionsModified:
2777             {
2778
2779                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List; 
2780                if(ranFuncList->list.array)
2781                {
2782                   for(ranFuncIdx = 0; ranFuncIdx< ranFuncList->list.count; ranFuncIdx++)
2783                   {
2784                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx];
2785                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
2786                      if(duDb->ranFunction[ranFuncItem->ranFunctionID-1].id != ranFuncItem->ranFunctionID)
2787                      {
2788                         /* Calculating total number of ran fuctions which are not present */
2789                         failedRanFuncCount++;
2790
2791                         /* Adding the ran function in temporary list */
2792                         ricRanFuncList.ranFunRejectedList[ricRanFuncList.numOfRanFuneRejected].id =  ranFuncItem->ranFunctionID; 
2793                         ricRanFuncList.numOfRanFuneRejected++;
2794                      }
2795                      else
2796                      {
2797
2798                         /* Adding the ran function in temporary list */
2799                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
2800                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
2801                         ricRanFuncList.numOfRanFunAccepted++;
2802
2803                         /* Updating the new ran function in DB*/
2804                         duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
2805                      }
2806                      /* Calculating total number of ran fuctions which are received for modification */
2807                      recvdRanFuncCount++;
2808                   }
2809                }
2810                break;
2811             }
2812          case ProtocolIE_IDE2_id_RANfunctionsDeleted:
2813             {
2814
2815                deleteList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List; 
2816                if(deleteList->list.array)
2817                {
2818                   for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
2819                   {
2820                      delRanFuncItem  = (RANfunctionID_ItemIEs_t*) deleteList->list.array[ranFuncIdx];
2821                      ranFuncIdItem = &delRanFuncItem->value.choice.RANfunctionID_Item;
2822                      if(duDb->ranFunction[ranFuncIdItem->ranFunctionID-1].id == ranFuncIdItem->ranFunctionID)
2823                      {
2824                         memset(&duDb->ranFunction[ranFuncIdItem->ranFunctionID-1], 0, sizeof(RanFunction));
2825                         duDb->numOfRanFunction--; 
2826                      }
2827
2828                      /* Calculating total number of ran fuctions which are received for deletion */
2829                      recvdRanFuncCount++;
2830                   }
2831                }
2832                break;
2833             }
2834
2835          default:
2836             {
2837                DU_LOG("\nERROR  -->  E2AP : IE [%ld] is not supported",ricServiceUpdate->protocolIEs.list.array[arrIdx]->id);
2838                break;
2839             }
2840       }
2841    }
2842    
2843    /* Sending RIC Service Update Failed if all RAN Functions received fail or if any IE processing fails
2844     * Else sending RIC Service Update Acknowledge */  
2845    if((elementCnt > arrIdx) ||((recvdRanFuncCount > 0) && (recvdRanFuncCount == failedRanFuncCount)))
2846    {
2847       if(BuildAndSendRicServiceUpdateFailure(duDb->duId, transId, CauseE2_PR_misc, CauseE2Misc_unspecified) != ROK)
2848       {
2849          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update Failure");
2850          return;
2851       }
2852    }
2853    else
2854    {
2855       if(BuildAndSendRicServiceUpdateAcknowledge(duDb, transId, ricRanFuncList) != ROK)
2856       {
2857          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update acknowledge");
2858          return;
2859       }
2860    }
2861 }
2862
2863 /*******************************************************************
2864  *
2865  * @brief Processing RIC subscription failure from DU
2866  *
2867  * @details
2868  *
2869  *    Function : ProcRicSubscriptionFailure
2870  *
2871  * Functionality: Processing RIC subscription failure from DU
2872  *
2873  * @param  ID of DU from which message was sent
2874  *         RIC Subscription failure message
2875  * @return ROK     - success
2876  *         RFAILED - failure
2877  *
2878  ******************************************************************/
2879 uint8_t ProcRicSubscriptionFailure(uint32_t duId, RICsubscriptionFailure_t *ricSubscriptionFailure)
2880 {
2881    uint8_t ieIdx = 0, duIdx = 0, subsIdx = 0;
2882    uint8_t ranFuncId = 0;
2883    bool   ricReqIdDecoded = false;
2884    DuDb    *duDb = NULLP;
2885    RanFunction *ranFuncDb = NULLP;
2886    RicRequestId ricReqId;
2887    RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
2888
2889    DU_LOG("\nINFO  -->  E2AP : Received RIC subscription failure");
2890
2891    SEARCH_DU_DB(duIdx, duId, duDb);
2892    if(duDb == NULLP)
2893    {
2894       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
2895       return RFAILED;
2896    }
2897
2898    memset(&ricReqId, 0, sizeof(RicRequestId));
2899    if(ricSubscriptionFailure)
2900    {
2901       if(ricSubscriptionFailure->protocolIEs.list.array)
2902       {
2903          for(ieIdx=0; ieIdx<ricSubscriptionFailure->protocolIEs.list.count; ieIdx++)
2904          {
2905             if(ricSubscriptionFailure->protocolIEs.list.array[ieIdx])
2906             {
2907                ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[ieIdx];
2908                switch(ricSubscriptionFailure->protocolIEs.list.array[ieIdx]->id)
2909                {
2910                   case ProtocolIE_IDE2_id_RICrequestID:
2911                   {
2912                      ricReqId.requestorId = ricSubsFailIe->value.choice.RICrequestID.ricRequestorID;
2913                      ricReqId.instanceId = ricSubsFailIe->value.choice.RICrequestID.ricInstanceID;
2914                      ricReqIdDecoded = true;
2915                      break;
2916                   }
2917                   case ProtocolIE_IDE2_id_RANfunctionID:
2918                   {
2919                      ranFuncId = ricSubsFailIe->value.choice.RANfunctionID;
2920                      if(duDb->ranFunction[ranFuncId-1].id == ranFuncId)
2921                      {
2922                         ranFuncDb = &duDb->ranFunction[ranFuncId-1];
2923                      }
2924                      break; 
2925                   }
2926                   case ProtocolIE_IDE2_id_CauseE2:
2927                   default:
2928                      /* No handling required as of now since this is a stub */
2929                      break;
2930
2931                }
2932             }
2933          }
2934
2935          /* Remove subscription entry from RAN Function */
2936          if(ranFuncDb && ricReqIdDecoded)
2937          {
2938             for(subsIdx = 0; subsIdx < ranFuncDb->numOfSubscription; subsIdx++)
2939             {
2940                if((ranFuncDb->subscriptionList[subsIdx].requestId.requestorId == ricReqId.requestorId) &&
2941                      (ranFuncDb->subscriptionList[subsIdx].requestId.instanceId == ricReqId.instanceId))
2942                {
2943                   memset(&ranFuncDb->subscriptionList[subsIdx], 0, sizeof(RicSubscription));
2944                   break;
2945                }
2946             }
2947          }
2948       }
2949    }
2950    return ROK;
2951 }
2952
2953 /*******************************************************************
2954 *
2955 * @brief Handles received E2AP message and sends back response  
2956 *
2957 * @details
2958 *
2959 *    Function : E2APMsgHdlr
2960 *
2961 *    Functionality:
2962 *         - Decodes received E2AP control message
2963 *         - Prepares response message, encodes and sends to SCTP
2964 *
2965 * @params[in] 
2966 * @return ROK     - success
2967 *         RFAILED - failure
2968 *
2969 * ****************************************************************/
2970 void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
2971 {
2972    int             i;
2973    char            *recvBuf;
2974    MsgLen          copyCnt;
2975    MsgLen          recvBufLen;
2976    E2AP_PDU_t      *e2apMsg;
2977    asn_dec_rval_t  rval; /* Decoder return value */
2978    E2AP_PDU_t      e2apasnmsg ;
2979  
2980    DU_LOG("\nINFO  -->  E2AP : Received E2AP message buffer");
2981    ODU_PRINT_MSG(mBuf, 0,0);
2982  
2983    /* Copy mBuf into char array to decode it */
2984    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
2985    RIC_ALLOC(recvBuf, (Size)recvBufLen);
2986
2987    if(recvBuf == NULLP)
2988    {
2989       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
2990       return;
2991    }
2992    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
2993    {
2994       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
2995       return;
2996    }
2997
2998    DU_LOG("\nDEBUG  -->  E2AP : Received flat buffer to be decoded : ");
2999    for(i=0; i< recvBufLen; i++)
3000    {
3001         DU_LOG("%x",recvBuf[i]);
3002    }
3003
3004    /* Decoding flat buffer into E2AP messsage */
3005    e2apMsg = &e2apasnmsg;
3006    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
3007
3008    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
3009    RIC_FREE(recvBuf, (Size)recvBufLen);
3010
3011    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
3012    {
3013       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
3014       return;
3015    }
3016    DU_LOG("\n");
3017    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3018
3019    switch(e2apMsg->present)
3020    {
3021       case E2AP_PDU_PR_initiatingMessage:
3022          {
3023             switch(e2apMsg->choice.initiatingMessage->value.present)
3024             {
3025                case InitiatingMessageE2__value_PR_E2setupRequest:
3026                   {
3027                      DU_LOG("\nINFO  -->  E2AP : E2 setup request received");
3028                      ProcE2SetupReq(duId, &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest);
3029                      break;
3030                   }
3031                case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate:
3032                   {
3033                      DU_LOG("\nINFO  -->  E2AP : E2 node config update received");
3034                      BuildAndSendE2NodeConfigUpdateAck(*duId);
3035                      break;
3036                   }
3037                case InitiatingMessageE2__value_PR_ResetRequestE2:
3038                   {
3039                      DU_LOG("\nINFO  -->  E2AP : E2 Reset Request received");
3040                      ProcE2ResetReq(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2);
3041                      break;
3042                   }
3043                case InitiatingMessageE2__value_PR_RICindication:
3044                   {
3045                      DU_LOG("\nINFO  -->  E2AP : RIC Indication Acknowledged");
3046                      break;
3047                   }
3048                case InitiatingMessageE2__value_PR_RICserviceUpdate:
3049                   {
3050                      DU_LOG("\nINFO  -->  E2AP : RIC Service update received");
3051                      ProcRicServiceUpdate(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate);
3052                      break;
3053                   }
3054
3055                default:
3056                   {
3057                      DU_LOG("\nERROR  -->  E2AP : Invalid type of intiating message [%d]", \
3058                         e2apMsg->choice.initiatingMessage->value.present);
3059                      return;
3060                   }
3061             }/* End of switch(initiatingMessage) */
3062             break;
3063          }
3064       case E2AP_PDU_PR_successfulOutcome: 
3065          {
3066             switch(e2apMsg->choice.successfulOutcome->value.present)
3067             {
3068                case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:  
3069                   {
3070                      ProcRicSubscriptionResponse(*duId, \
3071                         &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse);
3072                      break;
3073                   }
3074                default:
3075                   {
3076                      DU_LOG("\nERROR  -->  E2AP : Invalid type of successfulOutcome message [%d]", \
3077                         e2apMsg->choice.successfulOutcome->value.present);
3078                      return;
3079                   }
3080                   break;
3081             }
3082             break; 
3083          }
3084          case E2AP_PDU_PR_unsuccessfulOutcome:
3085          {
3086             switch(e2apMsg->choice.successfulOutcome->value.present)
3087             {
3088                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure:
3089                   {
3090                      ProcRicSubscriptionFailure(*duId, \
3091                         &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure);
3092                      break;
3093                   }
3094                default:
3095                   {
3096                      DU_LOG("\nERROR  -->  E2AP : Invalid type of unsuccessfulOutcome message [%d]", \
3097                         e2apMsg->choice.unsuccessfulOutcome->value.present);
3098                      return;
3099                   }
3100             }
3101             break;
3102          }
3103       default:
3104          {
3105             DU_LOG("\nERROR  -->  E2AP : Invalid type message type ");
3106             return;
3107          }
3108
3109    }/* End of switch(e2apMsg->present) */
3110 } /* End of E2APMsgHdlr */
3111
3112
3113 /**********************************************************************
3114   End of file
3115  **********************************************************************/