E2AP code changes
[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 "du_e2ap_msg_hdl.h"
19 #include "du_mgr_main.h"
20 #include "du_cfg.h"
21 #include "GlobalE2node-gNB-ID.h"
22
23 #define ENC_BUF_MAX_LEN 100
24
25 /* Global variable */
26 DuCfgParams duCfgParam;
27 char encBuf[ENC_BUF_MAX_LEN];
28 int  encBufSize;
29
30 S16 SendE2APMsg(Region , Pool );
31
32
33 /*******************************************************************
34  *
35  * @brief Writes the encoded chunks into a buffer
36  *
37  * @details
38  *
39  *    Function : PrepFinalEncBuf
40  *
41  *    Functionality:Fills the encoded buffer
42  *
43  * @params[in] void *buffer,initial encoded data
44  * @params[in] size_t size,size of buffer
45  * @params[in] void *encodedBuf,final buffer
46  * @return ROK     - success
47  *         RFAILED - failure
48  *
49  * ****************************************************************/
50 static int PrepFinalEncBuf(const void *buffer, size_t size, void *encodedBuf)
51 {
52    memcpy(encodedBuf + encBufSize, buffer, size);
53    encBufSize += size;
54    return 0;
55 } /* PrepFinalEncBuf */
56
57 /*******************************************************************
58  *
59  * @brief Builds PLMN ID 
60  *
61  * @details
62  *
63  *    Function : BuildPlmnId
64  *
65  *    Functionality: Building the PLMN ID
66  *
67  * @params[in] PLMNID plmn
68  *             OCTET_STRING_t *plmnid
69  * @return ROK     - success
70  *         RFAILED - failure
71  *
72  * ****************************************************************/
73
74 S16 BuildPlmnId(PlmnId plmn, OCTET_STRING_t *plmnid)
75 {
76    U8 mncCnt;
77    plmnid->size = 3;
78    DU_ALLOC(plmnid->buf,  plmnid->size * sizeof(U8));
79    if(plmnid->buf == NULLP)
80    {
81       RETVALUE(RFAILED);
82    }
83    mncCnt = 2;
84    plmnid->buf[0] = ((plmn.mcc[1] << 4) | (plmn.mcc[0]));
85    if(mncCnt == 2)
86    {
87       plmnid->buf[1]  = ((0xf0) | (plmn.mcc[2]));
88       plmnid->buf[2] = ((plmn.mnc[1] << 4) | (plmn.mnc[0]));
89    }
90    else
91    {
92       plmnid->buf[1] = ((plmn.mnc[0] << 4) | (plmn.mcc[2]));
93       plmnid->buf[2] = ((plmn.mnc[2] << 4) | (plmn.mnc[1]));
94    }
95   RETVALUE(ROK);
96 }
97
98 /*******************************************************************
99  *
100  * @brief Builds NodeB Id
101  *
102  * @details
103  *
104  *    Function : BuildNodeBId
105  *
106  *    Functionality: Building the NodeBId
107  *
108  * @params[in] BIT_STRING_t *nbid,
109  *             U8 unusedBits
110  *             U8 byteSize
111  *             U8 val
112  *
113  * @return ROK     - success
114  *         RFAILED - failure
115  *
116  * ****************************************************************/
117
118 S16 BuildNodeBId(BIT_STRING_t *nbid, U8 unusedBits, U8 byteSize, U8 val)
119 {
120    U8 tmp;
121    nbid->size = byteSize;
122    DU_ALLOC(nbid->buf, nbid->size * sizeof(U8));
123    if(nbid->buf == NULLP)
124    {
125       RETVALUE(RFAILED);
126    }
127
128    for (tmp = 0 ; tmp < ((nbid->size)-1); tmp++)
129    {
130       nbid->buf[tmp] = 0;
131    }
132    nbid->buf[byteSize-1] = val; 
133    nbid->bits_unused = unusedBits;
134    RETVALUE(ROK);
135 }
136
137 /*******************************************************************
138  *
139  * @brief Builds Global gNodeB Params
140  *
141  * @details
142  *
143  *    Function : BuildGlobalgNB
144  *
145  *    Functionality: Building the Plmn and gNB id
146  *
147  * @params[in] GlobalE2node_gNB_ID_t *gNbId
148  * @return ROK     - success
149  *         RFAILED - failure
150  *
151  * ****************************************************************/
152
153 S16 BuildGlobalgNB(GlobalE2node_gNB_ID_t *gNbId)
154 {
155    U8 unused = 0;
156    U8 byteSize = 4;
157    U8 val = 1;
158    if(gNbId != NULLP)
159    {
160       BuildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
161        &gNbId->global_gNB_ID.plmn_id); 
162       /* fill gND Id */
163       gNbId->global_gNB_ID.gnb_id.present = GNB_ID_Choice_PR_gnb_ID; 
164       BuildNodeBId(&gNbId->global_gNB_ID.gnb_id.choice.gnb_ID, unused, byteSize, val);
165    }
166    RETVALUE(ROK);   
167 }
168
169 #if 0
170 RANfunction_ItemIEs_t* BuildRanFuncItems(RANfunction_ItemIEs_t *items)
171 {
172    U8 byteSize;
173    U8 tmp;
174    byteSize = 3;
175
176    items->id = ProtocolIE_IDE2_id_RANfunctionID;   
177    items->criticality = CriticalityE2_ignore;   
178    items->value.present = RANfunction_ItemIEs__value_PR_RANfunction_Item;
179
180    items->value.choice.RANfunction_Item.ranFunctionID = 1;
181    BuildPlmn(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, &items->value.choice.RANfunction_Item.ranFunctionDefinition);
182    items->value.choice.RANfunction_Item.ranFunctionRevision = 4; 
183
184    RETVALUE(items);
185 }
186
187 S16 BuildRANList(RANfunctions_List_t *ranFuncList)
188 {
189    U8 elementCnt;
190    U8 eleidx;
191    S16 ret;
192    RANfunction_ItemIEs_t *funcItems;
193
194    elementCnt = 1; 
195    ranFuncList->list.count = elementCnt;
196    ranFuncList->list.size = elementCnt * sizeof(RANfunction_ItemIEs_t);
197    DU_ALLOC(ranFuncList->list.array, \
198              ranFuncList->list.size);
199    if(ranFuncList->list.array == NULLP)
200    {
201       DU_LOG("\nE2AP : Memory allocation for RAN Function List failed");
202       RETVALUE(RFAILED);
203    }
204    /* Fill RAN function Params */
205    DU_ALLOC(ranFuncList->list.array[0], sizeof(RANfunction_ItemIEs_t));
206    BuildRanFuncItems(ranFuncList->list.array[0]);
207
208    RETVALUE(ROK);
209 }
210 #endif
211
212 /*******************************************************************
213  *
214  * @brief Builds and Send the E2SetupRequest
215  *
216  * @details
217  *
218  *    Function : BuildAndSendE2SetupReq
219  *
220  * Functionality:Fills the E2SetupRequest
221  *
222  * @return ROK     - success
223  *         RFAILED - failure
224  *
225  ******************************************************************/
226
227 S16 BuildAndSendE2SetupReq()
228 {
229    E2AP_PDU_t                 *e2apMsg = NULLP;
230    E2setupRequest_t           *e2SetupReq;
231    U8   elementCnt;
232    U8   idx;
233    U8   ieId;
234    S16  ret; 
235    asn_enc_rval_t             encRetVal;        /* Encoder return value */
236
237    DU_LOG("\nE2AP : Building E2 Setup Request\n");
238
239    DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
240    if(e2apMsg == NULLP)
241    {
242       DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
243       RETVALUE(RFAILED);
244    }
245
246    e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
247    DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
248    if(e2apMsg->choice.initiatingMessage == NULLP)
249    {
250       DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
251       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
252       RETVALUE(RFAILED);
253    }
254    e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
255    e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2setup;
256    e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2setupRequest;
257    
258    DU_ALLOC(e2SetupReq, sizeof(E2setupRequest_t));
259    e2SetupReq = &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest;
260    
261    elementCnt = 1;
262    
263    e2SetupReq->protocolIEs.list.count = elementCnt;
264    e2SetupReq->protocolIEs.list.size = elementCnt * sizeof(E2setupRequestIEs_t);
265
266    /* Initialize the E2Setup members */
267    DU_ALLOC(e2SetupReq->protocolIEs.list.array, \
268             e2SetupReq->protocolIEs.list.size);
269    if(e2SetupReq->protocolIEs.list.array == NULLP)
270    {
271       DU_LOG("\nE2AP : Memory allocation for E2RequestIEs failed");
272       DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
273       DU_FREE(e2apMsg, (Size)sizeof(E2AP_PDU_t));
274       RETVALUE(RFAILED);
275    }
276    
277    for(idx=0; idx<elementCnt; idx++)
278    {
279       DU_ALLOC(e2SetupReq->protocolIEs.list.array[idx],\
280             sizeof(E2setupRequestIEs_t));
281       if(e2SetupReq->protocolIEs.list.array[idx] == NULLP)
282       {
283          for(ieId=0; ieId<idx; ieId++)
284          {
285             DU_FREE(e2SetupReq->protocolIEs.list.array[ieId],\
286                   sizeof(E2setupRequestIEs_t));
287          }
288          DU_FREE(e2SetupReq->protocolIEs.list.array,\
289                  e2SetupReq->protocolIEs.list.size);
290          DU_FREE(e2apMsg->choice.initiatingMessage, \
291                sizeof(InitiatingMessageE2_t));
292          DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
293          RETVALUE(RFAILED);
294       }
295    }
296
297    idx = 0;
298    /* GlobalE2node_gNB_ID */
299    e2SetupReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_GlobalE2node_ID;
300    e2SetupReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
301    e2SetupReq->protocolIEs.list.array[idx]->value.present =\
302                                     E2setupRequestIEs__value_PR_GlobalE2node_ID;
303    e2SetupReq->protocolIEs.list.array[idx]->value.choice.GlobalE2node_ID.present = \
304                                                                    GlobalE2node_ID_PR_gNB;
305    
306    GlobalE2node_gNB_ID_t *gNbId;
307    DU_ALLOC(gNbId, sizeof(GlobalE2node_gNB_ID_t));
308    BuildGlobalgNB(gNbId);
309    e2SetupReq->protocolIEs.list.array[idx]->value.choice.GlobalE2node_ID.choice.gNB = gNbId;
310
311    /* Prints the Msg formed */
312    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
313
314
315    cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
316    encBufSize = 0;
317    encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
318                encBuf);
319    if(encRetVal.encoded == ENCODE_FAIL)
320    {
321            DU_LOG("\nE2AP : Could not encode E2SetupRequest structure (at %s)\n",\
322                            encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
323            RETVALUE(RFAILED);
324    }
325    else
326    {
327            DU_LOG("\nE2AP : Created APER encoded buffer for E2SetupRequest\n");
328            for(int i=0; i< encBufSize; i++)
329            {
330                    printf("%x",encBuf[i]);
331            } 
332    }
333
334    if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL) != ROK)
335    {
336            DU_LOG("\nE2AP : Sending E2 Setup request failed");
337            RETVALUE(RFAILED);
338    }
339
340    RETVALUE(ROK);
341 }/* End of BuildAndSendE2SetupReq */
342
343 /*******************************************************************
344  *
345  * @brief Builds Ric Request Id
346  *
347  * @details
348  *
349  *    Function : BuildRicRequestId
350  *
351  *    Functionality: Building the Ric Request Id
352  *
353  * @params[in] RICrequestID_t *ricReqId
354  * @return ROK     - success
355  *         RFAILED - failure
356  *
357  * ****************************************************************/
358
359 S16 BuildRicRequestId(RICrequestID_t *ricReqId)
360 {
361    if(ricReqId != NULLP)
362    {
363       ricReqId->ricRequestorID = 1;
364       ricReqId->ricInstanceID  = 1;
365    }
366    RETVALUE(ROK);
367 }
368
369 /*******************************************************************
370  *
371  * @brief Fills the mandatory RicAdmitted List Items
372  *
373  * @details
374  *
375  *    Function : fillRicAdmitList
376  *
377  *    Functionality: Fills the mandatory Ric Admitted List Items
378  *
379  * @params[in] RICaction_Admitted_ItemIEs_t *ricAdmitItems
380  * @return ROK     - success
381  *         RFAILED - failure
382  *
383  * ****************************************************************/
384
385 S16 fillRicAdmitList(RICaction_Admitted_ItemIEs_t *ricAdmitItems)
386 {
387
388    if(ricAdmitItems != NULLP)
389    {
390       ricAdmitItems->id = ProtocolIE_IDE2_id_RICaction_Admitted_Item;
391       ricAdmitItems->criticality = CriticalityE2_reject;
392       ricAdmitItems->value.present = RICaction_Admitted_ItemIEs__value_PR_RICaction_Admitted_Item;
393       ricAdmitItems->value.choice.RICaction_Admitted_Item.ricActionID = 1; 
394    }
395    RETVALUE(ROK);
396 }
397 /*******************************************************************
398  *
399  * @brief Builds the mandatory RicAdmitted List Params
400  *
401  * @details
402  *
403  *    Function : fillRicAdmitList
404  *
405  *    Functionality: Builds the mandatory Ric Admitted List Params
406  *
407  * @params[in] RICaction_Admitted_List_t *admitListPtr
408  * @return ROK     - success
409  *         RFAILED - failure
410  *
411  * ****************************************************************/
412
413 S16 BuildRicAdmitList(RICaction_Admitted_List_t *admitListPtr)
414 {
415    U8 elementCnt; 
416
417    elementCnt = 1; 
418    admitListPtr->list.count = elementCnt;
419    admitListPtr->list.size  = elementCnt * sizeof(RICaction_Admitted_ItemIEs_t);
420    DU_ALLOC(admitListPtr->list.array, admitListPtr->list.size);
421    if(admitListPtr->list.array == NULLP)
422    {
423       DU_LOG("\nE2AP : Memory allocation for RIC Admit List failed");
424       RETVALUE(RFAILED);
425    }
426    DU_ALLOC(admitListPtr->list.array[0], sizeof(RICaction_Admitted_ItemIEs_t));
427    fillRicAdmitList(admitListPtr->list.array[0]);
428
429    RETVALUE(ROK);
430 }
431
432 /*******************************************************************
433  *
434  * @brief Builds and Send the RicSubscriptionRsp
435  *
436  * @details
437  *
438  *    Function : BuildAndSendRicSubscriptionRsp
439  *
440  * Functionality:Fills the RicSubscriptionRsp
441  *
442  * @return ROK     - success
443  *         RFAILED - failure
444  *
445  ******************************************************************/
446
447 S16 BuildAndSendRicSubscriptionRsp()
448 {
449
450    E2AP_PDU_t         *e2apRicMsg = NULLP;
451    RICsubscriptionResponse_t  *ricSubscriptionRsp;
452    asn_enc_rval_t     encRetVal; 
453    U8 idx;
454    U8 elementCnt;
455
456  
457    DU_LOG("\nE2AP : Building RIC Subscription Response\n");
458
459    DU_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t)); 
460    if(e2apRicMsg == NULLP)
461    {
462       DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
463       RETVALUE(RFAILED);
464    }
465    e2apRicMsg->present =  E2AP_PDU_PR_successfulOutcome;
466    DU_ALLOC(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
467    if(e2apRicMsg->choice.successfulOutcome == NULLP)
468    {
469       DU_LOG("\nE2AP : Memory allocation for Ric subscription Response failed");
470       DU_FREE(e2apRicMsg, sizeof(RICsubscriptionResponse_t));
471       RETVALUE(RFAILED);  
472    }
473
474    e2apRicMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
475    e2apRicMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
476    e2apRicMsg->choice.successfulOutcome->value.present = \
477          SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse;
478    ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
479
480    elementCnt = 3;
481    ricSubscriptionRsp->protocolIEs.list.count = elementCnt;
482    ricSubscriptionRsp->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionResponse_IEs_t);
483
484    DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array, \
485               ricSubscriptionRsp->protocolIEs.list.size);
486    if(ricSubscriptionRsp->protocolIEs.list.array == NULLP)
487    {
488       DU_LOG("\nE2AP : Memory allocation for RICsubscriptionResponseIE failed");
489       DU_FREE(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
490       DU_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
491       RETVALUE(RFAILED);
492    }
493
494    for(idx=0; idx<elementCnt; idx++)
495    {
496       DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array[idx], \
497             sizeof(RICsubscriptionResponse_IEs_t)); 
498       if(ricSubscriptionRsp->protocolIEs.list.array[idx] == NULLP)
499       {  
500          DU_FREE(ricSubscriptionRsp->protocolIEs.list.array,\
501                    ricSubscriptionRsp->protocolIEs.list.size);
502          DU_FREE(e2apRicMsg->choice.successfulOutcome, \
503                sizeof(SuccessfulOutcomeE2_t));
504          DU_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
505          RETVALUE(RFAILED);
506       }    
507    }
508    idx = 0;
509    ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
510    ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
511    ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
512             RICsubscriptionRequest_IEs__value_PR_RICrequestID;
513    BuildRicRequestId(&ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RICrequestID);
514    
515    idx++;
516    ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
517    ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
518    ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
519                                     RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
520    ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1;
521
522    idx++;
523    ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactions_Admitted;
524    ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
525    ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
526                                RICsubscriptionResponse_IEs__value_PR_RICaction_Admitted_List;
527    BuildRicAdmitList(&ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RICaction_Admitted_List);
528
529
530    /* Prints the Msg formed */
531    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
532
533    cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
534    encBufSize = 0;
535    encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\
536                encBuf);
537    if(encRetVal.encoded == ENCODE_FAIL)
538    {
539            DU_LOG("\nE2AP : Could not encode RIC Subscription Response structure (at %s)\n",\
540                            encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
541            RETVALUE(RFAILED);
542    }
543    else
544    {
545            DU_LOG("\nE2AP : Created APER encoded buffer for RIC subscription response \n");
546            for(int i=0; i< encBufSize; i++)
547            {
548                    printf("%x",encBuf[i]);
549            } 
550    }
551
552    if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL) != ROK)
553    {
554       DU_LOG("\nE2AP : Sending RIC Subscription Response failed");      
555       RETVALUE(RFAILED);
556    }
557    
558    RETVALUE(ROK);
559 }
560
561 /*******************************************************************
562  *
563  * @brief Builds and Send the RicIndication Message
564  *
565  * @details
566  *
567  *    Function : BuildAndSendRicIndication
568  *
569  * Functionality:Fills the RicIndication Message
570  *
571  * @return ROK     - success
572  *         RFAILED - failure
573  *
574  ******************************************************************/
575
576 S16 BuildAndSendRicIndication()
577 {
578    E2AP_PDU_t                 *e2apMsg = NULLP;
579    RICindication_t            *ricIndicationMsg;
580    E2apMsgDb                   e2apMsgDb;
581    U8   elementCnt;
582    U8   idx;
583    U8   ieId;
584    S16  ret; 
585    asn_enc_rval_t             encRetVal;        /* Encoder return value */
586
587    DU_LOG("\nE2AP : Building Ric Indication Message\n");
588
589    DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
590    if(e2apMsg == NULLP)
591    {
592       DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
593       RETVALUE(RFAILED);
594    }
595
596    e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
597    DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
598    if(e2apMsg->choice.initiatingMessage == NULLP)
599    {
600       DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
601       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
602       RETVALUE(RFAILED);
603    }
604    e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
605    e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
606    e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication;
607    
608    DU_ALLOC(ricIndicationMsg, sizeof(RICindication_t));
609    ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
610    
611    elementCnt = 6;
612    
613    ricIndicationMsg->protocolIEs.list.count = elementCnt;
614    ricIndicationMsg->protocolIEs.list.size  = elementCnt * sizeof(RICindication_t);
615
616    /* Initialize the Ric Indication members */
617    DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, \
618             ricIndicationMsg->protocolIEs.list.size);
619    if(ricIndicationMsg->protocolIEs.list.array == NULLP)
620    {
621       DU_LOG("\nE2AP : Memory allocation for RICindicationIEs failed");
622       DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
623       DU_FREE(e2apMsg, (Size)sizeof(E2AP_PDU_t));
624       RETVALUE(RFAILED);
625    }
626    
627    for(idx=0; idx<elementCnt; idx++)
628    {
629       DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx],\
630             sizeof(RICindication_IEs_t));
631       if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
632       {
633          for(ieId=0; ieId<idx; ieId++)
634          {
635             DU_FREE(ricIndicationMsg->protocolIEs.list.array[ieId],\
636                   sizeof(RICindication_IEs_t));
637          }
638          DU_FREE(ricIndicationMsg->protocolIEs.list.array,\
639                  ricIndicationMsg->protocolIEs.list.size);
640          DU_FREE(e2apMsg->choice.initiatingMessage, \
641                sizeof(InitiatingMessageE2_t));
642          DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
643          RETVALUE(RFAILED);
644       }
645    }
646    idx = 0;
647    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
648    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
649    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
650                                     RICindication_IEs__value_PR_RICrequestID;
651    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID = e2apMsgDb.ricReqId;
652    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID = e2apMsgDb.ricInstanceId;
653
654    idx++;
655    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
656    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
657    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
658                                    RICindication_IEs__value_PR_RANfunctionID;
659    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = e2apMsgDb.ranFuncId;
660
661    idx++;
662    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
663    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
664    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
665                                    RICindication_IEs__value_PR_RICactionID;
666    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = e2apMsgDb.ricActionId;
667
668
669    idx++;
670    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
671    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
672    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
673                                    RICindication_IEs__value_PR_RICindicationType;
674
675    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = e2apMsgDb.ricActionType;
676
677
678    idx++;
679    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
680    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
681    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
682                                    RICindication_IEs__value_PR_RICindicationHeader;
683    BuildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
684                 &ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader);
685
686    /* TO BE CHANGED: RIC INDICATION DATA */
687    /* Foe now filling a dummy octect data, need to tested with PRBs*/ 
688    idx++;
689    ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
690    ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
691    ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
692                                   RICindication_IEs__value_PR_RICindicationMessage;
693    BuildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
694                 &ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage);
695   
696    /* Prints the Msg formed */
697    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
698
699    cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
700    encBufSize = 0;
701    encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
702                encBuf);
703    if(encRetVal.encoded == ENCODE_FAIL)
704    {
705            DU_LOG("\nE2AP : Could not encode RIC Indication Message (at %s)\n",\
706                            encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
707            RETVALUE(RFAILED);
708    }
709    else
710    {
711            DU_LOG("\nE2AP : Created APER encoded buffer for RIC Indication Message \n");
712            for(int i=0; i< encBufSize; i++)
713            {
714                    printf("%x",encBuf[i]);
715            } 
716    }
717
718    if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL) != ROK)
719    {
720       DU_LOG("\nE2AP : Sending RIC Indication Message");      
721       RETVALUE(RFAILED);
722    }
723    RETVALUE(ROK);
724 }
725
726 /*******************************************************************
727 *
728 * @brief Sends E2 msg over SCTP
729 *
730 * @details
731 *
732 *    Function : SendE2APMsg
733 *
734 *    Functionality: Sends E2 msg over SCTP
735 *
736 * @params[in] Region region
737 *             Pool pool
738 * @return ROK     - success
739 *         RFAILED - failure
740 *
741 * ****************************************************************/
742
743 S16 SendE2APMsg(Region region, Pool pool)
744 {
745    Buffer *mBuf;
746
747    if(SGetMsg(region, pool, &mBuf) == ROK)
748    {
749       if(SAddPstMsgMult((Data *)encBuf, encBufSize, mBuf) == ROK)
750       {
751          SPrntMsg(mBuf, 0,0);
752  
753          if(sctpSend(mBuf, duCfgParam.sctpParams.itfType.e2Itf) != ROK)
754          {
755             DU_LOG("\nE2AP : SCTP Send for E2  failed");
756             SPutMsg(mBuf);
757             RETVALUE(RFAILED);
758          }
759       }
760       else
761       {
762          DU_LOG("\nF1AP : SAddPstMsgMult failed");
763          SPutMsg(mBuf);
764          RETVALUE(RFAILED);
765       }
766       SPutMsg(mBuf);
767    }
768    else
769    {
770       DU_LOG("\nF1AP : Failed to allocate memory");
771       RETVALUE(RFAILED);
772    }
773  
774    RETVALUE(ROK);
775 } /* SendE2APMsg */
776
777 /*******************************************************************
778 *
779 * @brief Handles received E2AP message and sends back response  
780 *
781 * @details
782 *
783 *    Function : E2APMsgHdlr
784 *
785 *    Functionality:
786 *         - Decodes received E2AP control message
787 *         - Prepares response message, encodes and sends to SCTP
788 *
789 * @params[in] 
790 * @return ROK     - success
791 *         RFAILED - failure
792 *
793 * ****************************************************************/
794 void E2APMsgHdlr(Buffer *mBuf)
795 {
796    int i;
797    char *recvBuf;
798    MsgLen copyCnt;
799    MsgLen recvBufLen;
800    E2AP_PDU_t *e2apMsg;
801    asn_dec_rval_t rval; /* Decoder return value */
802    E2AP_PDU_t e2apasnmsg ;
803  
804    DU_LOG("\nE2AP : Received E2AP message buffer");
805    SPrntMsg(mBuf, 0,0);
806  
807    /* Copy mBuf into char array to decode it */
808    SFndLenMsg(mBuf, &recvBufLen);
809    if(SGetSBuf(DFLT_REGION, DFLT_POOL, (Data **)&recvBuf, (Size)recvBufLen) != ROK)
810    {
811       DU_LOG("\nE2AP : Memory allocation failed");
812       return;
813    }
814    if(SCpyMsgFix(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
815    {
816       DU_LOG("\nE2AP : Failed while copying %d", copyCnt);
817       return;
818    }
819
820    printf("\nE2AP : Received flat buffer to be decoded : ");
821    for(i=0; i< recvBufLen; i++)
822    {
823         printf("%x",recvBuf[i]);
824    }
825
826    /* Decoding flat buffer into E2AP messsage */
827    e2apMsg = &e2apasnmsg;
828    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
829  
830    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
831    SPutSBuf(DFLT_REGION, DFLT_POOL, (Data *)recvBuf, (Size)recvBufLen);
832    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
833    {
834       DU_LOG("\nE2AP : ASN decode failed");
835       return;
836    }
837    printf("\n");
838    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
839
840    switch(e2apMsg->present)
841    {
842       case E2AP_PDU_PR_successfulOutcome:
843       {
844          switch(e2apMsg->choice.successfulOutcome->value.present)
845          {
846             case SuccessfulOutcomeE2__value_PR_E2setupResponse:
847             {
848                if(!duCb.e2Status)
849                {
850                  DU_LOG("\nE2AP : Store E2 setup response Params");
851                  procE2SetupRsp(e2apMsg);
852                }
853                break;
854             }
855             default:
856             {
857                DU_LOG("\nE2AP : Invalid type of intiating message [%d]", e2apMsg->choice.initiatingMessage->value.present);
858                return;
859             }
860          }/* End of switch(successfulOutcome) */
861          break;
862       }
863       case E2AP_PDU_PR_initiatingMessage:
864       {
865          switch(e2apMsg->choice.initiatingMessage->value.present)
866          {
867             case InitiatingMessageE2__value_PR_RICsubscriptionRequest: 
868             {
869                DU_LOG("\nE2AP : Calling RIC Subscription Response");
870                if(procRicSubsReq(e2apMsg) == ROK)
871                {
872                   BuildAndSendRicIndication();
873                }
874                break;
875             }
876             default:
877             {
878                DU_LOG("\nE2AP : Invalid type of successfulOutcome message [%d]", e2apMsg->choice.successfulOutcome->value.present);
879                return;
880             }
881          }/* End of switch(initiatingMessage) */
882          break;
883       }
884       default:
885       {
886          DU_LOG("\nE2AP : Invalid type of e2apMsg->present [%d]",e2apMsg->present);
887          return;
888       }
889
890    }/* End of switch(e2apMsg->present) */
891  
892 } /* End of E2APMsgHdlr */