[Epic-ID: ODUHIGH-404][Task-ID: ODUHIGH-413] Modification of E2setup request and...
[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    return ROK;
995 }
996
997 /******************************************************************
998  *
999  * @brief Processes RIC Subscription Req sent by RIC
1000  *
1001  * @details
1002  *
1003  *    Function : procRicSubsReq
1004  *
1005  *    Functionality: Processes E2 Setup Response sent by CU
1006  *
1007  * @params[in] E2AP_PDU_t ASN decoded E2AP message
1008  * @return ROK     - success
1009  *         RFAILED - failure
1010  *
1011  * ****************************************************************/
1012
1013 uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg)
1014 {
1015    uint8_t idx; 
1016    uint8_t ied; 
1017    uint8_t ret = ROK;
1018    uint32_t recvBufLen;             
1019    RICsubscriptionRequest_t *ricSubsReq;
1020    RICaction_ToBeSetup_ItemIEs_t *actionItem;
1021
1022    DU_LOG("\nINFO   -->  E2AP : RIC Subscription request received"); 
1023    ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
1024
1025    for(idx=0; idx<ricSubsReq->protocolIEs.list.count; idx++)
1026    {
1027       if(ricSubsReq->protocolIEs.list.array[idx])
1028       {
1029          switch(ricSubsReq->protocolIEs.list.array[idx]->id)
1030          {
1031             case ProtocolIE_IDE2_id_RICrequestID:
1032                {
1033                   e2apMsgDb.ricReqId = ricSubsReq->protocolIEs.list.array[idx]->\
1034                                        value.choice.RICrequestID.ricRequestorID;
1035                   e2apMsgDb.ricInstanceId = ricSubsReq->protocolIEs.list.array[idx]-> \
1036                                             value.choice.RICrequestID.ricInstanceID;
1037                   break;
1038                }
1039             case ProtocolIE_IDE2_id_RANfunctionID:
1040                {
1041                   e2apMsgDb.ranFuncId = ricSubsReq->protocolIEs.list.array[idx]-> \
1042                                         value.choice.RANfunctionID; 
1043                   break;
1044                }
1045             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
1046                {
1047                   recvBufLen = sizeof(ricSubsReq->protocolIEs.list.array[idx]->value\
1048                         .choice.RICsubscriptionDetails.ricEventTriggerDefinition.size);
1049                   e2apMsgDb.ricEventTrigger = NULLP;
1050                   DU_ALLOC(e2apMsgDb.ricEventTrigger, recvBufLen);
1051                   /*TODO : e2apMsgDb.ricEventTrigger memory to be deallocated after the usage */
1052                   if(e2apMsgDb.ricEventTrigger)
1053                   {
1054                      memcpy(e2apMsgDb.ricEventTrigger, ricSubsReq->protocolIEs.list.array[idx]\
1055                            ->value.choice.RICsubscriptionDetails.ricEventTriggerDefinition.buf, \
1056                            recvBufLen);
1057                      free(ricSubsReq->protocolIEs.list.array[idx]->value.choice.\
1058                            RICsubscriptionDetails.ricEventTriggerDefinition.buf);
1059                   }
1060                   if(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\
1061                         list.array)
1062                   {
1063                      actionItem =(RICaction_ToBeSetup_ItemIEs_t *)ricSubsReq->protocolIEs.list\
1064                                  .array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List\
1065                                  .list.array[0];
1066
1067                      for(ied = 0; ied < ricSubsReq->protocolIEs.list.array[idx]->value.choice.\
1068                            RICsubscriptionDetails.ricAction_ToBeSetup_List.list.count; ied++)
1069                      {
1070                         switch(actionItem->id)
1071                         {
1072                            case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item:
1073                               {
1074                                  e2apMsgDb.ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
1075                                  e2apMsgDb.ricActionType = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType;
1076                                  break;
1077                               }
1078                            default:
1079                               DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id);
1080                               break;
1081                         }
1082                         free(actionItem);
1083                      }
1084                      free(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\
1085                      list.array);
1086                   }
1087                   break;
1088                }
1089
1090             default:
1091                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RIC SubsReq:%ld",
1092                      ricSubsReq->protocolIEs.list.array[idx]->id);
1093                break;
1094          }
1095          free(ricSubsReq->protocolIEs.list.array[idx]);
1096       }
1097    }
1098    free(ricSubsReq->protocolIEs.list.array);
1099    ret = BuildAndSendRicSubscriptionRsp();
1100
1101    return ret;
1102 }
1103
1104 /*******************************************************************
1105  *
1106  * @brief Free the RicIndication Message
1107  *
1108  * @details
1109  *
1110  *    Function : FreeRicIndication
1111  *
1112  * Functionality: Free the RicIndication Message
1113  *
1114  * @return void
1115  *         
1116  *
1117  ******************************************************************/
1118 void FreeRicIndication(E2AP_PDU_t  *e2apMsg) 
1119 {
1120    uint8_t idx=0;
1121    RICindication_t *ricIndicationMsg= NULLP;
1122
1123
1124    if(e2apMsg != NULLP)
1125    {
1126       if(e2apMsg->choice.initiatingMessage != NULLP)
1127       {
1128          ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
1129          if(ricIndicationMsg!= NULLP)
1130          {
1131             if(ricIndicationMsg->protocolIEs.list.array != NULLP)
1132             {
1133                for(idx=0; idx<ricIndicationMsg->protocolIEs.list.count; idx++)
1134                {
1135                   if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP)
1136                   {
1137                      switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
1138                      {
1139                         case ProtocolIE_IDE2_id_RICrequestID:
1140                            break;
1141
1142                         case ProtocolIE_IDE2_id_RANfunctionID:
1143                            break;
1144
1145                         case ProtocolIE_IDE2_id_RICactionID:
1146                            break;
1147
1148                         case ProtocolIE_IDE2_id_RICindicationType:
1149                            break;
1150
1151                         case ProtocolIE_IDE2_id_RICindicationHeader:
1152                            {
1153                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\
1154                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
1155                               break;
1156                            }
1157                         case ProtocolIE_IDE2_id_RICindicationMessage:
1158                            {
1159                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\
1160                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
1161                               break;
1162                            }
1163                         default:
1164                            break;
1165                      }
1166                      DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t));
1167                   }
1168                }
1169                DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size);
1170             }
1171          }
1172          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1173       }
1174       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1175    }
1176 }
1177 /*******************************************************************
1178  *
1179  * brief Fill the RicIndication Message
1180  *
1181  * @details
1182  *
1183  *    Function : FillRicIndication
1184  *
1185  * Functionality:Fills the RicIndication Message
1186  *
1187  * @return ROK     - success
1188  *         RFAILED - failure
1189  *
1190  ******************************************************************/
1191 uint8_t FillRicIndication(RICindication_t *ricIndicationMsg)
1192 {
1193    uint8_t elementCnt=0;
1194    uint8_t idx=0;
1195    uint8_t ret = ROK;
1196    elementCnt = 6;
1197
1198    ricIndicationMsg->protocolIEs.list.count = elementCnt;
1199    ricIndicationMsg->protocolIEs.list.size  = elementCnt * sizeof(RICindication_t);
1200    /* Initialize the Ric Indication members */
1201    DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, \
1202          ricIndicationMsg->protocolIEs.list.size);
1203    if(ricIndicationMsg->protocolIEs.list.array == NULLP)
1204    {
1205       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1206       ret = RFAILED;
1207    }
1208    else
1209    {
1210       for(idx=0; idx<elementCnt; idx++)
1211       {
1212          DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx],\
1213                sizeof(RICindication_IEs_t));
1214          if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
1215          {
1216             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1217             ret = RFAILED;
1218          }
1219       }
1220       if(ret != RFAILED)
1221       {
1222          idx = 0;
1223
1224          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
1225          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1226          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1227                                                                         RICindication_IEs__value_PR_RICrequestID;
1228          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID =\
1229                                                                                                   e2apMsgDb.ricReqId;
1230          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID =\
1231                                                                                                  e2apMsgDb.ricInstanceId;
1232
1233          idx++;
1234          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
1235          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1236          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1237                                                                         RICindication_IEs__value_PR_RANfunctionID;
1238          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID =
1239             e2apMsgDb.ranFuncId;
1240
1241          idx++;
1242          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
1243          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1244          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1245                                                                         RICindication_IEs__value_PR_RICactionID;
1246          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID =
1247             e2apMsgDb.ricActionId;
1248
1249          idx++;
1250          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
1251          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1252          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1253                                                                         RICindication_IEs__value_PR_RICindicationType;
1254          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType =
1255             e2apMsgDb.ricActionType;
1256
1257          idx++;
1258          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
1259          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1260          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1261                                                                         RICindication_IEs__value_PR_RICindicationHeader;
1262          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size = 3 *
1263             sizeof(uint8_t);
1264          DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf ,\
1265                ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
1266          if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf == NULLP)
1267          {
1268             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1269             ret = RFAILED;
1270          }
1271          else
1272          {
1273             buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
1274                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf);
1275             idx++;
1276             /* TO BE CHANGED: RIC INDICATION DATA */
1277             /* For now filling a dummy octect data, need to tested with PRBs*/
1278             ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
1279             ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1280             ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1281                                                                            RICindication_IEs__value_PR_RICindicationMessage;
1282             ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size = 3 *
1283                sizeof(uint8_t);
1284             DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf ,\
1285                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
1286             if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf == NULLP)
1287             {
1288                DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1289                ret = RFAILED;
1290             }
1291             else
1292             {
1293                buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
1294                      ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf);
1295             }
1296          }
1297       }
1298    }
1299    return ret;
1300 }
1301
1302 /*******************************************************************
1303  *
1304  * @brief Builds and Send the RicIndication Message
1305  *
1306  * @details
1307  *
1308  *    Function : BuildAndSendRicIndication
1309  *
1310  * Functionality:Fills the RicIndication Message
1311  *
1312  * @return ROK     - success
1313  *         RFAILED - failure
1314  *
1315  ******************************************************************/
1316
1317 uint8_t BuildAndSendRicIndication()
1318 {
1319    E2AP_PDU_t                 *e2apMsg = NULLP;
1320    RICindication_t            *ricIndicationMsg=NULLP;
1321    asn_enc_rval_t             encRetVal;        /* Encoder return value */
1322    uint8_t ret = RFAILED; 
1323    uint8_t FillRicIndicationret = ROK;
1324
1325    while(true)
1326    {
1327       DU_LOG("\nINFO   -->  E2AP : Building RIC Indication Message\n");
1328
1329       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1330       if(e2apMsg == NULLP)
1331       {
1332          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1333          break;
1334       }
1335
1336       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
1337       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1338       if(e2apMsg->choice.initiatingMessage == NULLP)
1339       {
1340          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1341          break;
1342       }
1343       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
1344       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
1345       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication;
1346
1347       ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
1348
1349       FillRicIndicationret = FillRicIndication(ricIndicationMsg);
1350       if(FillRicIndicationret != ROK)
1351       {
1352          break;
1353       }
1354       /* Prints the Msg formed */
1355       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1356       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1357       encBufSize = 0;
1358       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
1359             encBuf);
1360       if(encRetVal.encoded == ENCODE_FAIL)
1361       {
1362          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Indication Message (at %s)\n",\
1363                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1364          break;
1365       }
1366       else
1367       {
1368          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Indication Message \n");
1369          for(int i=0; i< encBufSize; i++)
1370          {
1371             printf("%x",encBuf[i]);
1372          } 
1373       }
1374
1375       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL) != ROK)
1376       {
1377          DU_LOG("\nINFO   -->  E2AP : Sending RIC Indication Message");      
1378
1379       }
1380       ret = ROK;
1381       break;
1382    }
1383    FreeRicIndication(e2apMsg);  
1384    return ret;
1385 }
1386
1387 /*******************************************************************
1388  *
1389  * @brief Sends E2 msg over SCTP
1390  *
1391  * @details
1392  *
1393  *    Function : SendE2APMsg
1394  *
1395  *    Functionality: Sends E2 msg over SCTP
1396  *
1397  * @params[in] Region region
1398  *             Pool pool
1399  * @return ROK     - success
1400  *         RFAILED - failure
1401  *
1402  * ****************************************************************/
1403
1404 uint8_t SendE2APMsg(Region region, Pool pool)
1405 {
1406    Buffer *mBuf=NULLP;
1407
1408    if(ODU_GET_MSG_BUF(region, pool, &mBuf) == ROK)
1409    {
1410       if(ODU_ADD_POST_MSG_MULT((Data *)encBuf, encBufSize, mBuf) == ROK)
1411       {
1412          ODU_PRINT_MSG(mBuf, 0,0);
1413
1414          if(sctpSend(mBuf, E2_INTERFACE) != ROK)
1415          {
1416             DU_LOG("\nERROR  -->  E2AP : SCTP Send for E2  failed");
1417             ODU_PUT_MSG_BUF(mBuf);
1418             return RFAILED;
1419          }
1420       }
1421       else
1422       {
1423          DU_LOG("\nERROR  -->  E2AP : ODU_ADD_POST_MSG_MULT failed");
1424          ODU_PUT_MSG_BUF(mBuf);
1425          return RFAILED;
1426       }
1427       ODU_PUT_MSG_BUF(mBuf);
1428    }
1429    else
1430    {
1431       DU_LOG("\nERROR  -->  E2AP : Failed to allocate memory");
1432       return RFAILED;
1433    }
1434
1435    return ROK;
1436 } /* SendE2APMsg */
1437
1438 /*******************************************************************
1439  *
1440  * @brief Handles received E2AP message and sends back response  
1441  *
1442  * @details
1443  *
1444  *    Function : E2APMsgHdlr
1445  *
1446  *    Functionality:
1447  *         - Decodes received E2AP control message
1448  *         - Prepares response message, encodes and sends to SCTP
1449  *
1450  * @params[in] 
1451  * @return ROK     - success
1452  *         RFAILED - failure
1453  *
1454  * ****************************************************************/
1455 void E2APMsgHdlr(Buffer *mBuf)
1456 {
1457    int i =0;
1458    char *recvBuf = NULLP;
1459    MsgLen copyCnt =0;
1460    MsgLen recvBufLen =0;
1461    E2AP_PDU_t *e2apMsg = NULLP;
1462    asn_dec_rval_t rval ={0}; /* Decoder return value */
1463    E2AP_PDU_t e2apasnmsg={0} ;
1464
1465    DU_LOG("\nDEBUG   -->  E2AP : Received E2AP message buffer");
1466    ODU_PRINT_MSG(mBuf, 0,0);
1467
1468    /* Copy mBuf into char array to decode it */
1469    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
1470    DU_ALLOC(recvBuf, (Size)recvBufLen);
1471
1472    if(recvBuf == NULLP)
1473    {
1474       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
1475       return;
1476    }
1477    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
1478    {
1479       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
1480       return;
1481    }
1482
1483    printf("\nDEBUG   -->  E2AP : Received flat buffer to be decoded : ");
1484    for(i=0; i< recvBufLen; i++)
1485    {
1486       printf("%x",recvBuf[i]);
1487    }
1488
1489    /* Decoding flat buffer into E2AP messsage */
1490    e2apMsg = &e2apasnmsg;
1491    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
1492
1493    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
1494    DU_FREE(recvBuf, (Size)recvBufLen);
1495
1496    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
1497    {
1498       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
1499       return;
1500    }
1501    printf("\n");
1502    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1503
1504    switch(e2apMsg->present)
1505    {
1506       case E2AP_PDU_PR_successfulOutcome:
1507          {
1508             switch(e2apMsg->choice.successfulOutcome->value.present)
1509             {
1510                case SuccessfulOutcomeE2__value_PR_E2setupResponse:
1511                   {
1512                      if(!duCb.e2Status)
1513                      {
1514                         DU_LOG("\nDEBUG   -->  E2AP : Store E2 setup response Params");
1515                         procE2SetupRsp(e2apMsg);
1516                      }
1517                      break;
1518                   }
1519                default:
1520                   {
1521                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome  [%d]",\
1522                      e2apMsg->choice.successfulOutcome->value.present);
1523                      return;
1524                   }
1525             }/* End of switch(successfulOutcome) */
1526             free(e2apMsg->choice.successfulOutcome);
1527             break;
1528          }
1529       case E2AP_PDU_PR_initiatingMessage:
1530          {
1531             switch(e2apMsg->choice.initiatingMessage->value.present)
1532             {
1533                case InitiatingMessageE2__value_PR_RICsubscriptionRequest: 
1534                   {
1535                      if(procRicSubsReq(e2apMsg) == ROK)
1536                      {
1537                         BuildAndSendRicIndication();
1538                      }
1539                      break;
1540                   }
1541                default:
1542                   {
1543                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\
1544                      e2apMsg->choice.initiatingMessage->value.present);
1545                      return;
1546                   }
1547             }/* End of switch(initiatingMessage) */
1548             free(e2apMsg->choice.initiatingMessage);
1549             break;
1550          }
1551       default:
1552          {
1553             DU_LOG("\nERROR  -->  E2AP : Invalid type of e2apMsg->present [%d]",e2apMsg->present);
1554             return;
1555          }
1556          free(e2apMsg);
1557
1558    }/* End of switch(e2apMsg->present) */
1559
1560 } /* End of E2APMsgHdlr */
1561
1562 /**********************************************************************
1563   End of file
1564  **********************************************************************/