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