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