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