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