[Epic-ID: ODUHIGH-510][Task-ID: ODUHIGH-512] Implementation of E2 setup failure
[o-du/l2.git] / src / du_app / du_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 #include "common_def.h"
19 #include "du_tmr.h"
20 #include "lrg.h"
21 #include "lkw.x"
22 #include "lrg.x"
23 #include "legtp.h"
24 #include "du_app_mac_inf.h"
25 #include "du_app_rlc_inf.h"
26 #include "du_e2ap_mgr.h"
27 #include "du_e2ap_msg_hdl.h"
28 #include "du_cfg.h"
29 #include "du_mgr.h"
30 #include "du_mgr_main.h"
31 #include "du_utils.h"
32 #include "GlobalE2node-gNB-ID.h"
33 #include "ProtocolIE-FieldE2.h"
34 #include "E2setupRequest.h"
35 #include "InitiatingMessageE2.h"
36 #include "SuccessfulOutcomeE2.h"
37 #include "UnsuccessfulOutcomeE2.h"
38 #include "E2AP-PDU.h"
39 #include "odu_common_codec.h"
40 #include "E2nodeComponentInterfaceF1.h"
41 #include "E2setupRequest.h"
42 #include "du_e2_conversions.h"
43
44 /*******************************************************************
45  *
46  * @brief Builds Global gNodeB Params
47  *
48  * @details
49  *
50  *    Function : BuildGlobalgNBId
51  *
52  *    Functionality: Building the Plmn and gNB id
53  *
54  * @params[in] GlobalE2node_gNB_ID_t *gNbId
55  * @return ROK     - success
56  *         RFAILED - failure
57  *
58  ******************************************************************/
59
60 uint8_t BuildGlobalgNBId(GlobalE2node_gNB_ID_t *gNbId)
61 {
62    uint8_t unused = 0;
63    uint8_t byteSize = 4;
64    uint8_t gnbId = 1;
65    uint8_t ret = ROK;
66
67    /* Allocate Buffer size */
68    gNbId->global_gNB_ID.plmn_id.size = 3 * sizeof(uint8_t);
69    gNbId->global_gNB_ID.plmn_id.buf = NULLP;
70    DU_ALLOC(gNbId->global_gNB_ID.plmn_id.buf , gNbId->global_gNB_ID.plmn_id.size);
71    if(gNbId->global_gNB_ID.plmn_id.buf == NULLP)
72    {
73       DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for Plmn buffer");
74       ret = RFAILED;
75    }
76    else
77    {
78       buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
79             gNbId->global_gNB_ID.plmn_id.buf);
80       /* fill gND Id */
81       gNbId->global_gNB_ID.gnb_id.present = GNB_ID_Choice_PR_gnb_ID;
82       /* Allocate Buffer size */
83       gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size = byteSize * sizeof(uint8_t);
84       gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf = NULLP;
85       DU_ALLOC(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf, \
86             gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size);
87       if(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf == NULLP)
88       {
89          DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for gnb buffer");
90          ret = RFAILED;
91       }
92       else
93       {
94          fillBitString(&gNbId->global_gNB_ID.gnb_id.choice.gnb_ID, unused, byteSize, gnbId);
95       }
96    }
97    return ret;
98 }
99
100 /*******************************************************************
101  *
102  * @brief Builds E2 node config addition list 
103  *
104  * @details
105  *
106  *    Function : BuildE2NodeConfigAddList
107  *
108  *    Functionality: Building E2 node config addition list
109  *
110  * @params[in] E2nodeComponentConfigAddition_List_t *e2NodeAddList 
111  * @return ROK     - success
112  *         RFAILED - failure
113  *
114  ******************************************************************/
115
116 uint8_t BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAddList)
117 {
118    uint8_t arrIdx = 0;
119    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItemIe;
120    E2nodeComponentConfigAddition_Item_t *e2NodeAddItem;
121
122    e2NodeAddList->list.count = 1;
123    e2NodeAddList->list.size = e2NodeAddList->list.count * sizeof(E2nodeComponentConfigAddition_ItemIEs_t *);
124    DU_ALLOC(e2NodeAddList->list.array, e2NodeAddList->list.size);
125    if(e2NodeAddList->list.array == NULLP)
126    {
127        DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
128        return RFAILED;
129    }
130
131    for(arrIdx = 0; arrIdx< e2NodeAddList->list.count; arrIdx++)
132    {
133       DU_ALLOC(e2NodeAddList->list.array[arrIdx], sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
134       if(e2NodeAddList->list.array[arrIdx] == NULLP)
135       {
136          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
137          return RFAILED;
138       }
139    }
140
141    arrIdx = 0;
142    e2NodeAddItemIe = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[arrIdx];
143    e2NodeAddItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition_Item;
144    e2NodeAddItemIe->criticality = CriticalityE2_reject;
145    e2NodeAddItemIe->value.present = E2nodeComponentConfigAddition_ItemIEs__value_PR_E2nodeComponentConfigAddition_Item;
146    e2NodeAddItem = &e2NodeAddItemIe->value.choice.E2nodeComponentConfigAddition_Item;
147    
148    /* E2nodeComponentInterfaceType */
149    e2NodeAddItem->e2nodeComponentInterfaceType = E2nodeComponentInterfaceType_f1;
150
151    /* E2 Node Component Request Part */
152    e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.size = duCb.f1SetupReqAndRspMsg.f1MsgReqBufSize;
153    DU_ALLOC(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\
154    e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.size);
155    if(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf == NULLP)
156    {
157       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
158       return RFAILED;
159    }
160
161    memcpy(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\
162    duCb.f1SetupReqAndRspMsg.f1MsgReqBuf, e2NodeAddItem->e2nodeComponentConfiguration.\
163    e2nodeComponentRequestPart.size);
164   
165    /* E2 Node Component Response Part */
166    e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.size = duCb.f1SetupReqAndRspMsg.f1MsgRspBufSize; 
167    DU_ALLOC(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.buf, \
168    e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.size);
169    if(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.buf == NULLP)
170    {
171       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
172       return RFAILED;
173    }
174    memcpy(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.buf, \
175    duCb.f1SetupReqAndRspMsg.f1MsgRspBuf, e2NodeAddItem->e2nodeComponentConfiguration.\
176    e2nodeComponentResponsePart.size);
177
178    /* E2 Node Component ID */
179    e2NodeAddItem->e2nodeComponentID.present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1;
180    DU_ALLOC(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\
181    sizeof(E2nodeComponentInterfaceF1_t));
182    if(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1 == NULLP)
183    {
184        DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
185        return RFAILED;
186    }
187    e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t);
188    DU_ALLOC(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
189    e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
190
191    if(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP)
192    {
193       DU_LOG("\nERROR  -->list.  E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
194       return RFAILED;
195    }
196    e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[arrIdx]  = duCfgParam.duId;
197    return ROK;
198
199 }
200
201 /*******************************************************************
202  *
203  * @brief De Allocate E2 Setup Request Message
204  *
205  * @details
206  *
207  *    Function : FreeE2SetupReq
208  *
209  *    Functionality: De-Allocating E2 Setup request Message
210  *
211  * @params[in] E2AP_PDU_t *e2apMsg
212  
213  * @return void
214  *
215  * ****************************************************************/
216
217 void FreeE2SetupReq(E2AP_PDU_t *e2apMsg)
218 {
219    uint8_t arrIdx = 0;
220    uint8_t e2NodeAddListIdx =0;
221    E2setupRequest_t *e2SetupReq;
222    E2nodeComponentConfigAddition_List_t *e2NodeAddList;
223    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
224
225    /* De-allocating Memory */
226    if(e2apMsg != NULLP)
227    {
228       if(e2apMsg->choice.initiatingMessage != NULLP)
229       {
230          e2SetupReq = &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest; 
231          if(e2SetupReq->protocolIEs.list.array != NULLP)
232          {
233             for(arrIdx = 0; arrIdx < e2SetupReq->protocolIEs.list.count; arrIdx++)
234             {
235                if(e2SetupReq->protocolIEs.list.array[arrIdx] != NULLP)
236                {
237                   switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
238                   {
239                      case ProtocolIE_IDE2_id_TransactionID:
240                           break;
241                      case ProtocolIE_IDE2_id_GlobalE2node_ID:
242                         {
243                            if(e2SetupReq->protocolIEs.list.array[arrIdx]->\
244                                  value.choice.GlobalE2node_ID.choice.gNB != NULLP)
245                            {
246                               GlobalE2node_gNB_ID_t *gNbId = NULLP;
247                               gNbId = e2SetupReq->protocolIEs.list.array[arrIdx]->\
248                                       value.choice.GlobalE2node_ID.choice.gNB;
249                               if(gNbId->global_gNB_ID.plmn_id.buf != NULLP)
250                               {
251                                  DU_FREE(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf,\
252                                           gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size);
253                                  DU_FREE(gNbId->global_gNB_ID.plmn_id.buf,\
254                                        gNbId->global_gNB_ID.plmn_id.size);
255                               }
256                               DU_FREE(e2SetupReq->protocolIEs.list.array[arrIdx]->value.\
257                                     choice.GlobalE2node_ID.choice.gNB, sizeof(GlobalE2node_gNB_ID_t));
258                            }
259                            break;
260                         }
261                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
262                      {
263                          e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;
264                          if(e2NodeAddList->list.array)
265                          {
266                              for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
267                              {
268                                 e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
269                                 
270                                 /* Free E2 Node Component Request Part */
271                                 DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\
272                                       e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentRequestPart.size);
273                                 
274                                 /* Free E2 Node Component Response Part */
275                                 DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.\
276                                       e2nodeComponentResponsePart.buf, \
277                                       e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentResponsePart.size);
278                                  
279                                  /* Free E2 Node Component ID */
280                                 if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1)
281                                 {
282                                     DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
283                                     e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
284                                     e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
285                                     e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
286                                     DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\
287                                     sizeof(E2nodeComponentInterfaceF1_t));
288                                 }
289                                 DU_FREE(e2NodeAddList->list.array[e2NodeAddListIdx], sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
290                              }
291                              DU_FREE(e2NodeAddList->list.array, e2NodeAddList->list.size);
292                          }
293                          break;
294                      }
295                      default:
296                         DU_LOG("\nERROR  --> E2AP: Invalid event at e2SetupRequet %ld ",\
297                               (e2SetupReq->protocolIEs.list.array[arrIdx]->id));
298                         break;
299                   }
300                   DU_FREE(e2SetupReq->protocolIEs.list.array[arrIdx], sizeof(E2setupRequestIEs_t));
301                }
302             }
303             DU_FREE(e2SetupReq->protocolIEs.list.array, e2SetupReq->protocolIEs.list.size);
304          }
305          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
306       }
307       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
308    }
309 }
310
311 /*******************************************************************
312  *
313  * @brief Builds and Send the E2SetupRequest
314  *
315  * @details
316  *
317  *    Function : BuildAndSendE2SetupReq
318  *
319  * Functionality:Fills the E2SetupRequest
320  *
321  * @return ROK     - success
322  *         RFAILED - failure
323  *
324  ******************************************************************/
325
326 uint8_t BuildAndSendE2SetupReq()
327 {
328    uint8_t arrIdx = 0, elementCnt=0;
329    uint8_t transId = 0, ret = ROK;
330    bool memAllocFailed;
331    E2AP_PDU_t        *e2apMsg = NULLP;
332    E2setupRequest_t  *e2SetupReq = NULLP;
333    asn_enc_rval_t     encRetVal;       /* Encoder return value */
334
335    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup Request\n");
336    do
337    {
338       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
339       if(e2apMsg == NULLP)
340       {
341          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
342          break;
343       }
344       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
345       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
346       if(e2apMsg->choice.initiatingMessage == NULLP)
347       {
348          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
349          break;
350       }
351       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
352       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2setup;
353       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2setupRequest;
354       e2SetupReq = &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest;
355
356       elementCnt = 3;
357       e2SetupReq->protocolIEs.list.count = elementCnt;
358       e2SetupReq->protocolIEs.list.size = elementCnt * sizeof(E2setupRequestIEs_t*);
359
360       /* Initialize the E2Setup members */
361       DU_ALLOC(e2SetupReq->protocolIEs.list.array, \
362             e2SetupReq->protocolIEs.list.size);
363       if(e2SetupReq->protocolIEs.list.array == NULLP)
364       {
365          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
366          break;
367       }
368       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
369       {
370          DU_ALLOC(e2SetupReq->protocolIEs.list.array[arrIdx],\
371                sizeof(E2setupRequestIEs_t));
372          if(e2SetupReq->protocolIEs.list.array[arrIdx] == NULLP)
373          {
374             memAllocFailed = true;
375             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayarrIdx [%d]", arrIdx);
376             break;
377          }
378       }
379       if(memAllocFailed == true)
380          break;
381
382       arrIdx = 0;
383
384       /* TransactionID */
385       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
386       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
387       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
388       transId = assignTransactionId();
389       e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
390
391       arrIdx++;
392       /* GlobalE2node_gNB_ID */
393       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_GlobalE2node_ID;
394       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
395       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_GlobalE2node_ID;
396       e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.present = GlobalE2node_ID_PR_gNB;
397
398       DU_ALLOC(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.\
399             GlobalE2node_ID.choice.gNB, sizeof(GlobalE2node_gNB_ID_t));
400       if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.\
401             GlobalE2node_ID.choice.gNB == NULLP)
402       {
403          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for gNbId");
404          break;
405       }
406       else
407       {
408          ret = BuildGlobalgNBId(e2SetupReq->protocolIEs.list.array[arrIdx]->value.\
409                choice.GlobalE2node_ID.choice.gNB);
410          if(ret != ROK)
411          {
412              DU_LOG("\nERROR  -->  E2AP : Failed to build Global Gnb Id");
413              break;
414          }
415       }
416       
417       arrIdx++;
418       /* E2 Node Component Configuration Addition List */
419       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition;
420       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
421       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_E2nodeComponentConfigAddition_List;
422       if(BuildE2NodeConfigAddList(&(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List))!=ROK)
423       {
424          DU_LOG("\nERROR  -->  E2AP : Failed to E2 Node config addition list");
425          break;
426       }
427
428
429
430       /* Prints the Msg formed */
431       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
432
433       memset(encBuf, 0, ENC_BUF_MAX_LEN);
434       encBufSize = 0;
435       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
436             encBuf);
437       if(encRetVal.encoded == ENCODE_FAIL)
438       {
439          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupRequest structure (at %s)\n",\
440                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
441          break;
442       }
443       else
444       {
445          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2SetupRequest\n");
446 #ifdef DEBUG_ASN_PRINT
447          for(int i=0; i< encBufSize; i++)
448          {
449             printf("%x",encBuf[i]);
450          }
451 #endif
452       }
453       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
454       {
455          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
456       }
457       break;
458    }while(true);
459
460    duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].transactionId = transId;
461    duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
462    
463    FreeE2SetupReq(e2apMsg);
464    return ret;
465 }/* End of BuildAndSendE2SetupReq */
466
467 /*******************************************************************
468  *
469  * @brief Builds Ric Request Id
470  *
471  * @details
472  *
473  *    Function : BuildRicRequestId
474  *
475  *    Functionality: Building the Ric Request Id
476  *
477  * @params[in] RICrequestID_t *ricReqId
478  * @return ROK     - success
479  *         RFAILED - failure
480  *
481  * ****************************************************************/
482
483 uint8_t BuildRicRequestId(RICrequestID_t *ricReqId)
484 {
485    if(ricReqId == NULLP)
486    {
487       return RFAILED;
488    }
489
490    ricReqId->ricRequestorID = 1;
491    ricReqId->ricInstanceID  = 1;
492    return ROK;
493 }
494
495 /*******************************************************************
496  *
497  * @brief Fills the mandatory RicAdmitted List Items
498  *
499  * @details
500  *
501  *    Function : fillRicAdmitList
502  *
503  *    Functionality: Fills the mandatory Ric Admitted List Items
504  *
505  * @params[in] RICaction_Admitted_ItemIEs_t *ricAdmitItems
506  * @return ROK     - success
507  *         RFAILED - failure
508  *
509  * ****************************************************************/
510
511 uint8_t fillRicAdmitList(RICaction_Admitted_ItemIEs_t *ricAdmitItems)
512 {
513
514    if(ricAdmitItems != NULLP)
515    {
516       ricAdmitItems->id = ProtocolIE_IDE2_id_RICaction_Admitted_Item;
517       ricAdmitItems->criticality = CriticalityE2_reject;
518       ricAdmitItems->value.present = RICaction_Admitted_ItemIEs__value_PR_RICaction_Admitted_Item;
519       ricAdmitItems->value.choice.RICaction_Admitted_Item.ricActionID = 1; 
520    }
521    else
522    {
523       return RFAILED;
524    }
525    return ROK;
526 }
527 /*******************************************************************
528  *
529  * @brief Builds the mandatory RicAdmitted List Params
530  *
531  * @details
532  *
533  *    Function : BuildRicAdmitList
534  *
535  *    Functionality: Builds the mandatory Ric Admitted List Params
536  *
537  * @params[in] RICaction_Admitted_List_t *admitListPtr
538  * @return ROK     - success
539  *         RFAILED - failure
540  *
541  * ****************************************************************/
542
543 uint8_t BuildRicAdmitList(RICaction_Admitted_List_t *admitListPtr)
544 {
545    uint8_t idx ;
546    uint8_t elementCnt;  
547    uint8_t ret= ROK;
548    elementCnt = 1;
549
550    if(admitListPtr == NULLP)
551    {
552       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC Admit List failed");
553       ret = RFAILED;
554    }
555    else
556    {
557       admitListPtr->list.count = elementCnt;
558       admitListPtr->list.size  = elementCnt * sizeof(RICaction_Admitted_ItemIEs_t);
559       DU_ALLOC(admitListPtr->list.array, admitListPtr->list.size);
560       if(admitListPtr->list.array == NULLP)
561       {
562          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC Admit List failed");
563          ret = RFAILED;
564       }
565       else
566       {
567          for(idx=0 ; idx<elementCnt ; idx++ )
568          {
569             DU_ALLOC(admitListPtr->list.array[idx], sizeof(RICaction_Admitted_ItemIEs_t));
570             if(admitListPtr->list.array[idx] == NULLP)
571             {
572                ret = RFAILED;
573             }
574          }
575          if(ret != RFAILED)
576          {
577             idx=0;
578             fillRicAdmitList((RICaction_Admitted_ItemIEs_t *)admitListPtr->list.array[idx]);
579          }
580       }
581    }    
582    return ret;
583 }
584 /*******************************************************************
585  *
586  * @breif Deallocation of BuildAndSendRicSubscriptionRsp memory
587  *
588  * @details
589  *
590  *    Function : FreeRicSubscriptionRsp
591  *
592  * Functionality:Free the RicSubscriptionRsp
593  *
594  * @param[in] E2AP_PDU_t *e2apRicMsg
595  *
596  * @return void
597  *      
598  *
599  ******************************************************************/
600 void FreeRicSubscriptionRsp(E2AP_PDU_t  *e2apRicMsg)
601 {
602    RICsubscriptionResponse_t  *ricSubscriptionRsp= NULLP;
603    uint8_t idx=0;
604    uint8_t idx1=0;
605    RICaction_Admitted_List_t *admitListPtr;
606
607    if(e2apRicMsg != NULLP)
608    {
609       if(e2apRicMsg->choice.successfulOutcome != NULLP)
610       {
611          ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
612          if(ricSubscriptionRsp)
613          {
614             if(ricSubscriptionRsp->protocolIEs.list.array != NULLP)
615             {
616                for(idx=0; idx<ricSubscriptionRsp->protocolIEs.list.count; idx++)
617                {
618                   if(ricSubscriptionRsp->protocolIEs.list.array[idx] != NULLP)
619                   {
620                      switch(ricSubscriptionRsp->protocolIEs.list.array[idx]->id)
621                      {
622                         case ProtocolIE_IDE2_id_RICrequestID:
623                            break;
624
625                         case ProtocolIE_IDE2_id_RANfunctionID:
626                            break;
627
628                         case ProtocolIE_IDE2_id_RICactions_Admitted:
629                            {
630                               admitListPtr = &ricSubscriptionRsp->protocolIEs.list.\
631                                              array[idx]->value.choice.RICaction_Admitted_List;
632                               if(admitListPtr->list.array != NULLP)
633                               {
634                                  for(idx1=0 ; idx1<admitListPtr->list.count; idx1++ )
635                                  {
636                                     if(admitListPtr->list.array[idx1] != NULLP)
637                                     {
638                                        DU_FREE(admitListPtr->list.array[idx1],
639                                              sizeof(RICaction_Admitted_ItemIEs_t));
640                                     }
641                                  }
642                                  DU_FREE(admitListPtr->list.array, admitListPtr->list.size);     
643                               }
644                               break;
645                            }
646                         default:
647                            break;
648                      }
649                      DU_FREE(ricSubscriptionRsp->protocolIEs.list.array[idx], \
650                            sizeof(RICsubscriptionResponse_IEs_t));
651                   }
652                }
653                DU_FREE(ricSubscriptionRsp->protocolIEs.list.array, \
654                      ricSubscriptionRsp->protocolIEs.list.size);
655             }
656          }   
657          DU_FREE(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
658       }         
659       DU_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));        
660    }
661 }
662 /*******************************************************************
663  *
664  * @brief Builds and Send the RicSubscriptionRsp
665  *
666  * @details
667  *
668  *    Function : BuildAndSendRicSubscriptionRsp
669  *
670  * functionality:Fills the RicSubscriptionRsp
671  *
672  * @return ROK     - success
673  *         RFAILED - failure
674  *
675  ******************************************************************/
676 uint8_t  FillRicSubscriptionRsp(RICsubscriptionResponse_t  *ricSubscriptionRsp )
677 {
678    uint8_t idx=0;
679    uint8_t ret = ROK;
680    uint8_t elementCnt = 0;
681    uint8_t BuildRicRequestIdret=ROK;
682    uint8_t BuildRicAdmitListret=ROK;
683
684    elementCnt=3;
685    ricSubscriptionRsp->protocolIEs.list.count = elementCnt;
686    ricSubscriptionRsp->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionResponse_IEs_t);
687    DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array, \
688          ricSubscriptionRsp->protocolIEs.list.size);
689    if(ricSubscriptionRsp->protocolIEs.list.array == NULLP)
690    {
691       DU_LOG("\nERROR  -->  E2AP : Memory allocation for FillRicSubscriptionRsp  failed");
692       ret = RFAILED;
693    }
694    else
695    {
696       for(idx=0; idx<ricSubscriptionRsp->protocolIEs.list.count; idx++)
697       {
698          DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array[idx], \
699                sizeof(RICsubscriptionResponse_IEs_t));
700          if(ricSubscriptionRsp->protocolIEs.list.array[idx] == NULLP)
701          {
702             ret = RFAILED;
703          }
704       }
705       if(ret != RFAILED)
706       {
707
708          idx=0;
709          ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
710          ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
711          ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
712                                                                          RICsubscriptionRequest_IEs__value_PR_RICrequestID;
713          BuildRicRequestIdret =
714             BuildRicRequestId(&ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RICrequestID);
715          if(BuildRicRequestIdret != ROK)
716          {
717             ret = RFAILED;
718          }
719          else
720          {
721             idx++;
722             ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
723             ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
724             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
725                                                                             RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
726             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1;
727
728             idx++;
729             ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactions_Admitted;
730             ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
731             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
732                                                                             RICsubscriptionResponse_IEs__value_PR_RICaction_Admitted_List;
733             BuildRicAdmitListret =
734                BuildRicAdmitList(&ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RICaction_Admitted_List);
735             if(BuildRicAdmitListret != ROK)
736             {
737                ret = RFAILED;
738             }
739          }
740       }
741    }    
742    return ret;
743 }
744 /*******************************************************************
745  *
746  * @brief Builds and Send the RicSubscriptionRsp
747  *
748  * @details
749  *
750  *    Function : BuildAndSendRicSubscriptionRsp
751  *
752  * Functionality:Fills the RicSubscriptionRsp
753  *
754  * @return ROK     - success
755  *         RFAILED - failure
756  *
757  ******************************************************************/
758
759 uint8_t BuildAndSendRicSubscriptionRsp()
760 {
761
762    E2AP_PDU_t         *e2apRicMsg = NULLP;
763    RICsubscriptionResponse_t  *ricSubscriptionRsp=NULLP;
764    asn_enc_rval_t     encRetVal; 
765    uint8_t ret = RFAILED;
766    uint8_t FillRicricSubscriptionRspret;
767
768    while(true)
769    {
770       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Response\n");
771
772       DU_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t)); 
773       if(e2apRicMsg == NULLP)
774       {
775          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
776          break;
777       }
778       e2apRicMsg->present =  E2AP_PDU_PR_successfulOutcome;
779       DU_ALLOC(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
780       if(e2apRicMsg->choice.successfulOutcome == NULLP)
781       {
782          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC subscription Response failed");
783          break;
784       }
785
786       e2apRicMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
787       e2apRicMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
788       e2apRicMsg->choice.successfulOutcome->value.present = \
789                                                             SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse;
790       ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
791
792       FillRicricSubscriptionRspret = FillRicSubscriptionRsp(ricSubscriptionRsp);
793       if(FillRicricSubscriptionRspret != ROK)
794       {
795          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICsubscriptionResponseIE failed");
796          break;
797       }
798
799       /* Prints the Msg formed */
800       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
801
802       memset(encBuf, 0, ENC_BUF_MAX_LEN);
803       encBufSize = 0;
804       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\
805             encBuf);
806       if(encRetVal.encoded == ENCODE_FAIL)
807       {
808          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Response structure (at %s)\n",\
809                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
810          break;
811       }
812       else
813       {
814          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RIC subscription response \n");
815 #ifdef DEBUG_ASN_PRINT
816          for(int i=0; i< encBufSize; i++)
817          {
818             printf("%x",encBuf[i]);
819          } 
820 #endif
821       } 
822
823       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
824       {
825          DU_LOG("\nERROR  -->  E2AP : Sending RIC Subscription Response failed");      
826          break;
827       }
828
829       ret = ROK;
830       break;
831
832    }
833    FreeRicSubscriptionRsp(e2apRicMsg);
834
835    return ret;
836 }
837
838 /******************************************************************
839  *
840  * @brief Deallocation of memory allocated bu aper decoder for e2 setup response
841  *
842  * @details
843  *
844  *    Function : freeAperDecodingOfE2SetupRsp
845  *
846  *    Functionality: Deallocation of memory allocated bu aper decoder for e2
847  *    setup response
848  *
849  * @params[in] E2setupResponse_t *e2SetRspMsg;
850  * @return void
851  *
852  * ****************************************************************/
853 void freeAperDecodingOfE2SetupRsp(E2setupResponse_t *e2SetRspMsg)
854 {
855    uint8_t arrIdx, e2NodeConfigAddAckListIdx;
856    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem;
857    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAddAckList;
858
859    if(e2SetRspMsg)
860    {
861       if(e2SetRspMsg->protocolIEs.list.array)
862       {
863          for(arrIdx=0; arrIdx<e2SetRspMsg->protocolIEs.list.count; arrIdx++)
864          {
865             if(e2SetRspMsg->protocolIEs.list.array[arrIdx])
866             {
867                switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
868                {
869                   case ProtocolIE_IDE2_id_TransactionID:
870                      break;
871
872                   case ProtocolIE_IDE2_id_GlobalRIC_ID:
873                      {
874                         free(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.pLMN_Identity.buf);
875                         free(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID.buf);
876                         break;
877                      }
878
879                   case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
880                      {
881                         e2NodeConfigAddAckList = &e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
882                         if(e2NodeConfigAddAckList->list.array )
883                         {
884                            for(e2NodeConfigAddAckListIdx = 0; e2NodeConfigAddAckListIdx< e2NodeConfigAddAckList->list.count; e2NodeConfigAddAckListIdx++)
885                            {
886                               if(e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx])
887                               {
888                                  e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx];
889                                  free(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.\
890                                        e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf);
891                                  free(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.\
892                                        e2nodeComponentInterfaceTypeF1);
893                                  free(e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx]);
894                               }
895                            }
896                            free(e2NodeConfigAddAckList->list.array);
897                         }
898                         break;
899                      }
900                }
901                free(e2SetRspMsg->protocolIEs.list.array[arrIdx]);  
902             }
903          }
904          free(e2SetRspMsg->protocolIEs.list.array);
905       }
906    }
907 }
908 /******************************************************************
909  *
910  * @brief Processes E2 Setup Response sent by RIC
911  *
912  * @details
913  *
914  *    Function : procE2SetupRsp
915  *
916  *    Functionality: Processes E2 Setup Response sent by RIC
917  *
918  * @params[in] E2AP_PDU_t ASN decoded E2AP message
919  * @return ROK     - success
920  *         RFAILED - failure
921  *
922  * ****************************************************************/
923 uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg)
924 {
925    uint8_t arrIdx =0, transId=0; 
926    uint32_t recvBufLen;             
927    E2setupResponse_t *e2SetRspMsg;
928
929    DU_LOG("\nINFO   -->  E2AP : E2 Setup Response received"); 
930    duCb.e2Status = TRUE; //Set E2 status as true
931    e2SetRspMsg = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
932
933    for(arrIdx=0; arrIdx<e2SetRspMsg->protocolIEs.list.count; arrIdx++)
934    {
935       switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
936       {
937          case ProtocolIE_IDE2_id_TransactionID:
938             {
939                transId = e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
940                if((duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].transactionId == transId) &&\
941                      (duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
942                   memset(&duCb.e2apDb.e2TransInfo.onGoingTransaction[transId], 0, sizeof(E2TransInfo));
943                else
944                {
945                   DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
946                   return RFAILED;
947                }
948                break;
949             }
950
951          case ProtocolIE_IDE2_id_GlobalRIC_ID:
952             {
953                /* To store the Ric Id Params */
954                recvBufLen = sizeof(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value\
955                      .choice.GlobalRIC_ID.pLMN_Identity.size);
956                duCb.e2apDb.plmn = NULLP;
957                DU_ALLOC(duCb.e2apDb.plmn, recvBufLen);
958                if(duCb.e2apDb.plmn)
959                {
960                   memcpy(duCb.e2apDb.plmn, e2SetRspMsg->protocolIEs.list.array[arrIdx]\
961                         ->value.choice.GlobalRIC_ID.pLMN_Identity.buf, recvBufLen);
962                }
963                bitStringToInt(&e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID, &duCb.e2apDb.ricId);
964                /*TODO : duCb.e2apDb.plmn memory to be deallocated after the usage */
965                break;
966             }
967
968          case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
969             break;
970
971          default:
972             DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2SetupRsp:%ld",
973                   e2SetRspMsg->protocolIEs.list.array[arrIdx]->id);
974             break;
975       }
976    }
977    freeAperDecodingOfE2SetupRsp(e2SetRspMsg);
978    
979    DU_FREE(duCb.f1SetupReqAndRspMsg.f1MsgReqBuf,duCb.f1SetupReqAndRspMsg.f1MsgReqBufSize);
980    DU_FREE(duCb.f1SetupReqAndRspMsg.f1MsgRspBuf, duCb.f1SetupReqAndRspMsg.f1MsgRspBufSize); 
981    
982    BuildAndSendE2NodeConfigUpdate();
983    return ROK;
984 }
985
986 /******************************************************************
987  *
988  * @brief Processes RIC Subscription Req sent by RIC
989  *
990  * @details
991  *
992  *    Function : procRicSubsReq
993  *
994  *    Functionality: Processes E2 Setup Response sent by CU
995  *
996  * @params[in] E2AP_PDU_t ASN decoded E2AP message
997  * @return ROK     - success
998  *         RFAILED - failure
999  *
1000  * ****************************************************************/
1001
1002 uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg)
1003 {
1004    uint8_t idx; 
1005    uint8_t ied; 
1006    uint8_t ret = ROK;
1007    uint32_t recvBufLen;             
1008    RICsubscriptionRequest_t *ricSubsReq;
1009    RICaction_ToBeSetup_ItemIEs_t *actionItem;
1010
1011    DU_LOG("\nINFO   -->  E2AP : RIC Subscription request received"); 
1012    ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
1013
1014    for(idx=0; idx<ricSubsReq->protocolIEs.list.count; idx++)
1015    {
1016       if(ricSubsReq->protocolIEs.list.array[idx])
1017       {
1018          switch(ricSubsReq->protocolIEs.list.array[idx]->id)
1019          {
1020             case ProtocolIE_IDE2_id_RICrequestID:
1021                {
1022                   duCb.e2apDb.ricReqId = ricSubsReq->protocolIEs.list.array[idx]->\
1023                                          value.choice.RICrequestID.ricRequestorID;
1024                   duCb.e2apDb.ricInstanceId = ricSubsReq->protocolIEs.list.array[idx]-> \
1025                                               value.choice.RICrequestID.ricInstanceID;
1026                   break;
1027                }
1028             case ProtocolIE_IDE2_id_RANfunctionID:
1029                {
1030                   duCb.e2apDb.ranFuncId = ricSubsReq->protocolIEs.list.array[idx]-> \
1031                                           value.choice.RANfunctionID; 
1032                   break;
1033                }
1034             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
1035                {
1036                   recvBufLen = sizeof(ricSubsReq->protocolIEs.list.array[idx]->value\
1037                         .choice.RICsubscriptionDetails.ricEventTriggerDefinition.size);
1038                   duCb.e2apDb.ricEventTrigger = NULLP;
1039                   DU_ALLOC(duCb.e2apDb.ricEventTrigger, recvBufLen);
1040                   /*TODO : duCb.e2apDb.ricEventTrigger memory to be deallocated after the usage */
1041                   if(duCb.e2apDb.ricEventTrigger)
1042                   {
1043                      memcpy(duCb.e2apDb.ricEventTrigger, ricSubsReq->protocolIEs.list.array[idx]\
1044                            ->value.choice.RICsubscriptionDetails.ricEventTriggerDefinition.buf, \
1045                            recvBufLen);
1046                      free(ricSubsReq->protocolIEs.list.array[idx]->value.choice.\
1047                            RICsubscriptionDetails.ricEventTriggerDefinition.buf);
1048                   }
1049                   if(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\
1050                         list.array)
1051                   {
1052                      actionItem =(RICaction_ToBeSetup_ItemIEs_t *)ricSubsReq->protocolIEs.list\
1053                                  .array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List\
1054                                  .list.array[0];
1055
1056                      for(ied = 0; ied < ricSubsReq->protocolIEs.list.array[idx]->value.choice.\
1057                            RICsubscriptionDetails.ricAction_ToBeSetup_List.list.count; ied++)
1058                      {
1059                         switch(actionItem->id)
1060                         {
1061                            case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item:
1062                               {
1063                                  duCb.e2apDb.ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
1064                                  duCb.e2apDb.ricActionType = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType;
1065                                  break;
1066                               }
1067                            default:
1068                               DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id);
1069                               break;
1070                         }
1071                         free(actionItem);
1072                      }
1073                      free(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\
1074                            list.array);
1075                   }
1076                   break;
1077                }
1078
1079             default:
1080                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RIC SubsReq:%ld",
1081                      ricSubsReq->protocolIEs.list.array[idx]->id);
1082                break;
1083          }
1084          free(ricSubsReq->protocolIEs.list.array[idx]);
1085       }
1086    }
1087    free(ricSubsReq->protocolIEs.list.array);
1088    ret = BuildAndSendRicSubscriptionRsp();
1089
1090    return ret;
1091 }
1092
1093 /*******************************************************************
1094  *
1095  * @brief Free the RicIndication Message
1096  *
1097  * @details
1098  *
1099  *    Function : FreeRicIndication
1100  *
1101  * Functionality: Free the RicIndication Message
1102  *
1103  * @return void
1104  *         
1105  *
1106  ******************************************************************/
1107 void FreeRicIndication(E2AP_PDU_t  *e2apMsg) 
1108 {
1109    uint8_t idx=0;
1110    RICindication_t *ricIndicationMsg= NULLP;
1111
1112
1113    if(e2apMsg != NULLP)
1114    {
1115       if(e2apMsg->choice.initiatingMessage != NULLP)
1116       {
1117          ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
1118          if(ricIndicationMsg!= NULLP)
1119          {
1120             if(ricIndicationMsg->protocolIEs.list.array != NULLP)
1121             {
1122                for(idx=0; idx<ricIndicationMsg->protocolIEs.list.count; idx++)
1123                {
1124                   if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP)
1125                   {
1126                      switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
1127                      {
1128                         case ProtocolIE_IDE2_id_RICrequestID:
1129                            break;
1130
1131                         case ProtocolIE_IDE2_id_RANfunctionID:
1132                            break;
1133
1134                         case ProtocolIE_IDE2_id_RICactionID:
1135                            break;
1136
1137                         case ProtocolIE_IDE2_id_RICindicationType:
1138                            break;
1139
1140                         case ProtocolIE_IDE2_id_RICindicationHeader:
1141                            {
1142                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\
1143                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
1144                               break;
1145                            }
1146                         case ProtocolIE_IDE2_id_RICindicationMessage:
1147                            {
1148                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\
1149                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
1150                               break;
1151                            }
1152                         default:
1153                            break;
1154                      }
1155                      DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t));
1156                   }
1157                }
1158                DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size);
1159             }
1160          }
1161          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1162       }
1163       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1164    }
1165 }
1166 /*******************************************************************
1167  *
1168  * brief Fill the RicIndication Message
1169  *
1170  * @details
1171  *
1172  *    Function : FillRicIndication
1173  *
1174  * Functionality:Fills the RicIndication Message
1175  *
1176  * @return ROK     - success
1177  *         RFAILED - failure
1178  *
1179  ******************************************************************/
1180 uint8_t FillRicIndication(RICindication_t *ricIndicationMsg)
1181 {
1182    uint8_t elementCnt=0;
1183    uint8_t idx=0;
1184    uint8_t ret = ROK;
1185    elementCnt = 6;
1186
1187    ricIndicationMsg->protocolIEs.list.count = elementCnt;
1188    ricIndicationMsg->protocolIEs.list.size  = elementCnt * sizeof(RICindication_t);
1189    /* Initialize the Ric Indication members */
1190    DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, \
1191          ricIndicationMsg->protocolIEs.list.size);
1192    if(ricIndicationMsg->protocolIEs.list.array == NULLP)
1193    {
1194       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1195       ret = RFAILED;
1196    }
1197    else
1198    {
1199       for(idx=0; idx<elementCnt; idx++)
1200       {
1201          DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx],\
1202                sizeof(RICindication_IEs_t));
1203          if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
1204          {
1205             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1206             ret = RFAILED;
1207          }
1208       }
1209       if(ret != RFAILED)
1210       {
1211          idx = 0;
1212
1213          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
1214          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1215          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1216                                                                         RICindication_IEs__value_PR_RICrequestID;
1217          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID =\
1218                                                                                                   duCb.e2apDb.ricReqId;
1219          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID =\
1220                                                                                                  duCb.e2apDb.ricInstanceId;
1221
1222          idx++;
1223          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
1224          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1225          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1226                                                                         RICindication_IEs__value_PR_RANfunctionID;
1227          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID =
1228             duCb.e2apDb.ranFuncId;
1229
1230          idx++;
1231          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
1232          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1233          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1234                                                                         RICindication_IEs__value_PR_RICactionID;
1235          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID =
1236             duCb.e2apDb.ricActionId;
1237
1238          idx++;
1239          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
1240          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1241          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1242                                                                         RICindication_IEs__value_PR_RICindicationType;
1243          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType =
1244             duCb.e2apDb.ricActionType;
1245
1246          idx++;
1247          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
1248          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1249          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1250                                                                         RICindication_IEs__value_PR_RICindicationHeader;
1251          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size = 3 *
1252             sizeof(uint8_t);
1253          DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf ,\
1254                ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
1255          if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf == NULLP)
1256          {
1257             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1258             ret = RFAILED;
1259          }
1260          else
1261          {
1262             buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
1263                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf);
1264             idx++;
1265             /* TO BE CHANGED: RIC INDICATION DATA */
1266             /* For now filling a dummy octect data, need to tested with PRBs*/
1267             ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
1268             ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1269             ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1270                                                                            RICindication_IEs__value_PR_RICindicationMessage;
1271             ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size = 3 *
1272                sizeof(uint8_t);
1273             DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf ,\
1274                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
1275             if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf == NULLP)
1276             {
1277                DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1278                ret = RFAILED;
1279             }
1280             else
1281             {
1282                buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
1283                      ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf);
1284             }
1285          }
1286       }
1287    }
1288    return ret;
1289 }
1290
1291 /*******************************************************************
1292  *
1293  * @brief Builds and Send the RicIndication Message
1294  *
1295  * @details
1296  *
1297  *    Function : BuildAndSendRicIndication
1298  *
1299  * Functionality:Fills the RicIndication Message
1300  *
1301  * @return ROK     - success
1302  *         RFAILED - failure
1303  *
1304  ******************************************************************/
1305
1306 uint8_t BuildAndSendRicIndication()
1307 {
1308    E2AP_PDU_t                 *e2apMsg = NULLP;
1309    RICindication_t            *ricIndicationMsg=NULLP;
1310    asn_enc_rval_t             encRetVal;        /* Encoder return value */
1311    uint8_t ret = RFAILED; 
1312    uint8_t FillRicIndicationret = ROK;
1313
1314    while(true)
1315    {
1316       DU_LOG("\nINFO   -->  E2AP : Building RIC Indication Message\n");
1317
1318       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1319       if(e2apMsg == NULLP)
1320       {
1321          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1322          break;
1323       }
1324
1325       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
1326       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1327       if(e2apMsg->choice.initiatingMessage == NULLP)
1328       {
1329          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1330          break;
1331       }
1332       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
1333       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
1334       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication;
1335
1336       ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
1337
1338       FillRicIndicationret = FillRicIndication(ricIndicationMsg);
1339       if(FillRicIndicationret != ROK)
1340       {
1341          break;
1342       }
1343       /* Prints the Msg formed */
1344       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1345       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1346       encBufSize = 0;
1347       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
1348             encBuf);
1349       if(encRetVal.encoded == ENCODE_FAIL)
1350       {
1351          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Indication Message (at %s)\n",\
1352                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1353          break;
1354       }
1355       else
1356       {
1357          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Indication Message \n");
1358 #ifdef DEBUG_ASN_PRINT
1359          for(int i=0; i< encBufSize; i++)
1360          {
1361             printf("%x",encBuf[i]);
1362          } 
1363 #endif
1364       }
1365
1366       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
1367       {
1368          DU_LOG("\nINFO   -->  E2AP : Sending RIC Indication Message");      
1369
1370       }
1371       ret = ROK;
1372       break;
1373    }
1374    FreeRicIndication(e2apMsg);  
1375    return ret;
1376 }
1377
1378 /*******************************************************************
1379  *
1380  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
1381  *
1382  * @details
1383  *
1384  *    Function : FreeE2NodeConfigUpdate 
1385  *
1386  *    Functionality:
1387  *       - freeing the memory allocated for E2nodeConfigurationUpdate
1388  *
1389  * @params[in] E2AP_PDU_t *e2apMsg 
1390  * @return ROK     - success
1391  *         RFAILED - failure
1392  *
1393  * ****************************************************************/
1394 void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg)
1395 {
1396    uint8_t arrIdx =0;
1397    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate;
1398
1399    if(e2apMsg != NULLP)
1400    {
1401       if(e2apMsg->choice.initiatingMessage != NULLP)
1402       {
1403          e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
1404          if(e2NodeConfigUpdate->protocolIEs.list.array != NULLP)
1405          {
1406             for(arrIdx = 0; arrIdx < e2NodeConfigUpdate->protocolIEs.list.count; arrIdx++)
1407             {
1408                DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
1409             }
1410             DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
1411          }
1412          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1413       }
1414       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1415    }
1416 }
1417
1418 /*******************************************************************
1419  *
1420  * @brief Buld and send the E2 node config update msg 
1421  *
1422  * @details
1423  *
1424  *    Function : BuildAndSendE2NodeConfigUpdate
1425  *
1426  *    Functionality:
1427  *         - Buld and send the E2 node config update msg
1428  *
1429  * @params[in] 
1430  * @return ROK     - success
1431  *         RFAILED - failure
1432  *
1433  * ****************************************************************/
1434
1435 uint8_t BuildAndSendE2NodeConfigUpdate()
1436 {
1437    uint8_t arrIdx = 0,elementCnt = 1;
1438    uint8_t ret = ROK;
1439    E2AP_PDU_t        *e2apMsg = NULLP;
1440    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate = NULLP;
1441    asn_enc_rval_t     encRetVal;       /* Encoder return value */
1442
1443    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update\n");
1444    do
1445    {
1446       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1447       if(e2apMsg == NULLP)
1448       {
1449          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1450          break;
1451       }
1452       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
1453       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1454       if(e2apMsg->choice.initiatingMessage == NULLP)
1455       {
1456          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1457          DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1458          return RFAILED;
1459       }
1460       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
1461       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
1462       e2apMsg->choice.initiatingMessage->value.present = \
1463       InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate;
1464       e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
1465
1466       e2NodeConfigUpdate->protocolIEs.list.count = elementCnt;
1467       e2NodeConfigUpdate->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdate_IEs_t*);
1468       /* Initialize the Ric Indication members */
1469       DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array, \
1470             e2NodeConfigUpdate->protocolIEs.list.size);
1471       if(e2NodeConfigUpdate->protocolIEs.list.array == NULLP)
1472       {
1473          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
1474          break;
1475       }
1476       
1477       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
1478       {
1479          DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
1480          if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx] == NULLP)
1481          {
1482             
1483             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
1484             break;
1485          }
1486       }
1487
1488       arrIdx = 0;
1489       /* TransactionID */
1490       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
1491       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1492       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_TransactionID;
1493       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = TRANS_ID;
1494
1495
1496       /* Prints the Msg formed */
1497       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1498
1499       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1500       encBufSize = 0;
1501       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
1502             encBuf);
1503       if(encRetVal.encoded == ENCODE_FAIL)
1504       {
1505          DU_LOG("\nERROR  -->  E2AP : Could not encode E2nodeConfigurationUpdate structure (at %s)\n",\
1506                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1507          break;
1508       }
1509       else
1510       {
1511          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2nodeConfigurationUpdate\n");
1512 #ifdef DEBUG_ASN_PRINT
1513          for(int i=0; i< encBufSize; i++)
1514          {
1515             printf("%x",encBuf[i]);
1516          }
1517 #endif
1518       }
1519       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize))
1520       {
1521          DU_LOG("\nERROR  -->  E2AP : Sending E2 node config update failed");
1522          return RFAILED;
1523       }
1524
1525       break;
1526    }while(true);
1527    
1528    FreeE2NodeConfigUpdate(e2apMsg);
1529    return ret;
1530 }
1531
1532 /*******************************************************************
1533  *
1534  * @brief Deallocate the memory allocated for E2ResetRequest msg
1535  *
1536  * @details
1537  *
1538  *    Function : FreeE2ResetRequest
1539  *
1540  *    Functionality:
1541  *       - freeing the memory allocated for E2ResetRequest
1542  *
1543  * @params[in] E2AP_PDU_t *e2apMsg
1544  * @return ROK     - success
1545  *         RFAILED - failure
1546  *
1547  * ****************************************************************/
1548 void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg)
1549 {
1550    uint8_t ieIdx =0;
1551    ResetRequestE2_t  *resetReq = NULLP;
1552
1553    if(e2apMsg != NULLP)
1554    {
1555       if(e2apMsg->choice.initiatingMessage != NULLP)
1556       {
1557          resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
1558          if(resetReq->protocolIEs.list.array)
1559          {
1560             for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
1561             {
1562                DU_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
1563             }
1564             DU_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
1565          }
1566          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1567       }
1568       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1569    }
1570 }
1571
1572 /*******************************************************************
1573  *
1574  * @brief Build and send the E2 reset request msg
1575  *
1576  * @details
1577  *
1578  *    Function : BuildAndSendE2ResetRequest
1579  *
1580  *    Functionality:
1581  *         - Buld and send the E2 reset request msg to RIC
1582  *
1583  * @params[in]
1584  * @return ROK     - success
1585  *         RFAILED - failure
1586  *
1587  * ****************************************************************/
1588 uint8_t BuildAndSendE2ResetRequest(E2CauseType failureType, E2Cause failureCause)
1589 {
1590    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
1591    uint8_t ret = RFAILED;
1592    E2AP_PDU_t        *e2apMsg = NULLP;
1593    ResetRequestE2_t  *resetReq = NULLP;
1594    asn_enc_rval_t     encRetVal;       /* Encoder return value */
1595
1596    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Request\n");
1597
1598    do
1599    {
1600       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1601       if(e2apMsg == NULLP)
1602       {
1603          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for E2AP-PDU failed");
1604          break;
1605       }
1606
1607       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
1608       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1609       if(e2apMsg->choice.initiatingMessage == NULLP)
1610       {
1611          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for initiatingMessage");
1612          break;
1613       }
1614
1615       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
1616       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
1617       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
1618       resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
1619
1620       elementCnt = 2;
1621       resetReq->protocolIEs.list.count = elementCnt;
1622       resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
1623
1624       DU_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
1625       if(!resetReq->protocolIEs.list.array)
1626       {
1627          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
1628             Reset Request IE array");
1629          break;
1630       }
1631
1632       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
1633       {
1634          DU_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
1635          if(!resetReq->protocolIEs.list.array[ieIdx])
1636          {
1637             DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
1638             Reset Request IE array element");
1639             break;
1640          }
1641       }
1642
1643       /* In case of failure */
1644       if(ieIdx < elementCnt)
1645          break;
1646
1647       ieIdx = 0;
1648       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
1649       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
1650       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
1651       transId = assignTransactionId();
1652       resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
1653
1654       ieIdx++;
1655       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
1656       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
1657       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
1658       resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present = failureType;
1659       switch(resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present)
1660       {
1661          case CauseE2_PR_NOTHING:
1662             break;
1663          case CauseE2_PR_ricRequest:
1664             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricRequest = failureCause;
1665             break;
1666          case CauseE2_PR_ricService:
1667             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricService = failureCause;
1668             break;
1669          case CauseE2_PR_e2Node:
1670             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.e2Node = failureCause;
1671             break;
1672          case CauseE2_PR_transport:
1673             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.transport = failureCause;
1674             break;
1675          case CauseE2_PR_protocol:
1676             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.protocol = failureCause;
1677             break;
1678          case CauseE2_PR_misc:
1679             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.misc = failureCause;
1680             break;
1681       }
1682
1683       /* Prints the Msg formed */
1684       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1685
1686       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1687       encBufSize = 0;
1688       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
1689             encBuf);
1690       if(encRetVal.encoded == ENCODE_FAIL)
1691       {
1692          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupRequest structure (at %s)\n",\
1693                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1694          break;
1695       }
1696       else
1697       {
1698          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2SetupRequest\n");
1699 #ifdef DEBUG_ASN_PRINT
1700          for(int i=0; i< encBufSize; i++)
1701          {
1702             printf("%x",encBuf[i]);
1703          }
1704 #endif
1705       }
1706       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
1707       {
1708          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
1709          break;
1710       }
1711
1712       /* In case the message is sent successfully, store the transaction info to
1713        * be used when response is received */
1714       duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].transactionId = transId;
1715       duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
1716
1717       ret = ROK;
1718       break;
1719    }while(true);
1720
1721    /* Free all memory */
1722    FreeE2ResetRequest(e2apMsg);
1723    return ret;
1724 }
1725
1726 /*******************************************************************
1727  *
1728  * @brief Deallocate the memory allocated for Reset Response msg
1729  *
1730  * @details
1731  *
1732  *    Function : freeAperDecodingOfE2ResetRsp
1733  *
1734  *    Functionality:
1735  *       - freeing the memory allocated for Reset response
1736  *
1737  * @params[in] ResetResponseE2_t *resetResponse
1738  * @return void
1739  *
1740  * ****************************************************************/
1741 void freeAperDecodingOfE2ResetRsp(ResetResponseE2_t *resetResponse)
1742 {
1743    uint8_t ieIdx;
1744
1745    if(resetResponse)
1746    {
1747       if(resetResponse->protocolIEs.list.array)
1748       {
1749          for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
1750          {
1751             if(resetResponse->protocolIEs.list.array[ieIdx])
1752             {
1753                switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
1754                {
1755                   case ProtocolIE_IDE2_id_TransactionID:
1756                      break;
1757
1758                   case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
1759                      break;
1760                }
1761                free(resetResponse->protocolIEs.list.array[ieIdx]);
1762             }
1763          }
1764          free(resetResponse->protocolIEs.list.array);
1765       }
1766    }
1767 }
1768
1769 /******************************************************************
1770  *
1771  * @brief Processes E2 Reset Response sent by RIC
1772  *
1773  * @details
1774  *
1775  *    Function : procResetResponse
1776  *
1777  *    Functionality: Processes E2 Reset Response sent by RIC
1778  *
1779  * @params[in] E2AP_PDU_t ASN decoded E2AP message
1780  * @return ROK     - success
1781  *         RFAILED - failure
1782  *
1783  * ****************************************************************/
1784 uint8_t procResetResponse(E2AP_PDU_t *e2apMsg)
1785 {
1786    uint8_t ieIdx =0, transId;
1787    ResetResponseE2_t *resetResponse;
1788
1789    DU_LOG("\nINFO   -->  E2AP : E2 Reset Response received");
1790    resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;;
1791
1792    for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
1793    {
1794       switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
1795       {
1796          case ProtocolIE_IDE2_id_TransactionID:
1797             transId = resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
1798             if((duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].transactionId == transId) && \
1799                   (duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
1800               memset(&duCb.e2apDb.e2TransInfo.onGoingTransaction[transId], 0, sizeof(E2TransInfo));
1801             else
1802             {
1803                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
1804                return RFAILED;
1805             }
1806             break;
1807          case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
1808             /* As per ORAN WG3 E2AP spec v3.0, section 9.2.2
1809                Criticality Diagnostics IE is sent by Near-RT RIC when parts of a received message i.e. 
1810                Reset Request in this case, have not been comprehended or were missing, or if the message 
1811                contained logical errors.
1812
1813                Processing of this ID should be implemented when negative call flows are to be supported.
1814              */
1815             break;
1816          default:
1817             DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2 Reset Response : %ld",
1818                   resetResponse->protocolIEs.list.array[ieIdx]->id);
1819             break;
1820       }
1821    }
1822
1823    freeAperDecodingOfE2ResetRsp(resetResponse);
1824    return ROK;
1825 }
1826
1827 /******************************************************************
1828  *
1829  * @brief Deallocation of memory allocated bu aper decoder for e2 setup Failure
1830  *
1831  * @details
1832  *
1833  *    Function : freeAperDecodingOfE2SetupFailure
1834  *
1835  *    Functionality: Deallocation of memory allocated bu aper decoder for e2
1836  *    setup Failure
1837  *
1838  * @params[in] E2setupFailure_t *e2SetupFailure;
1839  * @return void
1840  *
1841  * ****************************************************************/
1842 void freeAperDecodingOfE2SetupFailure(E2setupFailure_t *e2SetupFailure)
1843 {
1844    uint8_t arrIdx;
1845
1846    if(e2SetupFailure)
1847    {
1848       if(e2SetupFailure->protocolIEs.list.array)
1849       {
1850          for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
1851          {
1852             if(e2SetupFailure->protocolIEs.list.array[arrIdx])
1853             {
1854                free(e2SetupFailure->protocolIEs.list.array[arrIdx]);  
1855             }
1856          }
1857          free(e2SetupFailure->protocolIEs.list.array);
1858       }
1859    }
1860 }
1861 /******************************************************************
1862  *
1863  * @brief Processes E2 Setup Failure sent by RIC
1864  *
1865  * @details
1866  *
1867  *    Function : procE2SetupFailure
1868  *
1869  *    Functionality: Processes E2 Setup failure sent by RIC
1870  *
1871  * @params[in] E2AP_PDU_t ASN decoded E2AP message
1872  * @return ROK     - success
1873  *         RFAILED - failure
1874  *
1875  * ****************************************************************/
1876 void procE2SetupFailure(E2AP_PDU_t *e2apMsg)
1877 {
1878    uint8_t arrIdx =0, transId =0, timerValue=0; 
1879    E2setupFailure_t *e2SetupFailure;
1880
1881    DU_LOG("\nINFO   -->  E2AP : E2 Setup failure received"); 
1882    e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
1883
1884    for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
1885    {
1886       switch(e2SetupFailure->protocolIEs.list.array[arrIdx]->id)
1887       {
1888          case ProtocolIE_IDE2_id_TransactionID:
1889          {
1890             transId = e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
1891             if((duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].transactionId == transId) &&\
1892             (duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
1893               memset(&duCb.e2apDb.e2TransInfo.onGoingTransaction[transId], 0, sizeof(E2TransInfo));
1894             else
1895             {
1896                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
1897                return ;
1898             }
1899             break;
1900          }
1901          case ProtocolIE_IDE2_id_TimeToWaitE2:
1902             {
1903                timerValue = covertE2WaitTimerEnumToValue(e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
1904                if((duChkTmr((PTR)&(duCb.e2apDb), EVENT_E2_SETUP_TMR)) == FALSE)
1905                {
1906                   duStartTmr((PTR)&(duCb.e2apDb), EVENT_E2_SETUP_TMR, timerValue);
1907                }
1908                else
1909                {
1910                   DU_LOG("\nERROR   -->  E2AP : EVENT_E2_SETUP_TMR timer is already running");
1911                   return;
1912                }
1913                break; 
1914             }
1915       }
1916    }
1917
1918    freeAperDecodingOfE2SetupFailure(e2SetupFailure);
1919 }
1920 /*******************************************************************
1921  *
1922  * @brief Handles received E2AP message and sends back response  
1923  *
1924  * @details
1925  *
1926  *    Function : E2APMsgHdlr
1927  *
1928  *    Functionality:
1929  *         - Decodes received E2AP control message
1930  *         - Prepares response message, encodes and sends to SCTP
1931  *
1932  * @params[in] 
1933  * @return ROK     - success
1934  *         RFAILED - failure
1935  *
1936  * ****************************************************************/
1937 void E2APMsgHdlr(Buffer *mBuf)
1938 {
1939    int i =0;
1940    char *recvBuf = NULLP;
1941    MsgLen copyCnt =0;
1942    MsgLen recvBufLen =0;
1943    E2AP_PDU_t *e2apMsg = NULLP;
1944    asn_dec_rval_t rval ={0}; /* Decoder return value */
1945    E2AP_PDU_t e2apasnmsg={0} ;
1946
1947    DU_LOG("\nDEBUG   -->  E2AP : Received E2AP message buffer");
1948    ODU_PRINT_MSG(mBuf, 0,0);
1949
1950    /* Copy mBuf into char array to decode it */
1951    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
1952    DU_ALLOC(recvBuf, (Size)recvBufLen);
1953
1954    if(recvBuf == NULLP)
1955    {
1956       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
1957       return;
1958    }
1959    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
1960    {
1961       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
1962       return;
1963    }
1964
1965 #ifdef DEBUG_ASN_PRINT
1966    printf("\nDEBUG   -->  E2AP : Received flat buffer to be decoded : ");
1967    for(i=0; i< recvBufLen; i++)
1968    {
1969       printf("%x",recvBuf[i]);
1970    }
1971 #endif
1972
1973    /* Decoding flat buffer into E2AP messsage */
1974    e2apMsg = &e2apasnmsg;
1975    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
1976
1977    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
1978    DU_FREE(recvBuf, (Size)recvBufLen);
1979
1980    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
1981    {
1982       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
1983       return;
1984    }
1985    printf("\n");
1986    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1987
1988    switch(e2apMsg->present)
1989    {
1990       case E2AP_PDU_PR_unsuccessfulOutcome:
1991          {
1992             switch(e2apMsg->choice.unsuccessfulOutcome->value.present)
1993             {
1994                case UnsuccessfulOutcomeE2__value_PR_E2setupFailure:
1995                   {
1996                      procE2SetupFailure(e2apMsg);
1997                      break;
1998                   }
1999                default:
2000                   {
2001                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome  [%d]",\
2002                            e2apMsg->choice.unsuccessfulOutcome->value.present);
2003                      return;
2004                   }
2005             }
2006             break;
2007          }
2008       case E2AP_PDU_PR_successfulOutcome:
2009          {
2010             switch(e2apMsg->choice.successfulOutcome->value.present)
2011             {
2012                case SuccessfulOutcomeE2__value_PR_E2setupResponse:
2013                   {
2014                      if(!duCb.e2Status)
2015                      {
2016                         procE2SetupRsp(e2apMsg);
2017                      }
2018                      break;
2019                   }
2020                case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge:
2021                   {
2022                      DU_LOG("\nDEBUG   -->  E2AP : E2 node Config update ack message recevied");
2023                      break;
2024                   }
2025                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
2026                   {
2027                      procResetResponse(e2apMsg);
2028                      break;
2029                   }
2030                default:
2031                   {
2032                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome  [%d]",\
2033                            e2apMsg->choice.successfulOutcome->value.present);
2034                      return;
2035                   }
2036             }/* End of switch(successfulOutcome) */
2037             free(e2apMsg->choice.successfulOutcome);
2038             break;
2039          }
2040
2041       case E2AP_PDU_PR_initiatingMessage:
2042          {
2043             switch(e2apMsg->choice.initiatingMessage->value.present)
2044             {
2045                case InitiatingMessageE2__value_PR_RICsubscriptionRequest: 
2046                   {
2047                      if(procRicSubsReq(e2apMsg) == ROK)
2048                      {
2049                         BuildAndSendRicIndication();
2050                      }
2051                      break;
2052                   }
2053                default:
2054                   {
2055                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\
2056                            e2apMsg->choice.initiatingMessage->value.present);
2057                      return;
2058                   }
2059             }/* End of switch(initiatingMessage) */
2060             free(e2apMsg->choice.initiatingMessage);
2061             break;
2062          }
2063       default:
2064          {
2065             DU_LOG("\nERROR  -->  E2AP : Invalid type of e2apMsg->present [%d]",e2apMsg->present);
2066             return;
2067          }
2068          free(e2apMsg);
2069
2070    }/* End of switch(e2apMsg->present) */
2071
2072 } /* End of E2APMsgHdlr */
2073
2074 /**********************************************************************
2075   End of file
2076  **********************************************************************/