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