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