57a89f9000ddda6cb4a076f7da3a6ca83ba9a836
[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
38 /* Global variable */
39 DuCfgParams duCfgParam;
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 Fills the initiating IE for E2 Setup Request
99  *
100  * @details
101  *
102  *    Function : fillE2SetupReq
103  *
104  * Functionality:Fills the Initiating message for
105  *               E2SetupRequest
106  *
107  * @params[in] E2setupRequest_t *e2SetupReq,
108  *             uint8_t *idx
109  * @return ROK     - success
110  *         RFAILED - failure
111  *
112  ******************************************************************/
113
114 uint8_t fillE2SetupReq(E2setupRequest_t **e2SetupReq, uint8_t *idx)
115 {
116    uint8_t elementCnt = 0;
117    uint8_t idx2 = 0;
118    uint8_t ret = ROK;
119
120    if(*e2SetupReq != NULLP)
121    {
122       elementCnt = 1;
123       (*e2SetupReq)->protocolIEs.list.count = elementCnt;
124       (*e2SetupReq)->protocolIEs.list.size = \
125                                              elementCnt * sizeof(E2setupRequestIEs_t);
126
127       /* Initialize the E2Setup members */
128       DU_ALLOC((*e2SetupReq)->protocolIEs.list.array, \
129             (*e2SetupReq)->protocolIEs.list.size);
130       if((*e2SetupReq)->protocolIEs.list.array == NULLP)
131       {
132          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
133          ret = RFAILED;
134       }
135       else
136       {
137          for(*idx = 0; *idx < elementCnt; (*idx)++)
138          {
139             DU_ALLOC((*e2SetupReq)->protocolIEs.list.array[*idx],\
140                   sizeof(E2setupRequestIEs_t));
141             if((*e2SetupReq)->protocolIEs.list.array[*idx] == NULLP)
142             {
143                DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayidx [%d]", *idx);
144                ret = RFAILED;
145             }
146             else
147             {
148                /* GlobalE2node_gNB_ID */
149                (*e2SetupReq)->protocolIEs.list.array[idx2]->id = \
150                                                                  ProtocolIE_IDE2_id_GlobalE2node_ID;
151                (*e2SetupReq)->protocolIEs.list.array[idx2]->criticality = \
152                                                                           CriticalityE2_reject;
153                (*e2SetupReq)->protocolIEs.list.array[idx2]->value.present =\
154                                                                            E2setupRequestIEs__value_PR_GlobalE2node_ID;
155                (*e2SetupReq)->protocolIEs.list.array[idx2]->value.choice.\
156                   GlobalE2node_ID.present = GlobalE2node_ID_PR_gNB;
157
158                DU_ALLOC((*e2SetupReq)->protocolIEs.list.array[idx2]->value.choice.\
159                      GlobalE2node_ID.choice.gNB, sizeof(GlobalE2node_gNB_ID_t));
160                if((*e2SetupReq)->protocolIEs.list.array[idx2]->value.choice.\
161                      GlobalE2node_ID.choice.gNB == NULLP)
162                {
163                   DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for gNbId");
164                   ret = RFAILED;
165                }
166                else
167                {
168                   ret = BuildGlobalgNBId((*e2SetupReq)->protocolIEs.list.array[idx2]->value.\
169                         choice.GlobalE2node_ID.choice.gNB);
170                   if(ret != ROK)
171                   {
172                      ret = RFAILED;
173                   }
174                }
175
176             }
177          }
178       }
179    }
180    else
181    {
182       ret = RFAILED;
183       DU_LOG("\nERROR  -->  E2AP : received e2SetupReq is NULL");
184    }
185    return ret;
186 }
187
188 /*******************************************************************
189  *
190  * @brief Builds and Send the E2SetupRequest
191  *
192  * @details
193  *
194  *    Function : BuildAndSendE2SetupReq
195  *
196  * Functionality:Fills the E2SetupRequest
197  *
198  * @return ROK     - success
199  *         RFAILED - failure
200  *
201  ******************************************************************/
202
203 uint8_t BuildAndSendE2SetupReq()
204 {
205    uint8_t idx = 0;
206    uint8_t ret = ROK;
207    E2AP_PDU_t        *e2apMsg = NULLP;
208    E2setupRequest_t  *e2SetupReq = NULLP;
209    asn_enc_rval_t     encRetVal;       /* Encoder return value */
210
211    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup Request\n");
212    do
213    {
214       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
215       if(e2apMsg == NULLP)
216       {
217          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
218          break;
219       }
220       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
221       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
222       if(e2apMsg->choice.initiatingMessage == NULLP)
223       {
224          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
225          DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
226          return RFAILED;
227       }
228       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
229       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2setup;
230       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2setupRequest;
231       e2SetupReq = &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest;
232
233       ret = fillE2SetupReq(&e2SetupReq, &idx);
234       if(ret != ROK)
235       {
236          DU_LOG("\nERROR  -->  E2AP : fillE2SetupReq() failed");
237          break;
238       }
239       /* Prints the Msg formed */
240       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
241
242       memset(encBuf, 0, ENC_BUF_MAX_LEN);
243       encBufSize = 0;
244       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
245             encBuf);
246       if(encRetVal.encoded == ENCODE_FAIL)
247       {
248          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupRequest structure (at %s)\n",\
249                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
250          break;
251       }
252       else
253       {
254          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2SetupRequest\n");
255          for(int i=0; i< encBufSize; i++)
256          {
257             printf("%x",encBuf[i]);
258          }
259       }
260       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL) != ROK)
261       {
262          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
263       }
264
265       break;
266    }while(true);
267
268    deAllocateE2SetupReqMsg(e2apMsg, e2SetupReq, idx);
269    return ret;
270 }/* End of BuildAndSendE2SetupReq */
271
272 /*******************************************************************
273  *
274  * @brief De Allocate E2 Setup Request Message
275  *
276  * @details
277  *
278  *    Function : deAllocateE2SetupReqMsg
279  *
280  *    Functionality: De-Allocating E2 Setup request Message
281  *
282  * @params[in] E2AP_PDU_t *e2apMsg
283  *             E2setupRequest_t *e2SetupReq
284  * @return ROK     - success
285  *         RFAILED - failure
286  *
287  * ****************************************************************/
288
289 uint8_t deAllocateE2SetupReqMsg(E2AP_PDU_t *e2apMsg, \
290       E2setupRequest_t *e2SetupReq, uint8_t idx)
291 {
292    uint8_t idx2;
293    uint8_t ret = ROK;
294    /* De-allocating Memory */
295    if(e2apMsg != NULLP)
296    {
297       if(e2apMsg->choice.initiatingMessage != NULLP)
298       {
299          if(e2SetupReq->protocolIEs.list.array != NULLP)
300          {
301             for(idx2 = 0; idx2 < idx; idx2++)
302             {
303                if(e2SetupReq->protocolIEs.list.array[idx2] != NULLP)
304                {
305                   switch(e2SetupReq->protocolIEs.list.array[idx2]->id)
306                   {
307                      case ProtocolIE_IDE2_id_GlobalE2node_ID:
308                         {
309                            if(e2SetupReq->protocolIEs.list.array[idx2]->\
310                                  value.choice.GlobalE2node_ID.choice.gNB != NULLP)
311                            {
312                               GlobalE2node_gNB_ID_t *gNbId = NULLP;
313                               gNbId = e2SetupReq->protocolIEs.list.array[idx2]->\
314                                       value.choice.GlobalE2node_ID.choice.gNB;
315                               if(gNbId->global_gNB_ID.plmn_id.buf != NULLP)
316                               {
317                                  if(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf != NULLP)
318                                  {
319                                     DU_FREE(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf,\
320                                           gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size);
321                                  }
322                                  DU_FREE(gNbId->global_gNB_ID.plmn_id.buf,\
323                                        gNbId->global_gNB_ID.plmn_id.size);
324                               }
325                               DU_FREE(e2SetupReq->protocolIEs.list.array[idx2]->value.\
326                                     choice.GlobalE2node_ID.choice.gNB, sizeof(GlobalE2node_gNB_ID_t));
327                            }
328                            DU_FREE(e2SetupReq->protocolIEs.list.array[idx2],\
329                                  sizeof(E2setupRequestIEs_t));
330                            break;
331                         }
332                      default:
333                         DU_LOG("\nERROR  --> E2AP: Invalid event at e2SetupRequet %ld ",\
334                               (e2SetupReq->protocolIEs.list.array[idx2]->id));
335                         break;
336                   }
337                }
338             }
339             DU_FREE(e2SetupReq->protocolIEs.list.array, e2SetupReq->protocolIEs.list.size);
340          }
341          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
342       }
343       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
344    }
345    return ret;  
346 }
347 /*******************************************************************
348  *
349  * @brief Builds Ric Request Id
350  *
351  * @details
352  *
353  *    Function : BuildRicRequestId
354  *
355  *    Functionality: Building the Ric Request Id
356  *
357  * @params[in] RICrequestID_t *ricReqId
358  * @return ROK     - success
359  *         RFAILED - failure
360  *
361  * ****************************************************************/
362
363 uint8_t BuildRicRequestId(RICrequestID_t *ricReqId)
364 {
365    if(ricReqId == NULLP)
366    {
367       return RFAILED;
368    }
369
370    ricReqId->ricRequestorID = 1;
371    ricReqId->ricInstanceID  = 1;
372    return ROK;
373 }
374
375 /*******************************************************************
376  *
377  * @brief Fills the mandatory RicAdmitted List Items
378  *
379  * @details
380  *
381  *    Function : fillRicAdmitList
382  *
383  *    Functionality: Fills the mandatory Ric Admitted List Items
384  *
385  * @params[in] RICaction_Admitted_ItemIEs_t *ricAdmitItems
386  * @return ROK     - success
387  *         RFAILED - failure
388  *
389  * ****************************************************************/
390
391 uint8_t fillRicAdmitList(RICaction_Admitted_ItemIEs_t *ricAdmitItems)
392 {
393
394    if(ricAdmitItems != NULLP)
395    {
396       ricAdmitItems->id = ProtocolIE_IDE2_id_RICaction_Admitted_Item;
397       ricAdmitItems->criticality = CriticalityE2_reject;
398       ricAdmitItems->value.present = RICaction_Admitted_ItemIEs__value_PR_RICaction_Admitted_Item;
399       ricAdmitItems->value.choice.RICaction_Admitted_Item.ricActionID = 1; 
400    }
401    else
402    {
403       return RFAILED;
404    }
405    return ROK;
406 }
407 /*******************************************************************
408  *
409  * @brief Builds the mandatory RicAdmitted List Params
410  *
411  * @details
412  *
413  *    Function : BuildRicAdmitList
414  *
415  *    Functionality: Builds the mandatory Ric Admitted List Params
416  *
417  * @params[in] RICaction_Admitted_List_t *admitListPtr
418  * @return ROK     - success
419  *         RFAILED - failure
420  *
421  * ****************************************************************/
422
423 uint8_t BuildRicAdmitList(RICaction_Admitted_List_t *admitListPtr)
424 {
425    uint8_t idx ;
426    uint8_t elementCnt;  
427    uint8_t ret= ROK;
428    elementCnt = 1;
429
430    if(admitListPtr == NULLP)
431    {
432       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC Admit List failed");
433       ret = RFAILED;
434    }
435    else
436    {
437       admitListPtr->list.count = elementCnt;
438       admitListPtr->list.size  = elementCnt * sizeof(RICaction_Admitted_ItemIEs_t);
439       DU_ALLOC(admitListPtr->list.array, admitListPtr->list.size);
440       if(admitListPtr->list.array == NULLP)
441       {
442          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC Admit List failed");
443          ret = RFAILED;
444       }
445       else
446       {
447          for(idx=0 ; idx<elementCnt ; idx++ )
448          {
449             DU_ALLOC(admitListPtr->list.array[idx], sizeof(RICaction_Admitted_ItemIEs_t));
450             if(admitListPtr->list.array[idx] == NULLP)
451             {
452                ret = RFAILED;
453             }
454          }
455          if(ret != RFAILED)
456          {
457             idx=0;
458             fillRicAdmitList((RICaction_Admitted_ItemIEs_t *)admitListPtr->list.array[idx]);
459          }
460       }
461    }    
462    return ret;
463 }
464 /*******************************************************************
465  *
466  * @breif Deallocation of BuildAndSendRicSubscriptionRsp memory
467  *
468  * @details
469  *
470  *    Function : FreeRicSubscriptionRsp
471  *
472  * Functionality:Free the RicSubscriptionRsp
473  *
474  * @param[in] E2AP_PDU_t *e2apRicMsg
475  *
476  * @return void
477  *      
478  *
479  ******************************************************************/
480 void FreeRicSubscriptionRsp(E2AP_PDU_t  *e2apRicMsg)
481 {
482    RICsubscriptionResponse_t  *ricSubscriptionRsp= NULLP;
483    uint8_t idx=0;
484    uint8_t idx1=0;
485    RICaction_Admitted_List_t *admitListPtr;
486
487    if(e2apRicMsg != NULLP)
488    {
489       if(e2apRicMsg->choice.successfulOutcome != NULLP)
490       {
491          ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
492          if(ricSubscriptionRsp)
493          {
494             if(ricSubscriptionRsp->protocolIEs.list.array != NULLP)
495             {
496                for(idx=0; idx<ricSubscriptionRsp->protocolIEs.list.count; idx++)
497                {
498                   if(ricSubscriptionRsp->protocolIEs.list.array[idx] != NULLP)
499                   {
500                      switch(ricSubscriptionRsp->protocolIEs.list.array[idx]->id)
501                      {
502                         case ProtocolIE_IDE2_id_RICrequestID:
503                            break;
504
505                         case ProtocolIE_IDE2_id_RANfunctionID:
506                            break;
507
508                         case ProtocolIE_IDE2_id_RICactions_Admitted:
509                            {
510                               admitListPtr = &ricSubscriptionRsp->protocolIEs.list.\
511                                              array[idx]->value.choice.RICaction_Admitted_List;
512                               if(admitListPtr->list.array != NULLP)
513                               {
514                                  for(idx1=0 ; idx1<admitListPtr->list.count; idx1++ )
515                                  {
516                                     if(admitListPtr->list.array[idx1] != NULLP)
517                                     {
518                                        DU_FREE(admitListPtr->list.array[idx1],
519                                              sizeof(RICaction_Admitted_ItemIEs_t));
520                                     }
521                                  }
522                                  DU_FREE(admitListPtr->list.array, admitListPtr->list.size);     
523                               }
524                               break;
525                            }
526                         default:
527                            break;
528                      }
529                      DU_FREE(ricSubscriptionRsp->protocolIEs.list.array[idx], \
530                            sizeof(RICsubscriptionResponse_IEs_t));
531                   }
532                }
533                DU_FREE(ricSubscriptionRsp->protocolIEs.list.array, \
534                      ricSubscriptionRsp->protocolIEs.list.size);
535             }
536          }   
537          DU_FREE(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
538       }         
539       DU_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));        
540    }
541 }
542 /*******************************************************************
543  *
544  * @brief Builds and Send the RicSubscriptionRsp
545  *
546  * @details
547  *
548  *    Function : BuildAndSendRicSubscriptionRsp
549  *
550  * functionality:Fills the RicSubscriptionRsp
551  *
552  * @return ROK     - success
553  *         RFAILED - failure
554  *
555  ******************************************************************/
556 uint8_t  FillRicSubscriptionRsp(RICsubscriptionResponse_t  *ricSubscriptionRsp )
557 {
558    uint8_t idx=0;
559    uint8_t ret = ROK;
560    uint8_t elementCnt = 0;
561    uint8_t BuildRicRequestIdret=ROK;
562    uint8_t BuildRicAdmitListret=ROK;
563
564    elementCnt=3;
565    ricSubscriptionRsp->protocolIEs.list.count = elementCnt;
566    ricSubscriptionRsp->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionResponse_IEs_t);
567    DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array, \
568          ricSubscriptionRsp->protocolIEs.list.size);
569    if(ricSubscriptionRsp->protocolIEs.list.array == NULLP)
570    {
571       DU_LOG("\nERROR  -->  E2AP : Memory allocation for FillRicSubscriptionRsp  failed");
572       ret = RFAILED;
573    }
574    else
575    {
576       for(idx=0; idx<ricSubscriptionRsp->protocolIEs.list.count; idx++)
577       {
578          DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array[idx], \
579                sizeof(RICsubscriptionResponse_IEs_t));
580          if(ricSubscriptionRsp->protocolIEs.list.array[idx] == NULLP)
581          {
582             ret = RFAILED;
583          }
584       }
585       if(ret != RFAILED)
586       {
587
588          idx=0;
589          ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
590          ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
591          ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
592                                                                          RICsubscriptionRequest_IEs__value_PR_RICrequestID;
593          BuildRicRequestIdret =
594             BuildRicRequestId(&ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RICrequestID);
595          if(BuildRicRequestIdret != ROK)
596          {
597             ret = RFAILED;
598          }
599          else
600          {
601             idx++;
602             ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
603             ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
604             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
605                                                                             RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
606             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1;
607
608             idx++;
609             ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactions_Admitted;
610             ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
611             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
612                                                                             RICsubscriptionResponse_IEs__value_PR_RICaction_Admitted_List;
613             BuildRicAdmitListret =
614                BuildRicAdmitList(&ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RICaction_Admitted_List);
615             if(BuildRicAdmitListret != ROK)
616             {
617                ret = RFAILED;
618             }
619          }
620       }
621    }    
622    return ret;
623 }
624 /*******************************************************************
625  *
626  * @brief Builds and Send the RicSubscriptionRsp
627  *
628  * @details
629  *
630  *    Function : BuildAndSendRicSubscriptionRsp
631  *
632  * Functionality:Fills the RicSubscriptionRsp
633  *
634  * @return ROK     - success
635  *         RFAILED - failure
636  *
637  ******************************************************************/
638
639 uint8_t BuildAndSendRicSubscriptionRsp()
640 {
641
642    E2AP_PDU_t         *e2apRicMsg = NULLP;
643    RICsubscriptionResponse_t  *ricSubscriptionRsp=NULLP;
644    asn_enc_rval_t     encRetVal; 
645    uint8_t ret = RFAILED;
646    uint8_t FillRicricSubscriptionRspret;
647
648    while(true)
649    {
650       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Response\n");
651
652       DU_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t)); 
653       if(e2apRicMsg == NULLP)
654       {
655          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
656          break;
657       }
658       e2apRicMsg->present =  E2AP_PDU_PR_successfulOutcome;
659       DU_ALLOC(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
660       if(e2apRicMsg->choice.successfulOutcome == NULLP)
661       {
662          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC subscription Response failed");
663          break;
664       }
665
666       e2apRicMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
667       e2apRicMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
668       e2apRicMsg->choice.successfulOutcome->value.present = \
669                                                             SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse;
670       ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
671
672       FillRicricSubscriptionRspret = FillRicSubscriptionRsp(ricSubscriptionRsp);
673       if(FillRicricSubscriptionRspret != ROK)
674       {
675          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICsubscriptionResponseIE failed");
676          break;
677       }
678
679       /* Prints the Msg formed */
680       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
681
682       memset(encBuf, 0, ENC_BUF_MAX_LEN);
683       encBufSize = 0;
684       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\
685             encBuf);
686       if(encRetVal.encoded == ENCODE_FAIL)
687       {
688          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Response structure (at %s)\n",\
689                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
690          break;
691       }
692       else
693       {
694          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RIC subscription response \n");
695          for(int i=0; i< encBufSize; i++)
696          {
697             printf("%x",encBuf[i]);
698          } 
699       } 
700
701       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL) != ROK)
702       {
703          DU_LOG("\nERROR  -->  E2AP : Sending RIC Subscription Response failed");      
704          break;
705       }
706
707       ret = ROK;
708       break;
709
710    }
711    FreeRicSubscriptionRsp(e2apRicMsg);
712
713    return ret;
714 }
715 /******************************************************************
716  *
717  * @brief Processes E2 Setup Response sent by RIC
718  *
719  * @details
720  *
721  *    Function : procE2SetupRsp
722  *
723  *    Functionality: Processes E2 Setup Response sent by RIC
724  *
725  * @params[in] E2AP_PDU_t ASN decoded E2AP message
726  * @return ROK     - success
727  *         RFAILED - failure
728  *
729  * ****************************************************************/
730 uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg)
731 {
732    uint8_t idx; 
733    uint32_t recvBufLen;             
734    E2setupResponse_t *e2SetRspMsg;
735
736    DU_LOG("\nINFO   -->  E2AP : E2 Setup Response received"); 
737    duCb.e2Status = TRUE; //Set E2 status as true
738    e2SetRspMsg = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
739
740    for(idx=0; idx<e2SetRspMsg->protocolIEs.list.count; idx++)
741    {
742       switch(e2SetRspMsg->protocolIEs.list.array[idx]->id)
743       {
744          case ProtocolIE_IDE2_id_GlobalRIC_ID:
745             {
746                /* To store the Ric Id Params */
747                recvBufLen = sizeof(e2SetRspMsg->protocolIEs.list.array[idx]->value\
748                      .choice.GlobalRIC_ID.pLMN_Identity.size);
749                e2apMsgDb.plmn = NULLP;
750                DU_ALLOC(e2apMsgDb.plmn, recvBufLen);
751                if(e2apMsgDb.plmn)
752                {
753                   memcpy(e2apMsgDb.plmn, e2SetRspMsg->protocolIEs.list.array[idx]\
754                         ->value.choice.GlobalRIC_ID.pLMN_Identity.buf, recvBufLen);
755                   free(e2SetRspMsg->protocolIEs.list.array[idx]->value.choice.\
756                         GlobalRIC_ID.pLMN_Identity.buf);
757                }
758                bitStringToInt(&e2SetRspMsg->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID.ric_ID, &e2apMsgDb.ricId);
759                free(e2SetRspMsg->protocolIEs.list.array[idx]->value.choice.\
760                      GlobalRIC_ID.ric_ID.buf);
761                /*TODO : e2apMsgDb.plmn memory to be deallocated after the usage */
762                break;
763             }
764          default:
765             DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2SetupRsp:%ld",
766                   e2SetRspMsg->protocolIEs.list.array[idx]->id);
767             break;
768       }
769       free(e2SetRspMsg->protocolIEs.list.array[idx]);
770    }
771    free(e2SetRspMsg->protocolIEs.list.array);
772    return ROK;
773 }
774
775 /******************************************************************
776  *
777  * @brief Processes RIC Subscription Req sent by RIC
778  *
779  * @details
780  *
781  *    Function : procRicSubsReq
782  *
783  *    Functionality: Processes E2 Setup Response sent by CU
784  *
785  * @params[in] E2AP_PDU_t ASN decoded E2AP message
786  * @return ROK     - success
787  *         RFAILED - failure
788  *
789  * ****************************************************************/
790
791 uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg)
792 {
793    uint8_t idx; 
794    uint8_t ied; 
795    uint8_t ret = ROK;
796    uint32_t recvBufLen;             
797    RICsubscriptionRequest_t *ricSubsReq;
798    RICaction_ToBeSetup_ItemIEs_t *actionItem;
799
800    DU_LOG("\nINFO   -->  E2AP : RIC Subscription request received"); 
801    ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
802
803    for(idx=0; idx<ricSubsReq->protocolIEs.list.count; idx++)
804    {
805       if(ricSubsReq->protocolIEs.list.array[idx])
806       {
807          switch(ricSubsReq->protocolIEs.list.array[idx]->id)
808          {
809             case ProtocolIE_IDE2_id_RICrequestID:
810                {
811                   e2apMsgDb.ricReqId = ricSubsReq->protocolIEs.list.array[idx]->\
812                                        value.choice.RICrequestID.ricRequestorID;
813                   e2apMsgDb.ricInstanceId = ricSubsReq->protocolIEs.list.array[idx]-> \
814                                             value.choice.RICrequestID.ricInstanceID;
815                   break;
816                }
817             case ProtocolIE_IDE2_id_RANfunctionID:
818                {
819                   e2apMsgDb.ranFuncId = ricSubsReq->protocolIEs.list.array[idx]-> \
820                                         value.choice.RANfunctionID; 
821                   break;
822                }
823             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
824                {
825                   recvBufLen = sizeof(ricSubsReq->protocolIEs.list.array[idx]->value\
826                         .choice.RICsubscriptionDetails.ricEventTriggerDefinition.size);
827                   e2apMsgDb.ricEventTrigger = NULLP;
828                   DU_ALLOC(e2apMsgDb.ricEventTrigger, recvBufLen);
829                   /*TODO : e2apMsgDb.ricEventTrigger memory to be deallocated after the usage */
830                   if(e2apMsgDb.ricEventTrigger)
831                   {
832                      memcpy(e2apMsgDb.ricEventTrigger, ricSubsReq->protocolIEs.list.array[idx]\
833                            ->value.choice.RICsubscriptionDetails.ricEventTriggerDefinition.buf, \
834                            recvBufLen);
835                      free(ricSubsReq->protocolIEs.list.array[idx]->value.choice.\
836                            RICsubscriptionDetails.ricEventTriggerDefinition.buf);
837                   }
838                   if(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\
839                         list.array)
840                   {
841                      actionItem =(RICaction_ToBeSetup_ItemIEs_t *)ricSubsReq->protocolIEs.list\
842                                  .array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List\
843                                  .list.array[0];
844
845                      for(ied = 0; ied < ricSubsReq->protocolIEs.list.array[idx]->value.choice.\
846                            RICsubscriptionDetails.ricAction_ToBeSetup_List.list.count; ied++)
847                      {
848                         switch(actionItem->id)
849                         {
850                            case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item:
851                               {
852                                  e2apMsgDb.ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
853                                  e2apMsgDb.ricActionType = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType;
854                                  break;
855                               }
856                            default:
857                               DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id);
858                               break;
859                         }
860                         free(actionItem);
861                      }
862                      free(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\
863                      list.array);
864                   }
865                   break;
866                }
867
868             default:
869                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RIC SubsReq:%ld",
870                      ricSubsReq->protocolIEs.list.array[idx]->id);
871                break;
872          }
873          free(ricSubsReq->protocolIEs.list.array[idx]);
874       }
875    }
876    free(ricSubsReq->protocolIEs.list.array);
877    ret = BuildAndSendRicSubscriptionRsp();
878
879    return ret;
880 }
881
882 /*******************************************************************
883  *
884  * @brief Free the RicIndication Message
885  *
886  * @details
887  *
888  *    Function : FreeRicIndication
889  *
890  * Functionality: Free the RicIndication Message
891  *
892  * @return void
893  *         
894  *
895  ******************************************************************/
896 void FreeRicIndication(E2AP_PDU_t  *e2apMsg) 
897 {
898    uint8_t idx=0;
899    RICindication_t *ricIndicationMsg= NULLP;
900
901
902    if(e2apMsg != NULLP)
903    {
904       if(e2apMsg->choice.initiatingMessage != NULLP)
905       {
906          ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
907          if(ricIndicationMsg!= NULLP)
908          {
909             if(ricIndicationMsg->protocolIEs.list.array != NULLP)
910             {
911                for(idx=0; idx<ricIndicationMsg->protocolIEs.list.count; idx++)
912                {
913                   if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP)
914                   {
915                      switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
916                      {
917                         case ProtocolIE_IDE2_id_RICrequestID:
918                            break;
919
920                         case ProtocolIE_IDE2_id_RANfunctionID:
921                            break;
922
923                         case ProtocolIE_IDE2_id_RICactionID:
924                            break;
925
926                         case ProtocolIE_IDE2_id_RICindicationType:
927                            break;
928
929                         case ProtocolIE_IDE2_id_RICindicationHeader:
930                            {
931                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\
932                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
933                               break;
934                            }
935                         case ProtocolIE_IDE2_id_RICindicationMessage:
936                            {
937                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\
938                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
939                               break;
940                            }
941                         default:
942                            break;
943                      }
944                      DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t));
945                   }
946                }
947                DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size);
948             }
949          }
950          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
951       }
952       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
953    }
954 }
955 /*******************************************************************
956  *
957  * brief Fill the RicIndication Message
958  *
959  * @details
960  *
961  *    Function : FillRicIndication
962  *
963  * Functionality:Fills the RicIndication Message
964  *
965  * @return ROK     - success
966  *         RFAILED - failure
967  *
968  ******************************************************************/
969 uint8_t FillRicIndication(RICindication_t *ricIndicationMsg)
970 {
971    uint8_t elementCnt=0;
972    uint8_t idx=0;
973    uint8_t ret = ROK;
974    elementCnt = 6;
975
976    ricIndicationMsg->protocolIEs.list.count = elementCnt;
977    ricIndicationMsg->protocolIEs.list.size  = elementCnt * sizeof(RICindication_t);
978    /* Initialize the Ric Indication members */
979    DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, \
980          ricIndicationMsg->protocolIEs.list.size);
981    if(ricIndicationMsg->protocolIEs.list.array == NULLP)
982    {
983       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
984       ret = RFAILED;
985    }
986    else
987    {
988       for(idx=0; idx<elementCnt; idx++)
989       {
990          DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx],\
991                sizeof(RICindication_IEs_t));
992          if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
993          {
994             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
995             ret = RFAILED;
996          }
997       }
998       if(ret != RFAILED)
999       {
1000          idx = 0;
1001
1002          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
1003          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1004          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1005                                                                         RICindication_IEs__value_PR_RICrequestID;
1006          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID =\
1007                                                                                                   e2apMsgDb.ricReqId;
1008          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID =\
1009                                                                                                  e2apMsgDb.ricInstanceId;
1010
1011          idx++;
1012          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
1013          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1014          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1015                                                                         RICindication_IEs__value_PR_RANfunctionID;
1016          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID =
1017             e2apMsgDb.ranFuncId;
1018
1019          idx++;
1020          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
1021          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1022          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1023                                                                         RICindication_IEs__value_PR_RICactionID;
1024          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID =
1025             e2apMsgDb.ricActionId;
1026
1027          idx++;
1028          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
1029          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1030          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1031                                                                         RICindication_IEs__value_PR_RICindicationType;
1032          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType =
1033             e2apMsgDb.ricActionType;
1034
1035          idx++;
1036          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
1037          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1038          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1039                                                                         RICindication_IEs__value_PR_RICindicationHeader;
1040          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size = 3 *
1041             sizeof(uint8_t);
1042          DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf ,\
1043                ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
1044          if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf == NULLP)
1045          {
1046             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1047             ret = RFAILED;
1048          }
1049          else
1050          {
1051             buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
1052                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf);
1053             idx++;
1054             /* TO BE CHANGED: RIC INDICATION DATA */
1055             /* For now filling a dummy octect data, need to tested with PRBs*/
1056             ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
1057             ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1058             ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1059                                                                            RICindication_IEs__value_PR_RICindicationMessage;
1060             ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size = 3 *
1061                sizeof(uint8_t);
1062             DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf ,\
1063                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
1064             if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf == NULLP)
1065             {
1066                DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1067                ret = RFAILED;
1068             }
1069             else
1070             {
1071                buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
1072                      ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf);
1073             }
1074          }
1075       }
1076    }
1077    return ret;
1078 }
1079
1080 /*******************************************************************
1081  *
1082  * @brief Builds and Send the RicIndication Message
1083  *
1084  * @details
1085  *
1086  *    Function : BuildAndSendRicIndication
1087  *
1088  * Functionality:Fills the RicIndication Message
1089  *
1090  * @return ROK     - success
1091  *         RFAILED - failure
1092  *
1093  ******************************************************************/
1094
1095 uint8_t BuildAndSendRicIndication()
1096 {
1097    E2AP_PDU_t                 *e2apMsg = NULLP;
1098    RICindication_t            *ricIndicationMsg=NULLP;
1099    asn_enc_rval_t             encRetVal;        /* Encoder return value */
1100    uint8_t ret = RFAILED; 
1101    uint8_t FillRicIndicationret = ROK;
1102
1103    while(true)
1104    {
1105       DU_LOG("\nINFO   -->  E2AP : Building RIC Indication Message\n");
1106
1107       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1108       if(e2apMsg == NULLP)
1109       {
1110          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1111          break;
1112       }
1113
1114       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
1115       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1116       if(e2apMsg->choice.initiatingMessage == NULLP)
1117       {
1118          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1119          break;
1120       }
1121       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
1122       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
1123       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication;
1124
1125       ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
1126
1127       FillRicIndicationret = FillRicIndication(ricIndicationMsg);
1128       if(FillRicIndicationret != ROK)
1129       {
1130          break;
1131       }
1132       /* Prints the Msg formed */
1133       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1134       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1135       encBufSize = 0;
1136       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
1137             encBuf);
1138       if(encRetVal.encoded == ENCODE_FAIL)
1139       {
1140          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Indication Message (at %s)\n",\
1141                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1142          break;
1143       }
1144       else
1145       {
1146          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Indication Message \n");
1147          for(int i=0; i< encBufSize; i++)
1148          {
1149             printf("%x",encBuf[i]);
1150          } 
1151       }
1152
1153       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL) != ROK)
1154       {
1155          DU_LOG("\nINFO   -->  E2AP : Sending RIC Indication Message");      
1156
1157       }
1158       ret = ROK;
1159       break;
1160    }
1161    FreeRicIndication(e2apMsg);  
1162    return ret;
1163 }
1164
1165 /*******************************************************************
1166  *
1167  * @brief Sends E2 msg over SCTP
1168  *
1169  * @details
1170  *
1171  *    Function : SendE2APMsg
1172  *
1173  *    Functionality: Sends E2 msg over SCTP
1174  *
1175  * @params[in] Region region
1176  *             Pool pool
1177  * @return ROK     - success
1178  *         RFAILED - failure
1179  *
1180  * ****************************************************************/
1181
1182 uint8_t SendE2APMsg(Region region, Pool pool)
1183 {
1184    Buffer *mBuf=NULLP;
1185
1186    if(ODU_GET_MSG_BUF(region, pool, &mBuf) == ROK)
1187    {
1188       if(ODU_ADD_POST_MSG_MULT((Data *)encBuf, encBufSize, mBuf) == ROK)
1189       {
1190          ODU_PRINT_MSG(mBuf, 0,0);
1191
1192          if(sctpSend(mBuf, E2_INTERFACE) != ROK)
1193          {
1194             DU_LOG("\nERROR  -->  E2AP : SCTP Send for E2  failed");
1195             ODU_PUT_MSG_BUF(mBuf);
1196             return RFAILED;
1197          }
1198       }
1199       else
1200       {
1201          DU_LOG("\nERROR  -->  E2AP : ODU_ADD_POST_MSG_MULT failed");
1202          ODU_PUT_MSG_BUF(mBuf);
1203          return RFAILED;
1204       }
1205       ODU_PUT_MSG_BUF(mBuf);
1206    }
1207    else
1208    {
1209       DU_LOG("\nERROR  -->  E2AP : Failed to allocate memory");
1210       return RFAILED;
1211    }
1212
1213    return ROK;
1214 } /* SendE2APMsg */
1215
1216 /*******************************************************************
1217  *
1218  * @brief Handles received E2AP message and sends back response  
1219  *
1220  * @details
1221  *
1222  *    Function : E2APMsgHdlr
1223  *
1224  *    Functionality:
1225  *         - Decodes received E2AP control message
1226  *         - Prepares response message, encodes and sends to SCTP
1227  *
1228  * @params[in] 
1229  * @return ROK     - success
1230  *         RFAILED - failure
1231  *
1232  * ****************************************************************/
1233 void E2APMsgHdlr(Buffer *mBuf)
1234 {
1235    int i =0;
1236    char *recvBuf = NULLP;
1237    MsgLen copyCnt =0;
1238    MsgLen recvBufLen =0;
1239    E2AP_PDU_t *e2apMsg = NULLP;
1240    asn_dec_rval_t rval ={0}; /* Decoder return value */
1241    E2AP_PDU_t e2apasnmsg={0} ;
1242
1243    DU_LOG("\nDEBUG   -->  E2AP : Received E2AP message buffer");
1244    ODU_PRINT_MSG(mBuf, 0,0);
1245
1246    /* Copy mBuf into char array to decode it */
1247    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
1248    DU_ALLOC(recvBuf, (Size)recvBufLen);
1249
1250    if(recvBuf == NULLP)
1251    {
1252       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
1253       return;
1254    }
1255    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
1256    {
1257       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
1258       return;
1259    }
1260
1261    printf("\nDEBUG   -->  E2AP : Received flat buffer to be decoded : ");
1262    for(i=0; i< recvBufLen; i++)
1263    {
1264       printf("%x",recvBuf[i]);
1265    }
1266
1267    /* Decoding flat buffer into E2AP messsage */
1268    e2apMsg = &e2apasnmsg;
1269    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
1270
1271    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
1272    DU_FREE(recvBuf, (Size)recvBufLen);
1273
1274    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
1275    {
1276       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
1277       return;
1278    }
1279    printf("\n");
1280    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1281
1282    switch(e2apMsg->present)
1283    {
1284       case E2AP_PDU_PR_successfulOutcome:
1285          {
1286             switch(e2apMsg->choice.successfulOutcome->value.present)
1287             {
1288                case SuccessfulOutcomeE2__value_PR_E2setupResponse:
1289                   {
1290                      if(!duCb.e2Status)
1291                      {
1292                         DU_LOG("\nDEBUG   -->  E2AP : Store E2 setup response Params");
1293                         procE2SetupRsp(e2apMsg);
1294                      }
1295                      break;
1296                   }
1297                default:
1298                   {
1299                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome  [%d]",\
1300                      e2apMsg->choice.successfulOutcome->value.present);
1301                      return;
1302                   }
1303             }/* End of switch(successfulOutcome) */
1304             free(e2apMsg->choice.successfulOutcome);
1305             break;
1306          }
1307       case E2AP_PDU_PR_initiatingMessage:
1308          {
1309             switch(e2apMsg->choice.initiatingMessage->value.present)
1310             {
1311                case InitiatingMessageE2__value_PR_RICsubscriptionRequest: 
1312                   {
1313                      if(procRicSubsReq(e2apMsg) == ROK)
1314                      {
1315                         BuildAndSendRicIndication();
1316                      }
1317                      break;
1318                   }
1319                default:
1320                   {
1321                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\
1322                      e2apMsg->choice.initiatingMessage->value.present);
1323                      return;
1324                   }
1325             }/* End of switch(initiatingMessage) */
1326             free(e2apMsg->choice.initiatingMessage);
1327             break;
1328          }
1329       default:
1330          {
1331             DU_LOG("\nERROR  -->  E2AP : Invalid type of e2apMsg->present [%d]",e2apMsg->present);
1332             return;
1333          }
1334          free(e2apMsg);
1335
1336    }/* End of switch(e2apMsg->present) */
1337
1338 } /* End of E2APMsgHdlr */
1339
1340 /**********************************************************************
1341   End of file
1342  **********************************************************************/