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