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