6060f9c2d6c3cd6d20f000ed9d6dfe07be11f17b
[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 *ranFuncAddedList;
174    E2setupResponse_t  *e2SetupRsp;
175    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItemIe;
176    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList;
177    E2nodeComponentInterfaceF1_t *f1InterfaceInfo;
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                      ranFuncAddedList= &e2SetupRsp->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
193                      if(ranFuncAddedList->list.array)
194                      {
195                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
196                         {
197                            if(ranFuncAddedList->list.array[ranFuncIdx])
198                            {
199                               RIC_FREE(ranFuncAddedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
200                            }
201                         }
202                         RIC_FREE(ranFuncAddedList->list.array, ranFuncAddedList->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 added list
316  *
317  * @details
318  *
319  *    Function : BuildRanFunctionAddedList
320  *
321  *    Functionality: Build RAN function added 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 added 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 BuildRanFunctionAddedList(DuDb *duDb, uint8_t count, RanFunction *ranFunToBeAdded, RANfunctionsID_List_t *ranFuncAddedList, uint8_t procedureCode)
339 {
340    uint8_t ranFuncIdx = 0;
341    RANfunctionID_ItemIEs_t *ranFuncAddedItemIe;
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       ranFuncAddedList->list.count = duDb->numOfRanFunction;
351    else
352       ranFuncAddedList->list.count = count;
353    
354    ranFuncAddedList->list.size = ranFuncAddedList->list.count*sizeof(RANfunctionID_ItemIEs_t*);
355    RIC_ALLOC(ranFuncAddedList->list.array, ranFuncAddedList->list.size);
356    if(ranFuncAddedList->list.array)
357    {
358       for(ranFuncIdx = 0; ranFuncIdx< ranFuncAddedList->list.count; ranFuncIdx++)
359       {
360          RIC_ALLOC(ranFuncAddedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
361          if(ranFuncAddedList->list.array[ranFuncIdx] == NULLP)
362          {
363             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function added list array item");
364             return RFAILED;
365          }
366          ranFuncAddedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAddedList->list.array[ranFuncIdx];
367          ranFuncAddedItemIe->id = ProtocolIE_IDE2_id_RANfunctionID_Item;
368          ranFuncAddedItemIe->criticality= CriticalityE2_ignore;
369          ranFuncAddedItemIe->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             ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionID = duDb->ranFunction[ranFuncIdx].id;
374             ranFuncAddedItemIe->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             ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionID = ranFunToBeAdded[ranFuncIdx].id;
380             ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision= ranFunToBeAdded[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(BuildRanFunctionAddedList(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 *ranFuncAddedList;
1526    RICserviceQuery_t *ricServiceQuery;
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                            ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
1544                            if(ranFuncAddedList->list.array)
1545                            {
1546                               for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
1547                               {
1548                                  RIC_FREE(ranFuncAddedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
1549                               }
1550                               RIC_FREE(ranFuncAddedList->list.array, ranFuncAddedList->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(BuildRanFunctionAddedList(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 Handles received E2AP message and sends back response  
1705 *
1706 * @details
1707 *
1708 *    Function : E2APMsgHdlr
1709 *
1710 *    Functionality:
1711 *         - Decodes received E2AP control message
1712 *         - Prepares response message, encodes and sends to SCTP
1713 *
1714 * @params[in] 
1715 * @return ROK     - success
1716 *         RFAILED - failure
1717 *
1718 * ****************************************************************/
1719 void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
1720 {
1721    int             i;
1722    char            *recvBuf;
1723    MsgLen          copyCnt;
1724    MsgLen          recvBufLen;
1725    E2AP_PDU_t      *e2apMsg;
1726    asn_dec_rval_t  rval; /* Decoder return value */
1727    E2AP_PDU_t      e2apasnmsg ;
1728  
1729    DU_LOG("\nINFO  -->  E2AP : Received E2AP message buffer");
1730    ODU_PRINT_MSG(mBuf, 0,0);
1731  
1732    /* Copy mBuf into char array to decode it */
1733    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
1734    RIC_ALLOC(recvBuf, (Size)recvBufLen);
1735
1736    if(recvBuf == NULLP)
1737    {
1738       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
1739       return;
1740    }
1741    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
1742    {
1743       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
1744       return;
1745    }
1746
1747    DU_LOG("\nDEBUG  -->  E2AP : Received flat buffer to be decoded : ");
1748    for(i=0; i< recvBufLen; i++)
1749    {
1750         DU_LOG("%x",recvBuf[i]);
1751    }
1752
1753    /* Decoding flat buffer into E2AP messsage */
1754    e2apMsg = &e2apasnmsg;
1755    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
1756
1757    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
1758    RIC_FREE(recvBuf, (Size)recvBufLen);
1759
1760    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
1761    {
1762       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
1763       return;
1764    }
1765    DU_LOG("\n");
1766    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1767
1768    switch(e2apMsg->present)
1769    {
1770       case E2AP_PDU_PR_initiatingMessage:
1771          {
1772             switch(e2apMsg->choice.initiatingMessage->value.present)
1773             {
1774                case InitiatingMessageE2__value_PR_E2setupRequest:
1775                   {
1776                      DU_LOG("\nINFO  -->  E2AP : E2 setup request received");
1777                      ProcE2SetupReq(duId, &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest);
1778                      break;
1779                   }
1780                case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate:
1781                   {
1782                      DU_LOG("\nINFO  -->  E2AP : E2 node config update received");
1783                      BuildAndSendE2NodeConfigUpdateAck(*duId);
1784                      break;
1785                   }
1786                case InitiatingMessageE2__value_PR_ResetRequestE2:
1787                   {
1788                      DU_LOG("\nINFO  -->  E2AP : E2 Reset Request received");
1789                      ProcE2ResetReq(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2);
1790                      break;
1791                   }
1792                case InitiatingMessageE2__value_PR_RICindication:
1793                   {
1794                      DU_LOG("\nINFO  -->  E2AP : RIC Indication Acknowledged");
1795                      break;
1796                   }
1797                default:
1798                   {
1799                      DU_LOG("\nERROR  -->  E2AP : Invalid type of intiating message [%d]",e2apMsg->choice.initiatingMessage->value.present);
1800                      return;
1801                   }
1802             }/* End of switch(initiatingMessage) */
1803             break;
1804          }
1805       case E2AP_PDU_PR_successfulOutcome: 
1806          {
1807             switch(e2apMsg->choice.successfulOutcome->value.present)
1808             {
1809                case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:  
1810                   {
1811                      ProcRicSubscriptionResponse(*duId);
1812                      break;
1813                   }
1814                default:
1815                   {
1816                      DU_LOG("\nERROR  -->  E2AP : Invalid type of successfulOutcome message [%d]",e2apMsg->choice.successfulOutcome->value.present);
1817                      return;
1818                   }
1819                   break;
1820             }
1821             break; 
1822          }
1823       default:
1824          {
1825             DU_LOG("\nERROR  -->  E2AP : Invalid type message type ");
1826             return;
1827          }
1828
1829    }/* End of switch(e2apMsg->present) */
1830 } /* End of E2APMsgHdlr */
1831
1832
1833 /**********************************************************************
1834   End of file
1835  **********************************************************************/