ec6e0db76ded53b0cb1927dbf9c9424ece79609f
[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 *
44 * @brief Sends E2 msg over SCTP
45 *
46 * @details
47 *
48 *    Function : SendE2APMsg
49 *
50 *    Functionality: Sends E2 msg over SCTP
51 *
52 * @params[in] Region region
53 *             Pool pool
54 * @return ROK     - success
55 *         RFAILED - failure
56 *
57 * ****************************************************************/
58
59 uint8_t SendE2APMsg(Region region, Pool pool, uint32_t duId)
60 {
61    Buffer *mBuf;
62
63    if(ODU_GET_MSG_BUF(region, pool, &mBuf) == ROK)
64    {
65       if(ODU_ADD_POST_MSG_MULT((Data *)encBuf, encBufSize, mBuf) == ROK)
66       {
67          ODU_PRINT_MSG(mBuf, 0,0);
68  
69          if(sctpSend(duId, mBuf) != ROK)
70          {
71             DU_LOG("\nERROR  -->  E2AP : SCTP Send for E2  failed");
72             ODU_PUT_MSG_BUF(mBuf);
73             return RFAILED;
74          }
75       }
76       else
77       {
78          DU_LOG("\nERROR  -->  E2AP : ODU_ADD_POST_MSG_MULT failed");
79          ODU_PUT_MSG_BUF(mBuf);
80          return RFAILED;
81       }
82       ODU_PUT_MSG_BUF(mBuf);
83    }
84    else
85    {
86       DU_LOG("\nERROR  -->  E2AP : Failed to allocate memory");
87       return RFAILED;
88    }
89  
90    return ROK;
91 } /* SendE2APMsg */
92
93 /*******************************************************************
94  *
95  * @brief Builds Global RIC Id Params
96  *
97  * @details
98  *
99  *    Function : BuildGlobalRicId
100  *
101  *    Functionality: Building the Plmn and ric id
102  *
103  * @params[in] GlobalRIC_ID_t *ricId
104  * @return ROK     - success
105  *         RFAILED - failure
106  *
107  * ****************************************************************/
108
109 uint8_t BuildGlobalRicId(GlobalRIC_ID_t *ricId)
110 {
111    uint8_t unused = 4;
112    uint8_t byteSize = 3;
113    uint8_t ricVal= 1;
114    if(ricId != NULLP)
115    {
116       ricId->pLMN_Identity.size = byteSize * sizeof(uint8_t);
117       RIC_ALLOC(ricId->pLMN_Identity.buf,  ricId->pLMN_Identity.size);
118       buildPlmnId(ricCb.ricCfgParams.plmn , ricId->pLMN_Identity.buf);
119       /* fill ric Id */
120       ricId->ric_ID.size = byteSize * sizeof(uint8_t);
121       RIC_ALLOC(ricId->ric_ID.buf, ricId->ric_ID.size);
122       fillBitString(&ricId->ric_ID, unused, byteSize, ricVal);
123    }
124    return ROK;   
125 }
126
127 /*******************************************************************
128  *
129  * @brief deallocate the memory allocated in E2SetupResponse
130  *
131  * @details
132  *
133  *    Function : FreeE2SetupRsp 
134  *
135  *    Functionality: deallocate the memory allocated in E2SetupResponse 
136  *
137  * @params[in] E2AP_PDU_t *e2apMsg
138  *
139  * @return void
140  * ****************************************************************/
141 void FreeE2SetupRsp(E2AP_PDU_t *e2apMsg)
142 {
143    uint8_t arrIdx = 0, e2NodeConfigIdx=0, ranFuncIdx=0;
144    RANfunctionsID_List_t *ranFuncAddedList;
145    E2setupResponse_t  *e2SetupRsp;
146    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItemIe;
147    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList;
148    E2nodeComponentInterfaceF1_t *f1InterfaceInfo;
149    
150    if(e2apMsg)
151    {
152       if(e2apMsg->choice.successfulOutcome)
153       {
154          e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
155          if(e2SetupRsp->protocolIEs.list.array)
156          {
157             for(arrIdx=0; arrIdx<e2SetupRsp->protocolIEs.list.count; arrIdx++)
158             {
159                switch(e2SetupRsp->protocolIEs.list.array[arrIdx]->id)
160                {
161                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
162                   {
163                      ranFuncAddedList= &e2SetupRsp->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
164                      if(ranFuncAddedList->list.array)
165                      {
166                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAddedList->list.count; ranFuncIdx++)
167                         {
168                            if(ranFuncAddedList->list.array[arrIdx])
169                            {
170                               RIC_FREE(ranFuncAddedList->list.array[arrIdx], sizeof(RANfunction_ItemIEs_t));
171                            }
172                         }
173                         RIC_FREE(ranFuncAddedList->list.array, ranFuncAddedList->list.size);
174                      }
175                      break;
176                   }
177                   case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
178                   {
179                      e2NodeConfigAdditionAckList =&e2SetupRsp->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
180                      if(e2NodeConfigAdditionAckList->list.count)
181                      {
182                         for(e2NodeConfigIdx=0; e2NodeConfigIdx<e2NodeConfigAdditionAckList->list.count; e2NodeConfigIdx++)
183                         {
184                            e2NodeAddAckItemIe = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[e2NodeConfigIdx];
185                            if(e2NodeAddAckItemIe)
186                            {
187                               f1InterfaceInfo = e2NodeAddAckItemIe->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1; 
188                               if(f1InterfaceInfo)
189                               {
190                                  RIC_FREE(f1InterfaceInfo->gNB_DU_ID.buf, f1InterfaceInfo->gNB_DU_ID.size);
191                                  RIC_FREE(f1InterfaceInfo, sizeof(E2nodeComponentInterfaceF1_t));
192                               }
193                               RIC_FREE(e2NodeAddAckItemIe, sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
194                            }
195                         }
196                         RIC_FREE(e2NodeConfigAdditionAckList->list.array, e2NodeConfigAdditionAckList->list.size);
197                      }
198                      break;
199                   }
200                }
201                RIC_FREE(e2SetupRsp->protocolIEs.list.array[arrIdx], sizeof(E2setupResponseIEs_t)); 
202             }
203             RIC_FREE(e2SetupRsp->protocolIEs.list.array, e2SetupRsp->protocolIEs.list.size);
204          }
205          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
206       }
207       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
208    }
209 }
210
211 /*******************************************************************
212  *
213  * @brief Build E2node Component config addition ack list
214  *
215  * @details
216  *
217  *    Function :  BuildE2nodeComponentConfigAdditionAck
218  *
219  *    Functionality: deallocate the memory allocated in E2SetupResponse 
220  *
221  * @params[in] E2nodeComponentConfigAdditionAck_List_t
222  * *e2NodeConfigAdditionAckList
223  *
224  * @return ROK - success
225  *         RFAILED - failure
226  * ****************************************************************/
227
228 uint8_t BuildE2nodeComponentConfigAdditionAck(E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList, DuDb *duDb)
229 {
230    uint8_t arrIdx = 0;
231    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem;
232    
233    e2NodeConfigAdditionAckList->list.count = 1;
234    e2NodeConfigAdditionAckList->list.size = e2NodeConfigAdditionAckList->list.count * sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t*);
235    RIC_ALLOC(e2NodeConfigAdditionAckList->list.array, e2NodeConfigAdditionAckList->list.size);
236    if(e2NodeConfigAdditionAckList->list.array == NULLP)
237    {
238       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
239       return RFAILED;
240    }
241
242    for(arrIdx = 0; arrIdx< e2NodeConfigAdditionAckList->list.count; arrIdx++)
243    {
244       RIC_ALLOC(e2NodeConfigAdditionAckList->list.array[arrIdx], sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
245       if(e2NodeConfigAdditionAckList->list.array[arrIdx] == NULLP)
246       {
247          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
248          return RFAILED;
249       }
250    }
251    e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[0];
252    e2NodeAddAckItem->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck_Item;
253    e2NodeAddAckItem->criticality = CriticalityE2_reject;
254    e2NodeAddAckItem->value.present = E2nodeComponentConfigAdditionAck_ItemIEs__value_PR_E2nodeComponentConfigAdditionAck_Item;
255    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentInterfaceType = duDb->e2NodeComponent.interfaceType;
256
257    /* >E2 Node Component ID */
258    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1;
259    RIC_ALLOC(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\
260          sizeof(E2nodeComponentInterfaceF1_t));
261    if(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1 == NULLP)
262    {
263       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
264       return RFAILED;
265    }
266    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t);
267    RIC_ALLOC(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
268          e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
269
270    if(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP)
271    {
272       DU_LOG("\nERROR  -->list.  E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
273       return RFAILED;
274    }
275    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]  = duDb->e2NodeComponent.componentId;
276    
277    /* >E2 Node Component Configuration Acknowledge*/
278    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentConfigurationAck.updateOutcome = \
279    E2nodeComponentConfigurationAck__updateOutcome_success;
280    
281    return ROK;  
282 }
283
284 /*******************************************************************
285  *
286  * @brief Build RAN function added list
287  *
288  * @details
289  *
290  *    Function : BuildRanFunctionAddedList
291  *
292  *    Functionality: Build RAN function added list 
293  *
294  * @params[in] DuDb *duDb, RANfunctionsID_List_t *ranFuncAddedList 
295  *
296  * @return ROK - success
297  *         RFAILED - failure
298  * ****************************************************************/
299
300 uint8_t BuildRanFunctionAddedList(DuDb *duDb, RANfunctionsID_List_t *ranFuncAddedList)
301 {
302    uint8_t ranFuncIdx = 0;
303    RANfunctionID_ItemIEs_t *ranFuncAddedItemIe;
304
305    ranFuncAddedList->list.count = duDb->numOfRanFunction;
306    ranFuncAddedList->list.size = ranFuncAddedList->list.count*sizeof(RANfunctionID_ItemIEs_t*);
307    RIC_ALLOC(ranFuncAddedList->list.array, ranFuncAddedList->list.size);
308    if(ranFuncAddedList->list.array)
309    {
310       for(ranFuncIdx = 0; ranFuncIdx< ranFuncAddedList->list.count; ranFuncIdx++)
311       {
312          RIC_ALLOC(ranFuncAddedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
313          if(ranFuncAddedList->list.array[ranFuncIdx] == NULLP)
314          {
315             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function added list array item");
316             return RFAILED;
317          }
318          ranFuncAddedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAddedList->list.array[ranFuncIdx];
319          ranFuncAddedItemIe->id = ProtocolIE_IDE2_id_RANfunctionID_Item;
320          ranFuncAddedItemIe->criticality= CriticalityE2_ignore;
321          ranFuncAddedItemIe->value.present = RANfunctionID_ItemIEs__value_PR_RANfunctionID_Item;
322          ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionID =duDb->ranFunction[ranFuncIdx].id;
323          ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision=duDb->ranFunction[ranFuncIdx].revisionCounter;
324       }
325    }
326    else
327    {
328       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function added list array");
329       return RFAILED;
330    }
331    return ROK;
332 }
333
334 /*******************************************************************
335  *
336  * @brief Builds and sends the E2SetupResponse
337  *
338  * @details
339  *
340  *    Function : BuildAndSendE2SetupRsp
341  *
342  *    Functionality: Constructs the F1SetupResponse message and sends
343  *                   it back to the DU through SCTP.
344  *
345  * @params[in] void **buf,Buffer to which encoded pattern is written into
346  * @params[in] int *size,size of buffer
347  *
348  * @return ROK     - success
349  *         RFAILED - failure
350  *
351  * ****************************************************************/
352 uint8_t BuildAndSendE2SetupRsp(DuDb *duDb, uint8_t transId)
353 {
354    E2AP_PDU_t         *e2apMsg = NULL;
355    E2setupResponse_t  *e2SetupRsp;
356    asn_enc_rval_t     encRetVal; 
357    uint8_t            idx;
358    uint8_t            elementCnt;
359    bool  memAllocFailed = false;
360  
361    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup Response\n");
362    while(true)
363    {
364       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); 
365       if(e2apMsg == NULLP)
366       {
367          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
368          break;
369       }
370       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
371       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
372       if(e2apMsg->choice.successfulOutcome == NULLP)
373       {
374          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
375          break;  
376       }
377
378       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
379       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
380       e2apMsg->choice.successfulOutcome->value.present = \
381                                                          SuccessfulOutcomeE2__value_PR_E2setupResponse;
382       e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
383
384       elementCnt = 4;
385       e2SetupRsp->protocolIEs.list.count = elementCnt;
386       e2SetupRsp->protocolIEs.list.size  = elementCnt * sizeof(E2setupResponseIEs_t*);
387
388       RIC_ALLOC(e2SetupRsp->protocolIEs.list.array, e2SetupRsp->protocolIEs.list.size);
389       if(e2SetupRsp->protocolIEs.list.array == NULLP)
390       {
391          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");
392          break;  
393       }
394
395       for(idx=0; idx<elementCnt; idx++)
396       {
397          RIC_ALLOC(e2SetupRsp->protocolIEs.list.array[idx], sizeof(E2setupResponseIEs_t)); 
398          if(e2SetupRsp->protocolIEs.list.array[idx] == NULLP)
399          { 
400             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");
401             memAllocFailed = true;
402             break;
403          }    
404       }
405       
406       if(memAllocFailed == true)
407       {
408           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");    
409           break;
410       }
411       /* Trans Id */
412       idx = 0;
413       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_TransactionID;
414       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
415       e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_TransactionID; 
416       e2SetupRsp->protocolIEs.list.array[idx]->value.choice.TransactionID  = transId;
417
418       /* Global RIC ID */
419       idx++;
420       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_GlobalRIC_ID;
421       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
422       e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
423                                                                E2setupResponseIEs__value_PR_GlobalRIC_ID;
424
425       if(BuildGlobalRicId(&(e2SetupRsp->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID))!=ROK)
426       {
427          DU_LOG("\nERROR  -->  E2AP : Failed to build Global Ric Id");
428          break;
429       }
430       
431       /* Accepted RAN function Id */
432       idx++;
433       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
434       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
435       e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_RANfunctionsID_List;
436       if(BuildRanFunctionAddedList(duDb, &e2SetupRsp->protocolIEs.list.array[idx]->value.choice.RANfunctionsID_List)!=ROK)
437       {
438          DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
439          break;         
440       }
441
442       /* E2 Node Component Configuration Addition Acknowledge List*/
443       idx++;
444       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck;
445       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
446       e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
447       E2setupResponseIEs__value_PR_E2nodeComponentConfigAdditionAck_List;
448       if(BuildE2nodeComponentConfigAdditionAck(&e2SetupRsp->protocolIEs.list.array[idx]->value.choice.E2nodeComponentConfigAdditionAck_List, duDb)!=ROK)
449       {
450          DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config addition ack list");
451          break;
452       }
453
454       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
455       memset(encBuf, 0, ENC_BUF_MAX_LEN);
456       encBufSize = 0;
457       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
458
459       /* Check encode results */
460       if(encRetVal.encoded == ENCODE_FAIL)
461       {
462          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupResponse structure (at %s)\n",\
463                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
464          break;   
465       } 
466       else 
467       {
468          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SetupResponse\n");
469          for(int i=0; i< encBufSize; i++)
470          {
471             DU_LOG("%x",encBuf[i]);
472          } 
473       }
474
475       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
476       {
477          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Response failed");      
478          break;   
479       }
480       break;
481    }
482
483    FreeE2SetupRsp(e2apMsg);
484    BuildAndSendRicSubscriptionReq(duDb->duId);
485    return ROK;
486 }
487
488 /*******************************************************************
489  *
490  * @brief Builds Ric Request Id
491  *
492  * @details
493  *
494  *    Function : BuildRicRequestId
495  *
496  *    Functionality: Building the Ric Request Id
497  *
498  * @params[in] RICrequestID_t *ricReqId
499  * @return ROK     - success
500  *         RFAILED - failure
501  *
502  * ****************************************************************/
503
504 uint8_t BuildRicRequestId(RICrequestID_t *ricReqId)
505 {
506
507    if(ricReqId != NULLP)
508    {
509       ricReqId->ricRequestorID = 1;
510       ricReqId->ricInstanceID  = 1;
511    }
512    return ROK;
513 }
514
515 /*******************************************************************
516  *
517  * @brief Fills Ric Action To be Setup Item
518  *
519  * @details
520  *
521  *    Function : fillSetupItems
522  *
523  *    Functionality: Filling ricAction Id, RicActionType
524  *
525  * @params[in] RICaction_ToBeSetup_Item_t *setupItems
526  * @return pointer of type RICaction_ToBeSetup_Item_t
527  *
528  * ****************************************************************/
529
530 RICaction_ToBeSetup_Item_t* fillSetupItems(RICaction_ToBeSetup_Item_t *setupItems)
531 {
532    if(setupItems != NULLP)
533    {
534       setupItems->ricActionID = 0;
535       setupItems->ricActionType = RICactionType_report;
536    }
537
538    return (setupItems);
539 }
540
541 /*******************************************************************
542  *
543  * @brief Fills RIC Subscription Details Item List
544  *
545  * @details
546  *
547  *    Function : fillSubsDetails
548  *
549  *    Functionality: Fill the RIC Subscription Details Items List
550  *
551  * @params[in] RICaction_ToBeSetup_ItemIEs_t *items
552  * @return ROK     - success
553  *         RFAILED - failure
554  *
555  * ****************************************************************/
556
557 uint8_t fillSubsDetails(RICaction_ToBeSetup_ItemIEs_t *items)
558 {
559    if(items != NULLP)
560    {
561       items->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item;
562       items->criticality   =  CriticalityE2_ignore;
563       items->value.present =  RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
564       fillSetupItems(&(items->value.choice.RICaction_ToBeSetup_Item));
565    }
566    return ROK;
567 }
568
569 /*******************************************************************
570  *
571  * @brief builds RIC Subscription Details
572  *
573  * @details
574  *
575  *    Function : BuildsRicSubsDetails
576  *
577  *    Functionality: Builds the RIC Subscription Details
578  *
579  * @params[in] RICsubscriptionDetails_t *subsDetails
580  * @return ROK     - success
581  *         RFAILED - failure
582  *
583  * ****************************************************************/
584
585 uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails)
586 {
587
588    uint8_t elementCnt;
589
590    if(subsDetails != NULLP)
591    {
592       /* Octet string to be build here */
593       /* Sending PLMN as Octect string */
594       uint8_t byteSize = 3;
595       subsDetails->ricEventTriggerDefinition.size = byteSize * sizeof(uint8_t);
596       RIC_ALLOC(subsDetails->ricEventTriggerDefinition.buf,  subsDetails->ricEventTriggerDefinition.size);
597       buildPlmnId(ricCb.ricCfgParams.plmn, subsDetails->ricEventTriggerDefinition.buf);
598       elementCnt = 1;
599       subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt;
600       subsDetails->ricAction_ToBeSetup_List.list.size = \
601                       elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t);
602       RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, \
603                 subsDetails->ricAction_ToBeSetup_List.list.size);
604       if(subsDetails->ricAction_ToBeSetup_List.list.array  == NULLP)
605       {
606          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICactionToBeSetup Items failed");
607          return RFAILED;
608       } 
609       RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[0],\
610                    sizeof(RICaction_ToBeSetup_ItemIEs_t));
611       fillSubsDetails(subsDetails->ricAction_ToBeSetup_List.list.array[0]);
612    }
613    return ROK;
614 }
615
616 /*******************************************************************
617  *
618  * @brief Builds and Send the RicSubscriptionReq
619  *
620  * @details
621  *
622  *    Function : BuildAndSendRicSubscriptionReq
623  *
624  * Functionality:Fills the RicSubscriptionReq
625  *
626  * @return ROK     - success
627  *         RFAILED - failure
628  *
629  ******************************************************************/
630
631 uint8_t BuildAndSendRicSubscriptionReq(uint32_t duId)
632 {
633
634    E2AP_PDU_t                 *e2apRicMsg = NULL;
635    RICsubscriptionRequest_t   *ricSubscriptionReq;
636    uint8_t         elementCnt;
637    uint8_t         idx;
638    uint8_t         ieId;
639    uint8_t         ret; 
640    asn_enc_rval_t  encRetVal;        /* Encoder return value */
641
642    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Request\n");
643
644    RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
645    if(e2apRicMsg == NULLP)
646    {
647       DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
648       return RFAILED;
649    }
650
651    e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
652    RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
653    if(e2apRicMsg->choice.initiatingMessage == NULLP)
654    {
655       DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
656       RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
657       return RFAILED;
658    }
659    e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
660    e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
661    e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
662    
663    RIC_ALLOC(ricSubscriptionReq, sizeof(RICsubscriptionRequest_t));
664    ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
665    
666    elementCnt = 3;
667    ricSubscriptionReq->protocolIEs.list.count = elementCnt;
668    ricSubscriptionReq->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
669
670    /* Initialize the subscription members */
671    RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, \
672               ricSubscriptionReq->protocolIEs.list.size);
673    if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
674    {
675       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICSubscriptionRequestIEs failed");
676       RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
677       RIC_FREE(e2apRicMsg, (Size)sizeof(E2AP_PDU_t));
678       return RFAILED;
679    }
680    
681    for(idx=0; idx<elementCnt; idx++)
682    {
683       RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx],\
684             sizeof(RICsubscriptionRequest_IEs_t));
685       if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
686       {
687          for(ieId=0; ieId<idx; ieId++)
688          {
689             RIC_FREE(ricSubscriptionReq->protocolIEs.list.array[ieId],\
690                   sizeof(RICsubscriptionRequest_IEs_t));
691          }
692          RIC_FREE(ricSubscriptionReq->protocolIEs.list.array,\
693                   ricSubscriptionReq->protocolIEs.list.size);
694          RIC_FREE(e2apRicMsg->choice.initiatingMessage, \
695                sizeof(InitiatingMessageE2_t));
696          RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
697          return RFAILED;
698       }
699    }
700
701    /* Filling RIC Request Id */
702    idx = 0;
703    ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
704    ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
705    ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
706                                     RICsubscriptionRequest_IEs__value_PR_RICrequestID;
707  
708    BuildRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID);
709
710
711    /* Filling RAN Function Id */
712    idx++;
713    ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
714    ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
715    ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
716                                     RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
717    ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1;
718
719
720    /* Filling RIC Subscription Details */
721    idx++;
722    ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
723    ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
724    ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
725                                     RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
726
727    BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails));
728
729
730    /* Prints the Msg formed */
731    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
732
733    memset(encBuf, 0, ENC_BUF_MAX_LEN);
734    encBufSize = 0;
735    encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\
736                encBuf);
737    if(encRetVal.encoded == ENCODE_FAIL)
738    {
739       DU_LOG("\nERROR  -->  E2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
740       encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
741       return RFAILED;
742    }
743    else
744    {
745       DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
746       for(int i=0; i< encBufSize; i++)
747       {
748           DU_LOG("%x",encBuf[i]);
749       } 
750    }
751
752
753    /* Sending msg */
754    if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
755    {
756       DU_LOG("\nERROR  -->  E2AP : Sending RIC subscription Request failed");
757       return RFAILED;
758    }
759
760    return ROK;
761 }
762
763 /*******************************************************************
764  *
765  * @brief Process RicSubscriptionResponse
766  *
767  * @details
768  *
769  *    Function : ProcRicSubscriptionRsp
770  *
771  * Functionality: Processes RicSubscriptionRsp
772  *
773  * @return ROK     - void
774  *
775  ******************************************************************/
776
777 void ProcRicSubscriptionResponse(uint32_t duId)
778 {
779    uint8_t duIdx = 0;
780    DuDb *duDb;
781
782    DU_LOG("\nINFO  -->  E2AP : RICsubscriptionResponse Msg Acknowledged");
783
784    SEARCH_DU_DB(duIdx, duId, duDb);
785    if(duDb)
786       duDb->ricSubscribedToDu = true;
787 }
788
789 /*******************************************************************
790  *
791  * @brief deallocate the memory allocated in E2SetupFailure
792  *
793  * @details
794  *
795  *    Function : FreeE2SetupFailure 
796  *
797  *    Functionality: deallocate the memory allocated in E2SetupFailure 
798  *
799  * @params[in] E2AP_PDU_t *e2apMsg
800  *
801  * @return void
802  * ****************************************************************/
803 void FreeE2SetupFailure(E2AP_PDU_t *e2apMsg)
804 {
805    uint8_t arrIdx = 0;
806    E2setupFailure_t  *e2SetupFail;
807
808    if(e2apMsg)
809    {
810       if(e2apMsg->choice.unsuccessfulOutcome)
811       {
812          e2SetupFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
813          if(e2SetupFail->protocolIEs.list.array)
814          {
815             for(arrIdx=0; arrIdx<e2SetupFail->protocolIEs.list.count; arrIdx++)
816             {
817                RIC_FREE(e2SetupFail->protocolIEs.list.array[arrIdx], sizeof(E2setupFailureIEs_t)); 
818             }
819             RIC_FREE(e2SetupFail->protocolIEs.list.array, e2SetupFail->protocolIEs.list.size);
820          }
821          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
822       }
823       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
824    }
825 }
826
827 /*******************************************************************
828  *
829  * @brief Buld and send the E2 Setup failure
830  *
831  * @details
832  *
833  *    Function : BuildAndSendE2SetupFailure
834  *
835  *    Functionality:
836  *         - Buld and send the E2 Setup failure
837  * @return ROK     - success
838  *         RFAILED - failure
839  *
840  * ****************************************************************/
841
842 uint8_t BuildAndSendE2SetupFailure(uint32_t duId, uint8_t transId)
843 {
844    E2AP_PDU_t         *e2apMsg = NULL;
845    E2setupFailure_t   *e2SetupFailure;
846    asn_enc_rval_t     encRetVal;
847    uint8_t            arrIdx;
848    uint8_t            elementCnt;
849    bool  memAllocFailed = false;
850
851    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup failure\n");
852    while(true)
853    {
854       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
855       if(e2apMsg == NULLP)
856       {
857          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
858          break;
859       }
860       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
861       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
862       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
863       {
864          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
865          break;
866       }
867
868       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
869       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
870       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2setupFailure;
871       e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
872
873       elementCnt = 3;
874       e2SetupFailure->protocolIEs.list.count = elementCnt;
875       e2SetupFailure->protocolIEs.list.size  = elementCnt * sizeof(struct E2setupFailureIEs *);
876
877       RIC_ALLOC(e2SetupFailure->protocolIEs.list.array, e2SetupFailure->protocolIEs.list.size);
878       if(e2SetupFailure->protocolIEs.list.array == NULLP)
879       {
880          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
881          break;
882       }
883
884       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
885       {
886          RIC_ALLOC(e2SetupFailure->protocolIEs.list.array[arrIdx], sizeof(struct E2setupFailureIEs));
887          if(e2SetupFailure->protocolIEs.list.array[arrIdx] == NULLP)
888          {
889             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
890             memAllocFailed = true;
891             break;
892          }
893       }
894
895       if(memAllocFailed == true)
896       {
897           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
898           break;
899       }
900
901       /* Trans Id */
902       arrIdx = 0;
903       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
904       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
905       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TransactionID;
906       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
907
908       arrIdx++;
909       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
910       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
911       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_CauseE2;
912       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.present = CauseE2_PR_protocol;
913       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.protocol = CauseE2Protocol_unspecified;
914
915       arrIdx++;
916       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
917       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
918       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TimeToWaitE2;
919       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
920
921       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
922       memset(encBuf, 0, ENC_BUF_MAX_LEN);
923       encBufSize = 0;
924       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
925
926       /* Check encode results */
927       if(encRetVal.encoded == ENCODE_FAIL)
928       {
929          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Setup failure structure (at %s)\n",\
930                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
931          break;
932       }
933       else
934       {
935          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Setup Failure\n");
936          for(int i=0; i< encBufSize; i++)
937          {
938             DU_LOG("%x",encBuf[i]);
939          }
940       }
941
942       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
943       {
944          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Failure failed");
945          break;
946       }
947       break;
948    }
949
950    FreeE2SetupFailure(e2apMsg);
951 }
952
953 /*******************************************************************
954  *
955  * @brief process the e2setup request 
956  *
957  * @details
958  *
959  *    Function : ProcE2SetupReq
960  *
961  * Functionality: process the e2setup request
962  *
963  * @return ROK     - success
964  *         RFAILED - failure
965  *
966  ******************************************************************/
967
968 uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
969 {
970    uint8_t arrIdx = 0, e2NodeAddListIdx =0, duIdx = 0, transId =0, ranFuncIdx;
971    DuDb    *duDb = NULLP;
972    E2nodeComponentConfigAddition_List_t *e2NodeAddList;
973    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
974    RANfunction_ItemIEs_t *ranFuncItemIe;
975    RANfunction_Item_t  *ranFunItem;
976    RANfunctions_List_t *ranFunctionsList;
977
978    if(e2SetupReq)
979    {
980       if(e2SetupReq->protocolIEs.list.array)      
981       {
982          for(arrIdx=0; arrIdx<e2SetupReq->protocolIEs.list.count; arrIdx++)
983          {
984             if(e2SetupReq->protocolIEs.list.array[arrIdx])
985             {
986                switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
987                {
988                   case ProtocolIE_IDE2_id_TransactionID:
989                      {
990                         transId = e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; 
991                         break;
992                      }
993                   case ProtocolIE_IDE2_id_GlobalE2node_ID:
994                      {
995                         if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID)
996                         {
997                             *duId =e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID->buf[0];
998
999                             SEARCH_DU_DB(duIdx, duId, duDb); 
1000                             if(duDb == NULLP)
1001                             {
1002                                duDb = &ricCb.duInfo[ricCb.numDu];
1003                                ricCb.numDu++;
1004                             }
1005                             memset(duDb, 0, sizeof(DuDb));
1006                             duDb->duId = *duId;
1007                         }
1008                         break;
1009                      }
1010                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
1011                      {
1012                         ranFunctionsList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
1013
1014                         if(ranFunctionsList->list.array)
1015                         {
1016                            for(ranFuncIdx=0;ranFuncIdx<ranFunctionsList->list.count; ranFuncIdx++)
1017                            {
1018                               ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncIdx]; 
1019                               ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
1020                               duDb->ranFunction[duDb->numOfRanFunction].id =  ranFunItem->ranFunctionID; 
1021                               duDb->ranFunction[ duDb->numOfRanFunction].revisionCounter =  ranFunItem->ranFunctionRevision; 
1022                               duDb->numOfRanFunction++;
1023                            }
1024                         }
1025                         break;
1026                      }
1027                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
1028                      {
1029                         e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;      
1030                         if(e2NodeAddList->list.array)
1031                         {
1032                            for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
1033                            {
1034                               if(e2NodeAddList->list.array[e2NodeAddListIdx])
1035                               {
1036                                  e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
1037                                  if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
1038                                        e2nodeComponentInterfaceTypeF1)
1039                                  {
1040                                     duDb->e2NodeComponent.interfaceType = F1; 
1041                                     duDb->e2NodeComponent.componentId = e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]; 
1042                                  }
1043                               }
1044                            }
1045                         }
1046                         break;
1047                      }
1048                      default:
1049                         break;
1050                   }
1051                }
1052             }
1053         }
1054    }
1055    if(BuildAndSendE2SetupRsp(duDb, transId) !=ROK)
1056    {
1057       DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 setup response");
1058       return RFAILED;
1059    }
1060    return ROK;   
1061 }
1062
1063 /*******************************************************************
1064  *
1065  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
1066  *
1067  * @details
1068  *
1069  *    Function : FreeE2NodeConfigUpdate 
1070  *
1071  *    Functionality:
1072  *       - freeing the memory allocated for E2nodeConfigurationUpdate
1073  *
1074  * @params[in] E2AP_PDU_t *e2apMsg 
1075  * @return ROK     - success
1076  *         RFAILED - failure
1077  *
1078  * ****************************************************************/
1079 void FreeE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg)
1080 {
1081    uint8_t arrIdx =0;
1082    E2nodeConfigurationUpdate_t *e2NodeConfigUpdateAck;
1083
1084    if(e2apMsg != NULLP)
1085    {
1086       if(e2apMsg->choice.successfulOutcome != NULLP)
1087       {
1088          e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
1089          if(e2NodeConfigUpdateAck->protocolIEs.list.array != NULLP)
1090          {
1091             for(arrIdx = 0; arrIdx < e2NodeConfigUpdateAck->protocolIEs.list.count; arrIdx++)
1092             {
1093                RIC_FREE(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_t));
1094             }
1095             RIC_FREE(e2NodeConfigUpdateAck->protocolIEs.list.array, e2NodeConfigUpdateAck->protocolIEs.list.size);
1096          }
1097          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1098       }
1099       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1100    }
1101 }
1102
1103 /*******************************************************************
1104  *
1105  * @brief Buld and send the E2 node config update msg 
1106  *
1107  * @details
1108  *
1109  *    Function : BuildAndSendE2NodeConfigUpdate
1110  *
1111  *    Functionality:
1112  *         - Buld and send the E2 node config update msg
1113  * @return ROK     - success
1114  *         RFAILED - failure
1115  *
1116  * ****************************************************************/
1117
1118 uint8_t BuildAndSendE2NodeConfigUpdateAck(uint32_t duId)
1119 {
1120    uint8_t arrIdx = 0,elementCnt = 1;
1121    uint8_t ret = ROK;
1122    E2AP_PDU_t        *e2apMsg = NULLP;
1123    E2nodeConfigurationUpdateAcknowledge_t *e2NodeConfigUpdateAck = NULLP;
1124    asn_enc_rval_t     encRetVal;       /* Encoder return value */
1125
1126    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update Ack Message\n");
1127    do
1128    {
1129       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1130       if(e2apMsg == NULLP)
1131       {
1132          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1133          break;
1134       }
1135       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
1136       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1137       if(e2apMsg->choice.successfulOutcome == NULLP)
1138       {
1139          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1140          RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1141          return RFAILED;
1142       }
1143       
1144       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
1145       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
1146       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge;
1147       e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
1148
1149       e2NodeConfigUpdateAck->protocolIEs.list.count = elementCnt;
1150       e2NodeConfigUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t*);
1151       /* Initialize the Ric Indication members */
1152       RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array, \
1153             e2NodeConfigUpdateAck->protocolIEs.list.size);
1154       if(e2NodeConfigUpdateAck->protocolIEs.list.array == NULLP)
1155       {
1156          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdateAck failed");
1157          break;
1158       }
1159       
1160       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
1161       {
1162          RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t));
1163          if(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
1164          {
1165             
1166             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdateAck failed");
1167             break;
1168          }
1169       }
1170
1171       arrIdx = 0;
1172       /* TransactionID */
1173       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
1174       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1175       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_TransactionID;
1176       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = TRANS_ID;
1177
1178
1179       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1180
1181       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1182       encBufSize = 0;
1183       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
1184             encBuf);
1185       if(encRetVal.encoded == ENCODE_FAIL)
1186       {
1187          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Node config update ack structure (at %s)\n",\
1188                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1189          return RFAILED;
1190       }
1191       else
1192       {
1193          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Node config update ack \n");
1194          for(int i=0; i< encBufSize; i++)
1195          {
1196             DU_LOG("%x",encBuf[i]);
1197          } 
1198       }
1199
1200
1201       /* Sending msg */
1202       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
1203       {
1204          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Node config update ack ");
1205          return RFAILED;
1206       }
1207
1208       break;
1209    }while(true);
1210    
1211    FreeE2NodeConfigUpdateAck(e2apMsg);
1212    return ret;
1213 }
1214
1215 /*******************************************************************
1216  *
1217  * @brief Deallocate the memory allocated for E2 Reset Response
1218  *
1219  * @details
1220  *
1221  *    Function : FreeE2ResetResponse
1222  *
1223  *    Functionality:
1224  *       - freeing the memory allocated for E2ResetResponse
1225  *
1226  * @params[in] E2AP_PDU_t *e2apMsg
1227  * @return ROK     - success
1228  *         RFAILED - failure
1229  *
1230  * ****************************************************************/
1231 void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg)
1232 {
1233    uint8_t ieIdx =0;
1234    ResetResponseE2_t *resetResponse;
1235
1236    if(e2apMsg != NULLP)
1237    {
1238       if(e2apMsg->choice.successfulOutcome != NULLP)
1239       {
1240          resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
1241          if(resetResponse->protocolIEs.list.array)
1242          {
1243             for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
1244             {
1245                if(resetResponse->protocolIEs.list.array[ieIdx])
1246                {
1247                   RIC_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
1248                }
1249             }
1250             RIC_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
1251          }
1252          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1253       }
1254       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1255    }
1256 }
1257
1258 /*******************************************************************
1259  *
1260  * @brief Buld and send the E2 Reset Response msg
1261  *
1262  * @details
1263  *
1264  *    Function : BuildAndSendE2ResetResponse
1265  *
1266  *    Functionality:
1267  *         - Buld and send the E2 Reset Response Message
1268  * @return ROK     - success
1269  *         RFAILED - failure
1270  *
1271  * ****************************************************************/
1272 uint8_t BuildAndSendResetResponse(uint32_t duId, uint8_t transId)
1273 {
1274    uint8_t           ieIdx = 0, elementCnt = 0;
1275    uint8_t           ret = RFAILED;
1276    E2AP_PDU_t        *e2apMsg = NULLP;
1277    ResetResponseE2_t *resetResponse;
1278    asn_enc_rval_t    encRetVal;       /* Encoder return value */
1279
1280    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
1281    do
1282    {
1283       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1284       if(e2apMsg == NULLP)
1285       {
1286          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
1287          break;
1288       }
1289       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
1290
1291       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1292       if(e2apMsg->choice.successfulOutcome == NULLP)
1293       {
1294          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
1295          RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1296          return RFAILED;
1297       }
1298  
1299       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
1300       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
1301       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
1302       resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
1303
1304       elementCnt = 1;
1305       resetResponse->protocolIEs.list.count = elementCnt;
1306       resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
1307       RIC_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
1308       if(!resetResponse->protocolIEs.list.array)
1309       {
1310          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
1311          break;
1312       }
1313
1314       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
1315       {
1316          RIC_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
1317          if(!resetResponse->protocolIEs.list.array[ieIdx])
1318          {
1319             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
1320             break;
1321          }
1322       }
1323       if(ieIdx < elementCnt)
1324          break;
1325
1326       ieIdx = 0; 
1327       resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
1328       resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
1329       resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
1330       resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
1331
1332       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1333
1334       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1335       encBufSize = 0;
1336       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
1337       if(encRetVal.encoded == ENCODE_FAIL)
1338       {
1339          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
1340                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1341          return RFAILED;
1342       }
1343       else
1344       {
1345          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
1346          for(int i=0; i< encBufSize; i++)
1347          {
1348             DU_LOG("%x",encBuf[i]);
1349          }
1350       }
1351
1352       /* Sending msg */
1353       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
1354       {
1355          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
1356          return RFAILED;
1357       }
1358
1359       ret = ROK;
1360       break;
1361    }while(true);
1362
1363    FreeE2ResetResponse(e2apMsg);
1364    return ROK;
1365 }
1366
1367 /*******************************************************************
1368  *
1369  * @brief process the E2 Reset Request
1370  *
1371  * @details
1372  *
1373  *    Function : ProcE2ResetReq
1374  *
1375  * Functionality: Process E2 Reset Request
1376  *
1377  * @return ROK     - success
1378  *         RFAILED - failure
1379  *
1380  ******************************************************************/
1381
1382 uint8_t ProcE2ResetReq(uint32_t duId, ResetRequestE2_t  *resetReq)
1383 {
1384    uint8_t ieIdx = 0, duIdx = 0;
1385    uint8_t transId = 0, cause = 0;
1386    DuDb    *duDb = NULLP;
1387
1388    if(resetReq)
1389    {
1390       if(resetReq->protocolIEs.list.array)
1391       {
1392          for(ieIdx=0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
1393          {
1394             if(resetReq->protocolIEs.list.array[ieIdx])
1395             {
1396                switch(resetReq->protocolIEs.list.array[ieIdx]->id)
1397                {
1398                   case ProtocolIE_IDE2_id_TransactionID:
1399                      transId = resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
1400                      break;
1401                   case ProtocolIE_IDE2_id_CauseE2:
1402                      DU_LOG("\nDEBUG  -->  E2AP : Reset reason %d", resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present);
1403                      switch(resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present)
1404                      {
1405                         case CauseE2_PR_NOTHING:
1406                            break;
1407                         case CauseE2_PR_ricRequest:
1408                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricRequest;
1409                            break;
1410                         case CauseE2_PR_ricService:
1411                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricService;
1412                            break;
1413                         case CauseE2_PR_e2Node:
1414                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.e2Node;
1415                            break;
1416                         case CauseE2_PR_transport:
1417                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.transport;
1418                            break;
1419                         case CauseE2_PR_protocol:
1420                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.protocol;
1421                            break;
1422                         case CauseE2_PR_misc:
1423                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.misc;
1424                            break;
1425                      }
1426                      DU_LOG("\nDEBUG  -->  E2AP : Reset cause %d", cause);
1427                      break;
1428                }
1429             }
1430          }
1431       }
1432    }
1433    BuildAndSendResetResponse(duId, transId);
1434    return ROK;
1435 }
1436
1437 /*******************************************************************
1438 *
1439 * @brief Handles received E2AP message and sends back response  
1440 *
1441 * @details
1442 *
1443 *    Function : E2APMsgHdlr
1444 *
1445 *    Functionality:
1446 *         - Decodes received E2AP control message
1447 *         - Prepares response message, encodes and sends to SCTP
1448 *
1449 * @params[in] 
1450 * @return ROK     - success
1451 *         RFAILED - failure
1452 *
1453 * ****************************************************************/
1454 void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
1455 {
1456    int             i;
1457    char            *recvBuf;
1458    MsgLen          copyCnt;
1459    MsgLen          recvBufLen;
1460    E2AP_PDU_t      *e2apMsg;
1461    asn_dec_rval_t  rval; /* Decoder return value */
1462    E2AP_PDU_t      e2apasnmsg ;
1463  
1464    DU_LOG("\nINFO  -->  E2AP : Received E2AP message buffer");
1465    ODU_PRINT_MSG(mBuf, 0,0);
1466  
1467    /* Copy mBuf into char array to decode it */
1468    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
1469    RIC_ALLOC(recvBuf, (Size)recvBufLen);
1470
1471    if(recvBuf == NULLP)
1472    {
1473       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
1474       return;
1475    }
1476    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
1477    {
1478       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
1479       return;
1480    }
1481
1482    DU_LOG("\nDEBUG  -->  E2AP : Received flat buffer to be decoded : ");
1483    for(i=0; i< recvBufLen; i++)
1484    {
1485         DU_LOG("%x",recvBuf[i]);
1486    }
1487
1488    /* Decoding flat buffer into E2AP messsage */
1489    e2apMsg = &e2apasnmsg;
1490    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
1491
1492    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
1493    RIC_FREE(recvBuf, (Size)recvBufLen);
1494
1495    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
1496    {
1497       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
1498       return;
1499    }
1500    DU_LOG("\n");
1501    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1502
1503    switch(e2apMsg->present)
1504    {
1505       case E2AP_PDU_PR_initiatingMessage:
1506          {
1507             switch(e2apMsg->choice.initiatingMessage->value.present)
1508             {
1509                case InitiatingMessageE2__value_PR_E2setupRequest:
1510                   {
1511                      DU_LOG("\nINFO  -->  E2AP : E2 setup request received");
1512                      ProcE2SetupReq(duId, &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest);
1513                      break;
1514                   }
1515                case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate:
1516                   {
1517                      DU_LOG("\nINFO  -->  E2AP : E2 node config update received");
1518                      BuildAndSendE2NodeConfigUpdateAck(*duId);
1519                      break;
1520                   }
1521                case InitiatingMessageE2__value_PR_ResetRequestE2:
1522                   {
1523                      DU_LOG("\nINFO  -->  E2AP : E2 Reset Request received");
1524                      ProcE2ResetReq(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2);
1525                      break;
1526                   }
1527                case InitiatingMessageE2__value_PR_RICindication:
1528                   {
1529                      DU_LOG("\nINFO  -->  E2AP : RIC Indication Acknowledged");
1530                      break;
1531                   }
1532                default:
1533                   {
1534                      DU_LOG("\nERROR  -->  E2AP : Invalid type of intiating message [%d]",e2apMsg->choice.initiatingMessage->value.present);
1535                      return;
1536                   }
1537             }/* End of switch(initiatingMessage) */
1538             break;
1539          }
1540       case E2AP_PDU_PR_successfulOutcome: 
1541          {
1542             switch(e2apMsg->choice.successfulOutcome->value.present)
1543             {
1544                case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:  
1545                   {
1546                      ProcRicSubscriptionResponse(*duId);
1547                      break;
1548                   }
1549                default:
1550                   {
1551                      DU_LOG("\nERROR  -->  E2AP : Invalid type of successfulOutcome message [%d]",e2apMsg->choice.successfulOutcome->value.present);
1552                      return;
1553                   }
1554                   break;
1555             }
1556             break; 
1557          }
1558       default:
1559          {
1560             DU_LOG("\nERROR  -->  E2AP : Invalid type message type ");
1561             return;
1562          }
1563
1564    }/* End of switch(e2apMsg->present) */
1565 } /* End of E2APMsgHdlr */
1566
1567
1568 /**********************************************************************
1569   End of file
1570  **********************************************************************/