[Epic-ID: ODUHIGH-406][Task-ID: ODUHIGH-428]Slot Indication at DUAPP
[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 val = 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, val);
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          for(int i=0; i< encBufSize; i++)
480          {
481             printf("%x",encBuf[i]);
482          }
483       }
484       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL) != ROK)
485       {
486          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
487       }
488
489       break;
490    }while(true);
491
492    FreeE2SetupReq(e2apMsg);
493    return ret;
494 }/* End of BuildAndSendE2SetupReq */
495
496 /*******************************************************************
497  *
498  * @brief Builds Ric Request Id
499  *
500  * @details
501  *
502  *    Function : BuildRicRequestId
503  *
504  *    Functionality: Building the Ric Request Id
505  *
506  * @params[in] RICrequestID_t *ricReqId
507  * @return ROK     - success
508  *         RFAILED - failure
509  *
510  * ****************************************************************/
511
512 uint8_t BuildRicRequestId(RICrequestID_t *ricReqId)
513 {
514    if(ricReqId == NULLP)
515    {
516       return RFAILED;
517    }
518
519    ricReqId->ricRequestorID = 1;
520    ricReqId->ricInstanceID  = 1;
521    return ROK;
522 }
523
524 /*******************************************************************
525  *
526  * @brief Fills the mandatory RicAdmitted List Items
527  *
528  * @details
529  *
530  *    Function : fillRicAdmitList
531  *
532  *    Functionality: Fills the mandatory Ric Admitted List Items
533  *
534  * @params[in] RICaction_Admitted_ItemIEs_t *ricAdmitItems
535  * @return ROK     - success
536  *         RFAILED - failure
537  *
538  * ****************************************************************/
539
540 uint8_t fillRicAdmitList(RICaction_Admitted_ItemIEs_t *ricAdmitItems)
541 {
542
543    if(ricAdmitItems != NULLP)
544    {
545       ricAdmitItems->id = ProtocolIE_IDE2_id_RICaction_Admitted_Item;
546       ricAdmitItems->criticality = CriticalityE2_reject;
547       ricAdmitItems->value.present = RICaction_Admitted_ItemIEs__value_PR_RICaction_Admitted_Item;
548       ricAdmitItems->value.choice.RICaction_Admitted_Item.ricActionID = 1; 
549    }
550    else
551    {
552       return RFAILED;
553    }
554    return ROK;
555 }
556 /*******************************************************************
557  *
558  * @brief Builds the mandatory RicAdmitted List Params
559  *
560  * @details
561  *
562  *    Function : BuildRicAdmitList
563  *
564  *    Functionality: Builds the mandatory Ric Admitted List Params
565  *
566  * @params[in] RICaction_Admitted_List_t *admitListPtr
567  * @return ROK     - success
568  *         RFAILED - failure
569  *
570  * ****************************************************************/
571
572 uint8_t BuildRicAdmitList(RICaction_Admitted_List_t *admitListPtr)
573 {
574    uint8_t idx ;
575    uint8_t elementCnt;  
576    uint8_t ret= ROK;
577    elementCnt = 1;
578
579    if(admitListPtr == NULLP)
580    {
581       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC Admit List failed");
582       ret = RFAILED;
583    }
584    else
585    {
586       admitListPtr->list.count = elementCnt;
587       admitListPtr->list.size  = elementCnt * sizeof(RICaction_Admitted_ItemIEs_t);
588       DU_ALLOC(admitListPtr->list.array, admitListPtr->list.size);
589       if(admitListPtr->list.array == NULLP)
590       {
591          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC Admit List failed");
592          ret = RFAILED;
593       }
594       else
595       {
596          for(idx=0 ; idx<elementCnt ; idx++ )
597          {
598             DU_ALLOC(admitListPtr->list.array[idx], sizeof(RICaction_Admitted_ItemIEs_t));
599             if(admitListPtr->list.array[idx] == NULLP)
600             {
601                ret = RFAILED;
602             }
603          }
604          if(ret != RFAILED)
605          {
606             idx=0;
607             fillRicAdmitList((RICaction_Admitted_ItemIEs_t *)admitListPtr->list.array[idx]);
608          }
609       }
610    }    
611    return ret;
612 }
613 /*******************************************************************
614  *
615  * @breif Deallocation of BuildAndSendRicSubscriptionRsp memory
616  *
617  * @details
618  *
619  *    Function : FreeRicSubscriptionRsp
620  *
621  * Functionality:Free the RicSubscriptionRsp
622  *
623  * @param[in] E2AP_PDU_t *e2apRicMsg
624  *
625  * @return void
626  *      
627  *
628  ******************************************************************/
629 void FreeRicSubscriptionRsp(E2AP_PDU_t  *e2apRicMsg)
630 {
631    RICsubscriptionResponse_t  *ricSubscriptionRsp= NULLP;
632    uint8_t idx=0;
633    uint8_t idx1=0;
634    RICaction_Admitted_List_t *admitListPtr;
635
636    if(e2apRicMsg != NULLP)
637    {
638       if(e2apRicMsg->choice.successfulOutcome != NULLP)
639       {
640          ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
641          if(ricSubscriptionRsp)
642          {
643             if(ricSubscriptionRsp->protocolIEs.list.array != NULLP)
644             {
645                for(idx=0; idx<ricSubscriptionRsp->protocolIEs.list.count; idx++)
646                {
647                   if(ricSubscriptionRsp->protocolIEs.list.array[idx] != NULLP)
648                   {
649                      switch(ricSubscriptionRsp->protocolIEs.list.array[idx]->id)
650                      {
651                         case ProtocolIE_IDE2_id_RICrequestID:
652                            break;
653
654                         case ProtocolIE_IDE2_id_RANfunctionID:
655                            break;
656
657                         case ProtocolIE_IDE2_id_RICactions_Admitted:
658                            {
659                               admitListPtr = &ricSubscriptionRsp->protocolIEs.list.\
660                                              array[idx]->value.choice.RICaction_Admitted_List;
661                               if(admitListPtr->list.array != NULLP)
662                               {
663                                  for(idx1=0 ; idx1<admitListPtr->list.count; idx1++ )
664                                  {
665                                     if(admitListPtr->list.array[idx1] != NULLP)
666                                     {
667                                        DU_FREE(admitListPtr->list.array[idx1],
668                                              sizeof(RICaction_Admitted_ItemIEs_t));
669                                     }
670                                  }
671                                  DU_FREE(admitListPtr->list.array, admitListPtr->list.size);     
672                               }
673                               break;
674                            }
675                         default:
676                            break;
677                      }
678                      DU_FREE(ricSubscriptionRsp->protocolIEs.list.array[idx], \
679                            sizeof(RICsubscriptionResponse_IEs_t));
680                   }
681                }
682                DU_FREE(ricSubscriptionRsp->protocolIEs.list.array, \
683                      ricSubscriptionRsp->protocolIEs.list.size);
684             }
685          }   
686          DU_FREE(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
687       }         
688       DU_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));        
689    }
690 }
691 /*******************************************************************
692  *
693  * @brief Builds and Send the RicSubscriptionRsp
694  *
695  * @details
696  *
697  *    Function : BuildAndSendRicSubscriptionRsp
698  *
699  * functionality:Fills the RicSubscriptionRsp
700  *
701  * @return ROK     - success
702  *         RFAILED - failure
703  *
704  ******************************************************************/
705 uint8_t  FillRicSubscriptionRsp(RICsubscriptionResponse_t  *ricSubscriptionRsp )
706 {
707    uint8_t idx=0;
708    uint8_t ret = ROK;
709    uint8_t elementCnt = 0;
710    uint8_t BuildRicRequestIdret=ROK;
711    uint8_t BuildRicAdmitListret=ROK;
712
713    elementCnt=3;
714    ricSubscriptionRsp->protocolIEs.list.count = elementCnt;
715    ricSubscriptionRsp->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionResponse_IEs_t);
716    DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array, \
717          ricSubscriptionRsp->protocolIEs.list.size);
718    if(ricSubscriptionRsp->protocolIEs.list.array == NULLP)
719    {
720       DU_LOG("\nERROR  -->  E2AP : Memory allocation for FillRicSubscriptionRsp  failed");
721       ret = RFAILED;
722    }
723    else
724    {
725       for(idx=0; idx<ricSubscriptionRsp->protocolIEs.list.count; idx++)
726       {
727          DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array[idx], \
728                sizeof(RICsubscriptionResponse_IEs_t));
729          if(ricSubscriptionRsp->protocolIEs.list.array[idx] == NULLP)
730          {
731             ret = RFAILED;
732          }
733       }
734       if(ret != RFAILED)
735       {
736
737          idx=0;
738          ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
739          ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
740          ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
741                                                                          RICsubscriptionRequest_IEs__value_PR_RICrequestID;
742          BuildRicRequestIdret =
743             BuildRicRequestId(&ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RICrequestID);
744          if(BuildRicRequestIdret != ROK)
745          {
746             ret = RFAILED;
747          }
748          else
749          {
750             idx++;
751             ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
752             ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
753             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
754                                                                             RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
755             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1;
756
757             idx++;
758             ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactions_Admitted;
759             ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
760             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
761                                                                             RICsubscriptionResponse_IEs__value_PR_RICaction_Admitted_List;
762             BuildRicAdmitListret =
763                BuildRicAdmitList(&ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RICaction_Admitted_List);
764             if(BuildRicAdmitListret != ROK)
765             {
766                ret = RFAILED;
767             }
768          }
769       }
770    }    
771    return ret;
772 }
773 /*******************************************************************
774  *
775  * @brief Builds and Send the RicSubscriptionRsp
776  *
777  * @details
778  *
779  *    Function : BuildAndSendRicSubscriptionRsp
780  *
781  * Functionality:Fills the RicSubscriptionRsp
782  *
783  * @return ROK     - success
784  *         RFAILED - failure
785  *
786  ******************************************************************/
787
788 uint8_t BuildAndSendRicSubscriptionRsp()
789 {
790
791    E2AP_PDU_t         *e2apRicMsg = NULLP;
792    RICsubscriptionResponse_t  *ricSubscriptionRsp=NULLP;
793    asn_enc_rval_t     encRetVal; 
794    uint8_t ret = RFAILED;
795    uint8_t FillRicricSubscriptionRspret;
796
797    while(true)
798    {
799       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Response\n");
800
801       DU_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t)); 
802       if(e2apRicMsg == NULLP)
803       {
804          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
805          break;
806       }
807       e2apRicMsg->present =  E2AP_PDU_PR_successfulOutcome;
808       DU_ALLOC(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
809       if(e2apRicMsg->choice.successfulOutcome == NULLP)
810       {
811          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC subscription Response failed");
812          break;
813       }
814
815       e2apRicMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
816       e2apRicMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
817       e2apRicMsg->choice.successfulOutcome->value.present = \
818                                                             SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse;
819       ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
820
821       FillRicricSubscriptionRspret = FillRicSubscriptionRsp(ricSubscriptionRsp);
822       if(FillRicricSubscriptionRspret != ROK)
823       {
824          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICsubscriptionResponseIE failed");
825          break;
826       }
827
828       /* Prints the Msg formed */
829       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
830
831       memset(encBuf, 0, ENC_BUF_MAX_LEN);
832       encBufSize = 0;
833       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\
834             encBuf);
835       if(encRetVal.encoded == ENCODE_FAIL)
836       {
837          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Response structure (at %s)\n",\
838                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
839          break;
840       }
841       else
842       {
843          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RIC subscription response \n");
844          for(int i=0; i< encBufSize; i++)
845          {
846             printf("%x",encBuf[i]);
847          } 
848       } 
849
850       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL) != ROK)
851       {
852          DU_LOG("\nERROR  -->  E2AP : Sending RIC Subscription Response failed");      
853          break;
854       }
855
856       ret = ROK;
857       break;
858
859    }
860    FreeRicSubscriptionRsp(e2apRicMsg);
861
862    return ret;
863 }
864
865 /******************************************************************
866  *
867  * @brief Deallocation of memory allocated bu aper decoder for e2 setup response
868  *
869  * @details
870  *
871  *    Function : freeAperDecodingOfE2SetupRsp
872  *
873  *    Functionality: Deallocation of memory allocated bu aper decoder for e2
874  *    setup response
875  *
876  * @params[in] E2setupResponse_t *e2SetRspMsg;
877  * @return void
878  *
879  * ****************************************************************/
880 void freeAperDecodingOfE2SetupRsp(E2setupResponse_t *e2SetRspMsg)
881 {
882    uint8_t arrIdx, e2NodeConfigAddAckListIdx;
883    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem;
884    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAddAckList;
885
886    if(e2SetRspMsg)
887    {
888       if(e2SetRspMsg->protocolIEs.list.array)
889       {
890          for(arrIdx=0; arrIdx<e2SetRspMsg->protocolIEs.list.count; arrIdx++)
891          {
892             if(e2SetRspMsg->protocolIEs.list.array[arrIdx])
893             {
894                switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
895                {
896                   case ProtocolIE_IDE2_id_TransactionID:
897                      break;
898
899                   case ProtocolIE_IDE2_id_GlobalRIC_ID:
900                      {
901                         free(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.pLMN_Identity.buf);
902                         free(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID.buf);
903                         break;
904                      }
905
906                   case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
907                      {
908                         e2NodeConfigAddAckList = &e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
909                         if(e2NodeConfigAddAckList->list.array )
910                         {
911                            for(e2NodeConfigAddAckListIdx = 0; e2NodeConfigAddAckListIdx< e2NodeConfigAddAckList->list.count; e2NodeConfigAddAckListIdx++)
912                            {
913                               if(e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx])
914                               {
915                                  e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx];
916                                  free(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.\
917                                        e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf);
918                                  free(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.\
919                                        e2nodeComponentInterfaceTypeF1);
920                                  free(e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx]);
921                               }
922                            }
923                            free(e2NodeConfigAddAckList->list.array);
924                         }
925                         break;
926                      }
927                }
928                free(e2SetRspMsg->protocolIEs.list.array[arrIdx]);  
929             }
930          }
931          free(e2SetRspMsg->protocolIEs.list.array);
932       }
933    }
934 }
935 /******************************************************************
936  *
937  * @brief Processes E2 Setup Response sent by RIC
938  *
939  * @details
940  *
941  *    Function : procE2SetupRsp
942  *
943  *    Functionality: Processes E2 Setup Response sent by RIC
944  *
945  * @params[in] E2AP_PDU_t ASN decoded E2AP message
946  * @return ROK     - success
947  *         RFAILED - failure
948  *
949  * ****************************************************************/
950 uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg)
951 {
952    uint8_t arrIdx =0; 
953    uint32_t recvBufLen;             
954    E2setupResponse_t *e2SetRspMsg;
955
956    DU_LOG("\nINFO   -->  E2AP : E2 Setup Response received"); 
957    duCb.e2Status = TRUE; //Set E2 status as true
958    e2SetRspMsg = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
959
960    for(arrIdx=0; arrIdx<e2SetRspMsg->protocolIEs.list.count; arrIdx++)
961    {
962       switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
963       {
964          case ProtocolIE_IDE2_id_TransactionID:
965             break;
966
967          case ProtocolIE_IDE2_id_GlobalRIC_ID:
968             {
969                /* To store the Ric Id Params */
970                recvBufLen = sizeof(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value\
971                      .choice.GlobalRIC_ID.pLMN_Identity.size);
972                e2apMsgDb.plmn = NULLP;
973                DU_ALLOC(e2apMsgDb.plmn, recvBufLen);
974                if(e2apMsgDb.plmn)
975                {
976                   memcpy(e2apMsgDb.plmn, e2SetRspMsg->protocolIEs.list.array[arrIdx]\
977                         ->value.choice.GlobalRIC_ID.pLMN_Identity.buf, recvBufLen);
978                }
979                bitStringToInt(&e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID, &e2apMsgDb.ricId);
980                /*TODO : e2apMsgDb.plmn memory to be deallocated after the usage */
981                break;
982             }
983
984          case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
985             break;
986
987          default:
988             DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2SetupRsp:%ld",
989                   e2SetRspMsg->protocolIEs.list.array[arrIdx]->id);
990             break;
991       }
992    }
993    freeAperDecodingOfE2SetupRsp(e2SetRspMsg);
994    BuildAndSendE2NodeConfigUpdate();
995    return ROK;
996 }
997
998 /******************************************************************
999  *
1000  * @brief Processes RIC Subscription Req sent by RIC
1001  *
1002  * @details
1003  *
1004  *    Function : procRicSubsReq
1005  *
1006  *    Functionality: Processes E2 Setup Response sent by CU
1007  *
1008  * @params[in] E2AP_PDU_t ASN decoded E2AP message
1009  * @return ROK     - success
1010  *         RFAILED - failure
1011  *
1012  * ****************************************************************/
1013
1014 uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg)
1015 {
1016    uint8_t idx; 
1017    uint8_t ied; 
1018    uint8_t ret = ROK;
1019    uint32_t recvBufLen;             
1020    RICsubscriptionRequest_t *ricSubsReq;
1021    RICaction_ToBeSetup_ItemIEs_t *actionItem;
1022
1023    DU_LOG("\nINFO   -->  E2AP : RIC Subscription request received"); 
1024    ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
1025
1026    for(idx=0; idx<ricSubsReq->protocolIEs.list.count; idx++)
1027    {
1028       if(ricSubsReq->protocolIEs.list.array[idx])
1029       {
1030          switch(ricSubsReq->protocolIEs.list.array[idx]->id)
1031          {
1032             case ProtocolIE_IDE2_id_RICrequestID:
1033                {
1034                   e2apMsgDb.ricReqId = ricSubsReq->protocolIEs.list.array[idx]->\
1035                                        value.choice.RICrequestID.ricRequestorID;
1036                   e2apMsgDb.ricInstanceId = ricSubsReq->protocolIEs.list.array[idx]-> \
1037                                             value.choice.RICrequestID.ricInstanceID;
1038                   break;
1039                }
1040             case ProtocolIE_IDE2_id_RANfunctionID:
1041                {
1042                   e2apMsgDb.ranFuncId = ricSubsReq->protocolIEs.list.array[idx]-> \
1043                                         value.choice.RANfunctionID; 
1044                   break;
1045                }
1046             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
1047                {
1048                   recvBufLen = sizeof(ricSubsReq->protocolIEs.list.array[idx]->value\
1049                         .choice.RICsubscriptionDetails.ricEventTriggerDefinition.size);
1050                   e2apMsgDb.ricEventTrigger = NULLP;
1051                   DU_ALLOC(e2apMsgDb.ricEventTrigger, recvBufLen);
1052                   /*TODO : e2apMsgDb.ricEventTrigger memory to be deallocated after the usage */
1053                   if(e2apMsgDb.ricEventTrigger)
1054                   {
1055                      memcpy(e2apMsgDb.ricEventTrigger, ricSubsReq->protocolIEs.list.array[idx]\
1056                            ->value.choice.RICsubscriptionDetails.ricEventTriggerDefinition.buf, \
1057                            recvBufLen);
1058                      free(ricSubsReq->protocolIEs.list.array[idx]->value.choice.\
1059                            RICsubscriptionDetails.ricEventTriggerDefinition.buf);
1060                   }
1061                   if(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\
1062                         list.array)
1063                   {
1064                      actionItem =(RICaction_ToBeSetup_ItemIEs_t *)ricSubsReq->protocolIEs.list\
1065                                  .array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List\
1066                                  .list.array[0];
1067
1068                      for(ied = 0; ied < ricSubsReq->protocolIEs.list.array[idx]->value.choice.\
1069                            RICsubscriptionDetails.ricAction_ToBeSetup_List.list.count; ied++)
1070                      {
1071                         switch(actionItem->id)
1072                         {
1073                            case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item:
1074                               {
1075                                  e2apMsgDb.ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
1076                                  e2apMsgDb.ricActionType = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType;
1077                                  break;
1078                               }
1079                            default:
1080                               DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id);
1081                               break;
1082                         }
1083                         free(actionItem);
1084                      }
1085                      free(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\
1086                      list.array);
1087                   }
1088                   break;
1089                }
1090
1091             default:
1092                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RIC SubsReq:%ld",
1093                      ricSubsReq->protocolIEs.list.array[idx]->id);
1094                break;
1095          }
1096          free(ricSubsReq->protocolIEs.list.array[idx]);
1097       }
1098    }
1099    free(ricSubsReq->protocolIEs.list.array);
1100    ret = BuildAndSendRicSubscriptionRsp();
1101
1102    return ret;
1103 }
1104
1105 /*******************************************************************
1106  *
1107  * @brief Free the RicIndication Message
1108  *
1109  * @details
1110  *
1111  *    Function : FreeRicIndication
1112  *
1113  * Functionality: Free the RicIndication Message
1114  *
1115  * @return void
1116  *         
1117  *
1118  ******************************************************************/
1119 void FreeRicIndication(E2AP_PDU_t  *e2apMsg) 
1120 {
1121    uint8_t idx=0;
1122    RICindication_t *ricIndicationMsg= NULLP;
1123
1124
1125    if(e2apMsg != NULLP)
1126    {
1127       if(e2apMsg->choice.initiatingMessage != NULLP)
1128       {
1129          ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
1130          if(ricIndicationMsg!= NULLP)
1131          {
1132             if(ricIndicationMsg->protocolIEs.list.array != NULLP)
1133             {
1134                for(idx=0; idx<ricIndicationMsg->protocolIEs.list.count; idx++)
1135                {
1136                   if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP)
1137                   {
1138                      switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
1139                      {
1140                         case ProtocolIE_IDE2_id_RICrequestID:
1141                            break;
1142
1143                         case ProtocolIE_IDE2_id_RANfunctionID:
1144                            break;
1145
1146                         case ProtocolIE_IDE2_id_RICactionID:
1147                            break;
1148
1149                         case ProtocolIE_IDE2_id_RICindicationType:
1150                            break;
1151
1152                         case ProtocolIE_IDE2_id_RICindicationHeader:
1153                            {
1154                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\
1155                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
1156                               break;
1157                            }
1158                         case ProtocolIE_IDE2_id_RICindicationMessage:
1159                            {
1160                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\
1161                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
1162                               break;
1163                            }
1164                         default:
1165                            break;
1166                      }
1167                      DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t));
1168                   }
1169                }
1170                DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size);
1171             }
1172          }
1173          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1174       }
1175       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1176    }
1177 }
1178 /*******************************************************************
1179  *
1180  * brief Fill the RicIndication Message
1181  *
1182  * @details
1183  *
1184  *    Function : FillRicIndication
1185  *
1186  * Functionality:Fills the RicIndication Message
1187  *
1188  * @return ROK     - success
1189  *         RFAILED - failure
1190  *
1191  ******************************************************************/
1192 uint8_t FillRicIndication(RICindication_t *ricIndicationMsg)
1193 {
1194    uint8_t elementCnt=0;
1195    uint8_t idx=0;
1196    uint8_t ret = ROK;
1197    elementCnt = 6;
1198
1199    ricIndicationMsg->protocolIEs.list.count = elementCnt;
1200    ricIndicationMsg->protocolIEs.list.size  = elementCnt * sizeof(RICindication_t);
1201    /* Initialize the Ric Indication members */
1202    DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, \
1203          ricIndicationMsg->protocolIEs.list.size);
1204    if(ricIndicationMsg->protocolIEs.list.array == NULLP)
1205    {
1206       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1207       ret = RFAILED;
1208    }
1209    else
1210    {
1211       for(idx=0; idx<elementCnt; idx++)
1212       {
1213          DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx],\
1214                sizeof(RICindication_IEs_t));
1215          if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
1216          {
1217             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1218             ret = RFAILED;
1219          }
1220       }
1221       if(ret != RFAILED)
1222       {
1223          idx = 0;
1224
1225          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
1226          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1227          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1228                                                                         RICindication_IEs__value_PR_RICrequestID;
1229          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID =\
1230                                                                                                   e2apMsgDb.ricReqId;
1231          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID =\
1232                                                                                                  e2apMsgDb.ricInstanceId;
1233
1234          idx++;
1235          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
1236          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1237          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1238                                                                         RICindication_IEs__value_PR_RANfunctionID;
1239          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID =
1240             e2apMsgDb.ranFuncId;
1241
1242          idx++;
1243          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
1244          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1245          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1246                                                                         RICindication_IEs__value_PR_RICactionID;
1247          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID =
1248             e2apMsgDb.ricActionId;
1249
1250          idx++;
1251          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
1252          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1253          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1254                                                                         RICindication_IEs__value_PR_RICindicationType;
1255          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType =
1256             e2apMsgDb.ricActionType;
1257
1258          idx++;
1259          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
1260          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1261          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1262                                                                         RICindication_IEs__value_PR_RICindicationHeader;
1263          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size = 3 *
1264             sizeof(uint8_t);
1265          DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf ,\
1266                ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
1267          if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf == NULLP)
1268          {
1269             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1270             ret = RFAILED;
1271          }
1272          else
1273          {
1274             buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
1275                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf);
1276             idx++;
1277             /* TO BE CHANGED: RIC INDICATION DATA */
1278             /* For now filling a dummy octect data, need to tested with PRBs*/
1279             ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
1280             ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1281             ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1282                                                                            RICindication_IEs__value_PR_RICindicationMessage;
1283             ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size = 3 *
1284                sizeof(uint8_t);
1285             DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf ,\
1286                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
1287             if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf == NULLP)
1288             {
1289                DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1290                ret = RFAILED;
1291             }
1292             else
1293             {
1294                buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
1295                      ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf);
1296             }
1297          }
1298       }
1299    }
1300    return ret;
1301 }
1302
1303 /*******************************************************************
1304  *
1305  * @brief Builds and Send the RicIndication Message
1306  *
1307  * @details
1308  *
1309  *    Function : BuildAndSendRicIndication
1310  *
1311  * Functionality:Fills the RicIndication Message
1312  *
1313  * @return ROK     - success
1314  *         RFAILED - failure
1315  *
1316  ******************************************************************/
1317
1318 uint8_t BuildAndSendRicIndication()
1319 {
1320    E2AP_PDU_t                 *e2apMsg = NULLP;
1321    RICindication_t            *ricIndicationMsg=NULLP;
1322    asn_enc_rval_t             encRetVal;        /* Encoder return value */
1323    uint8_t ret = RFAILED; 
1324    uint8_t FillRicIndicationret = ROK;
1325
1326    while(true)
1327    {
1328       DU_LOG("\nINFO   -->  E2AP : Building RIC Indication Message\n");
1329
1330       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1331       if(e2apMsg == NULLP)
1332       {
1333          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1334          break;
1335       }
1336
1337       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
1338       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1339       if(e2apMsg->choice.initiatingMessage == NULLP)
1340       {
1341          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1342          break;
1343       }
1344       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
1345       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
1346       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication;
1347
1348       ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
1349
1350       FillRicIndicationret = FillRicIndication(ricIndicationMsg);
1351       if(FillRicIndicationret != ROK)
1352       {
1353          break;
1354       }
1355       /* Prints the Msg formed */
1356       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1357       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1358       encBufSize = 0;
1359       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
1360             encBuf);
1361       if(encRetVal.encoded == ENCODE_FAIL)
1362       {
1363          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Indication Message (at %s)\n",\
1364                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1365          break;
1366       }
1367       else
1368       {
1369          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Indication Message \n");
1370          for(int i=0; i< encBufSize; i++)
1371          {
1372             printf("%x",encBuf[i]);
1373          } 
1374       }
1375
1376       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL) != ROK)
1377       {
1378          DU_LOG("\nINFO   -->  E2AP : Sending RIC Indication Message");      
1379
1380       }
1381       ret = ROK;
1382       break;
1383    }
1384    FreeRicIndication(e2apMsg);  
1385    return ret;
1386 }
1387
1388 /*******************************************************************
1389  *
1390  * @brief Sends E2 msg over SCTP
1391  *
1392  * @details
1393  *
1394  *    Function : SendE2APMsg
1395  *
1396  *    Functionality: Sends E2 msg over SCTP
1397  *
1398  * @params[in] Region region
1399  *             Pool pool
1400  * @return ROK     - success
1401  *         RFAILED - failure
1402  *
1403  * ****************************************************************/
1404
1405 uint8_t SendE2APMsg(Region region, Pool pool)
1406 {
1407    Buffer *mBuf=NULLP;
1408
1409    if(ODU_GET_MSG_BUF(region, pool, &mBuf) == ROK)
1410    {
1411       if(ODU_ADD_POST_MSG_MULT((Data *)encBuf, encBufSize, mBuf) == ROK)
1412       {
1413          ODU_PRINT_MSG(mBuf, 0,0);
1414
1415          if(sctpSend(mBuf, E2_INTERFACE) != ROK)
1416          {
1417             DU_LOG("\nERROR  -->  E2AP : SCTP Send for E2  failed");
1418             ODU_PUT_MSG_BUF(mBuf);
1419             return RFAILED;
1420          }
1421       }
1422       else
1423       {
1424          DU_LOG("\nERROR  -->  E2AP : ODU_ADD_POST_MSG_MULT failed");
1425          ODU_PUT_MSG_BUF(mBuf);
1426          return RFAILED;
1427       }
1428       ODU_PUT_MSG_BUF(mBuf);
1429    }
1430    else
1431    {
1432       DU_LOG("\nERROR  -->  E2AP : Failed to allocate memory");
1433       return RFAILED;
1434    }
1435
1436    return ROK;
1437 } /* SendE2APMsg */
1438
1439 /*******************************************************************
1440  *
1441  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
1442  *
1443  * @details
1444  *
1445  *    Function : FreeE2NodeConfigUpdate 
1446  *
1447  *    Functionality:
1448  *       - freeing the memory allocated for E2nodeConfigurationUpdate
1449  *
1450  * @params[in] E2AP_PDU_t *e2apMsg 
1451  * @return ROK     - success
1452  *         RFAILED - failure
1453  *
1454  * ****************************************************************/
1455 void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg)
1456 {
1457    uint8_t arrIdx =0;
1458    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate;
1459
1460    if(e2apMsg != NULLP)
1461    {
1462       if(e2apMsg->choice.initiatingMessage != NULLP)
1463       {
1464          e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
1465          if(e2NodeConfigUpdate->protocolIEs.list.array != NULLP)
1466          {
1467             for(arrIdx = 0; arrIdx < e2NodeConfigUpdate->protocolIEs.list.count; arrIdx++)
1468             {
1469                DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
1470             }
1471             DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
1472          }
1473          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1474       }
1475       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1476    }
1477 }
1478
1479 /*******************************************************************
1480  *
1481  * @brief Buld and send the E2 node config update msg 
1482  *
1483  * @details
1484  *
1485  *    Function : BuildAndSendE2NodeConfigUpdate
1486  *
1487  *    Functionality:
1488  *         - Buld and send the E2 node config update msg
1489  *
1490  * @params[in] 
1491  * @return ROK     - success
1492  *         RFAILED - failure
1493  *
1494  * ****************************************************************/
1495
1496 uint8_t BuildAndSendE2NodeConfigUpdate()
1497 {
1498    uint8_t arrIdx = 0,elementCnt = 1;
1499    uint8_t ret = ROK;
1500    E2AP_PDU_t        *e2apMsg = NULLP;
1501    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate = NULLP;
1502    asn_enc_rval_t     encRetVal;       /* Encoder return value */
1503
1504    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update\n");
1505    do
1506    {
1507       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1508       if(e2apMsg == NULLP)
1509       {
1510          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1511          break;
1512       }
1513       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
1514       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1515       if(e2apMsg->choice.initiatingMessage == NULLP)
1516       {
1517          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1518          DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1519          return RFAILED;
1520       }
1521       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
1522       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
1523       e2apMsg->choice.initiatingMessage->value.present = \
1524       InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate;
1525       e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
1526
1527       e2NodeConfigUpdate->protocolIEs.list.count = elementCnt;
1528       e2NodeConfigUpdate->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdate_IEs_t*);
1529       /* Initialize the Ric Indication members */
1530       DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array, \
1531             e2NodeConfigUpdate->protocolIEs.list.size);
1532       if(e2NodeConfigUpdate->protocolIEs.list.array == NULLP)
1533       {
1534          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
1535          break;
1536       }
1537       
1538       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
1539       {
1540          DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
1541          if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx] == NULLP)
1542          {
1543             
1544             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
1545             break;
1546          }
1547       }
1548
1549       arrIdx = 0;
1550       /* TransactionID */
1551       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
1552       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1553       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_TransactionID;
1554       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = TRANS_ID;
1555
1556
1557       /* Prints the Msg formed */
1558       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1559
1560       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1561       encBufSize = 0;
1562       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
1563             encBuf);
1564       if(encRetVal.encoded == ENCODE_FAIL)
1565       {
1566          DU_LOG("\nERROR  -->  E2AP : Could not encode E2nodeConfigurationUpdate structure (at %s)\n",\
1567                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1568          break;
1569       }
1570       else
1571       {
1572          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2nodeConfigurationUpdate\n");
1573          for(int i=0; i< encBufSize; i++)
1574          {
1575             printf("%x",encBuf[i]);
1576          }
1577       }
1578       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL) != ROK)
1579       {
1580          DU_LOG("\nERROR  -->  E2AP : Sending E2 node config update failed");
1581          return RFAILED;
1582       }
1583
1584       break;
1585    }while(true);
1586    
1587    FreeE2NodeConfigUpdate(e2apMsg);
1588    return ret;
1589 }
1590
1591 /*******************************************************************
1592  *
1593  * @brief Handles received E2AP message and sends back response  
1594  *
1595  * @details
1596  *
1597  *    Function : E2APMsgHdlr
1598  *
1599  *    Functionality:
1600  *         - Decodes received E2AP control message
1601  *         - Prepares response message, encodes and sends to SCTP
1602  *
1603  * @params[in] 
1604  * @return ROK     - success
1605  *         RFAILED - failure
1606  *
1607  * ****************************************************************/
1608 void E2APMsgHdlr(Buffer *mBuf)
1609 {
1610    int i =0;
1611    char *recvBuf = NULLP;
1612    MsgLen copyCnt =0;
1613    MsgLen recvBufLen =0;
1614    E2AP_PDU_t *e2apMsg = NULLP;
1615    asn_dec_rval_t rval ={0}; /* Decoder return value */
1616    E2AP_PDU_t e2apasnmsg={0} ;
1617
1618    DU_LOG("\nDEBUG   -->  E2AP : Received E2AP message buffer");
1619    ODU_PRINT_MSG(mBuf, 0,0);
1620
1621    /* Copy mBuf into char array to decode it */
1622    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
1623    DU_ALLOC(recvBuf, (Size)recvBufLen);
1624
1625    if(recvBuf == NULLP)
1626    {
1627       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
1628       return;
1629    }
1630    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
1631    {
1632       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
1633       return;
1634    }
1635
1636    printf("\nDEBUG   -->  E2AP : Received flat buffer to be decoded : ");
1637    for(i=0; i< recvBufLen; i++)
1638    {
1639       printf("%x",recvBuf[i]);
1640    }
1641
1642    /* Decoding flat buffer into E2AP messsage */
1643    e2apMsg = &e2apasnmsg;
1644    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
1645
1646    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
1647    DU_FREE(recvBuf, (Size)recvBufLen);
1648
1649    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
1650    {
1651       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
1652       return;
1653    }
1654    printf("\n");
1655    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1656
1657    switch(e2apMsg->present)
1658    {
1659       case E2AP_PDU_PR_successfulOutcome:
1660          {
1661             switch(e2apMsg->choice.successfulOutcome->value.present)
1662             {
1663                case SuccessfulOutcomeE2__value_PR_E2setupResponse:
1664                   {
1665                      if(!duCb.e2Status)
1666                      {
1667                         DU_LOG("\nDEBUG   -->  E2AP : Store E2 setup response Params");
1668                         procE2SetupRsp(e2apMsg);
1669                      }
1670                      break;
1671                   }
1672                case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge:
1673                   {
1674                      DU_LOG("\nDEBUG   -->  E2AP : E2 node Config update ack message recevied");
1675                      break;
1676                   }
1677                default:
1678                   {
1679                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome  [%d]",\
1680                            e2apMsg->choice.successfulOutcome->value.present);
1681                      return;
1682                   }
1683             }/* End of switch(successfulOutcome) */
1684             free(e2apMsg->choice.successfulOutcome);
1685             break;
1686          }
1687       case E2AP_PDU_PR_initiatingMessage:
1688          {
1689             switch(e2apMsg->choice.initiatingMessage->value.present)
1690             {
1691                case InitiatingMessageE2__value_PR_RICsubscriptionRequest: 
1692                   {
1693                      if(procRicSubsReq(e2apMsg) == ROK)
1694                      {
1695                         BuildAndSendRicIndication();
1696                      }
1697                      break;
1698                   }
1699                default:
1700                   {
1701                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\
1702                            e2apMsg->choice.initiatingMessage->value.present);
1703                      return;
1704                   }
1705             }/* End of switch(initiatingMessage) */
1706             free(e2apMsg->choice.initiatingMessage);
1707             break;
1708          }
1709       default:
1710          {
1711             DU_LOG("\nERROR  -->  E2AP : Invalid type of e2apMsg->present [%d]",e2apMsg->present);
1712             return;
1713          }
1714          free(e2apMsg);
1715
1716    }/* End of switch(e2apMsg->present) */
1717
1718 } /* End of E2APMsgHdlr */
1719
1720 /**********************************************************************
1721   End of file
1722  **********************************************************************/