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