<[Epic-ID: ODUHIGH-406][Task-ID: ODUHIGH-421]Paging Message: CU_STUB Trigger and...
[o-du/l2.git] / src / ric_stub / ric_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
19 /* This file contains E2AP message handler functions */
20 #include "common_def.h"
21 #include "OCTET_STRING.h"
22 #include "BIT_STRING.h"
23 #include "odu_common_codec.h"
24 #include "ric_stub_sctp.h"
25 #include "ric_stub.h"
26 #include "ric_e2ap_msg_hdl.h"
27 #include "GlobalE2node-gNB-ID.h"
28 #include "ProtocolIE-FieldE2.h"
29 #include "InitiatingMessageE2.h"
30 #include "SuccessfulOutcomeE2.h"
31 #include "E2AP-PDU.h"
32 #include "du_log.h"
33 #include "E2nodeComponentInterfaceF1.h"
34
35
36 /*******************************************************************
37 *
38 * @brief Sends E2 msg over SCTP
39 *
40 * @details
41 *
42 *    Function : SendE2APMsg
43 *
44 *    Functionality: Sends E2 msg over SCTP
45 *
46 * @params[in] Region region
47 *             Pool pool
48 * @return ROK     - success
49 *         RFAILED - failure
50 *
51 * ****************************************************************/
52
53 uint8_t SendE2APMsg(Region region, Pool pool)
54 {
55    Buffer *mBuf;
56
57    if(ODU_GET_MSG_BUF(region, pool, &mBuf) == ROK)
58    {
59       if(ODU_ADD_POST_MSG_MULT((Data *)encBuf, encBufSize, mBuf) == ROK)
60       {
61          ODU_PRINT_MSG(mBuf, 0,0);
62  
63          if(sctpSend(mBuf) != ROK)
64          {
65             DU_LOG("\nERROR  -->  E2AP : SCTP Send for E2  failed");
66             ODU_PUT_MSG_BUF(mBuf);
67             return RFAILED;
68          }
69       }
70       else
71       {
72          DU_LOG("\nERROR  -->  E2AP : ODU_ADD_POST_MSG_MULT failed");
73          ODU_PUT_MSG_BUF(mBuf);
74          return RFAILED;
75       }
76       ODU_PUT_MSG_BUF(mBuf);
77    }
78    else
79    {
80       DU_LOG("\nERROR  -->  E2AP : Failed to allocate memory");
81       return RFAILED;
82    }
83  
84    return ROK;
85 } /* SendE2APMsg */
86
87 /*******************************************************************
88  *
89  * @brief Builds Global RIC Id Params
90  *
91  * @details
92  *
93  *    Function : BuildGlobalRicId
94  *
95  *    Functionality: Building the Plmn and ric id
96  *
97  * @params[in] GlobalRIC_ID_t *ricId
98  * @return ROK     - success
99  *         RFAILED - failure
100  *
101  * ****************************************************************/
102
103 uint8_t BuildGlobalRicId(GlobalRIC_ID_t *ricId)
104 {
105    uint8_t unused = 4;
106    uint8_t byteSize = 3;
107    uint8_t ricVal= 1;
108    if(ricId != NULLP)
109    {
110       ricId->pLMN_Identity.size = byteSize * sizeof(uint8_t);
111       RIC_ALLOC(ricId->pLMN_Identity.buf,  ricId->pLMN_Identity.size);
112       buildPlmnId(ricCfgParams.plmn , ricId->pLMN_Identity.buf);
113       /* fill ric Id */
114       ricId->ric_ID.size = byteSize * sizeof(uint8_t);
115       RIC_ALLOC(ricId->ric_ID.buf, ricId->ric_ID.size);
116       fillBitString(&ricId->ric_ID, unused, byteSize, ricVal);
117    }
118    return ROK;   
119 }
120
121 /*******************************************************************
122  *
123  * @brief deallocate the memory allocated in E2SetupResponse
124  *
125  * @details
126  *
127  *    Function : FreeE2SetupRsp 
128  *
129  *    Functionality: deallocate the memory allocated in E2SetupResponse 
130  *
131  * @params[in] E2AP_PDU_t *e2apMsg
132  *
133  * @return void
134  * ****************************************************************/
135 void FreeE2SetupRsp(E2AP_PDU_t *e2apMsg)
136 {
137    uint8_t arrIdx = 0;
138    E2setupResponse_t  *e2SetupRsp;
139
140    if(e2apMsg)
141    {
142       if(e2apMsg->choice.successfulOutcome)
143       {
144          e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
145          if(e2SetupRsp->protocolIEs.list.array)
146          {
147             for(arrIdx=0; arrIdx<e2SetupRsp->protocolIEs.list.count; arrIdx++)
148             {
149                RIC_FREE(e2SetupRsp->protocolIEs.list.array[arrIdx], sizeof(E2setupResponseIEs_t)); 
150             }
151             RIC_FREE(e2SetupRsp->protocolIEs.list.array, e2SetupRsp->protocolIEs.list.size);
152          }
153          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
154       }
155       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
156    }
157 }
158
159 /*******************************************************************
160  *
161  * @brief Build E2node Component config addition ack list
162  *
163  * @details
164  *
165  *    Function :  BuildE2nodeComponentConfigAdditionAck
166  *
167  *    Functionality: deallocate the memory allocated in E2SetupResponse 
168  *
169  * @params[in] E2nodeComponentConfigAdditionAck_List_t
170  * *e2NodeConfigAdditionAckList
171  *
172  * @return ROK - success
173  *         RFAILED - failure
174  * ****************************************************************/
175 uint8_t BuildE2nodeComponentConfigAdditionAck(E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList, uint8_t duId)
176 {
177    uint8_t arrIdx = 0;
178    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem;
179    
180    e2NodeConfigAdditionAckList->list.count = 1;
181    e2NodeConfigAdditionAckList->list.size = e2NodeConfigAdditionAckList->list.count * sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t*);
182    RIC_ALLOC(e2NodeConfigAdditionAckList->list.array, e2NodeConfigAdditionAckList->list.size);
183    if(e2NodeConfigAdditionAckList->list.array == NULLP)
184    {
185       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
186       return RFAILED;
187    }
188
189    for(arrIdx = 0; arrIdx< e2NodeConfigAdditionAckList->list.count; arrIdx++)
190    {
191       RIC_ALLOC(e2NodeConfigAdditionAckList->list.array[arrIdx], sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
192       if(e2NodeConfigAdditionAckList->list.array[arrIdx] == NULLP)
193       {
194          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
195          return RFAILED;
196       }
197    }
198    e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[0];
199    e2NodeAddAckItem->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck_Item;
200    e2NodeAddAckItem->criticality = CriticalityE2_reject;
201    e2NodeAddAckItem->value.present = E2nodeComponentConfigAdditionAck_ItemIEs__value_PR_E2nodeComponentConfigAdditionAck_Item;
202    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentInterfaceType = E2nodeComponentInterfaceType_f1;
203
204    /* >E2 Node Component ID */
205    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1;
206    RIC_ALLOC(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\
207          sizeof(E2nodeComponentInterfaceF1_t));
208    if(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1 == NULLP)
209    {
210       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
211       return RFAILED;
212    }
213    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t);
214    RIC_ALLOC(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
215          e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
216
217    if(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP)
218    {
219       DU_LOG("\nERROR  -->list.  E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
220       return RFAILED;
221    }
222    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]  = duId;
223    
224    /* >E2 Node Component Configuration Acknowledge*/
225    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentConfigurationAck.updateOutcome = \
226    E2nodeComponentConfigurationAck__updateOutcome_success;
227    
228    return ROK;  
229 }
230 /*******************************************************************
231  *
232  * @brief Builds and sends the E2SetupResponse
233  *
234  * @details
235  *
236  *    Function : BuildAndSendE2SetupRsp
237  *
238  *    Functionality: Constructs the F1SetupResponse message and sends
239  *                   it back to the DU through SCTP.
240  *
241  * @params[in] void **buf,Buffer to which encoded pattern is written into
242  * @params[in] int *size,size of buffer
243  *
244  * @return ROK     - success
245  *         RFAILED - failure
246  *
247  * ****************************************************************/
248 uint8_t BuildAndSendE2SetupRsp(uint8_t duId)
249 {
250    E2AP_PDU_t         *e2apMsg = NULL;
251    E2setupResponse_t  *e2SetupRsp;
252    asn_enc_rval_t     encRetVal; 
253    uint8_t            idx;
254    uint8_t            elementCnt;
255    bool  memAllocFailed = false;
256  
257    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup Response\n");
258    while(true)
259    {
260       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); 
261       if(e2apMsg == NULLP)
262       {
263          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
264          break;
265       }
266       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
267       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
268       if(e2apMsg->choice.successfulOutcome == NULLP)
269       {
270          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
271          break;  
272       }
273
274       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
275       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
276       e2apMsg->choice.successfulOutcome->value.present = \
277                                                          SuccessfulOutcomeE2__value_PR_E2setupResponse;
278       e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
279
280       elementCnt = 3;
281       e2SetupRsp->protocolIEs.list.count = elementCnt;
282       e2SetupRsp->protocolIEs.list.size  = elementCnt * sizeof(E2setupResponseIEs_t);
283
284       RIC_ALLOC(e2SetupRsp->protocolIEs.list.array, e2SetupRsp->protocolIEs.list.size);
285       if(e2SetupRsp->protocolIEs.list.array == NULLP)
286       {
287          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");
288          break;  
289       }
290
291       for(idx=0; idx<elementCnt; idx++)
292       {
293          RIC_ALLOC(e2SetupRsp->protocolIEs.list.array[idx], sizeof(E2setupResponseIEs_t)); 
294          if(e2SetupRsp->protocolIEs.list.array[idx] == NULLP)
295          { 
296             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");
297             memAllocFailed = true;
298             break;
299          }    
300       }
301       
302       if(memAllocFailed == true)
303       {
304           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");    
305           break;
306       }
307       /* Trans Id */
308       idx = 0;
309       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_TransactionID;
310       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
311       e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_TransactionID; 
312       e2SetupRsp->protocolIEs.list.array[idx]->value.choice.TransactionID  = TRANS_ID;
313
314       /* Global RIC ID */
315       idx++;
316       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_GlobalRIC_ID;
317       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
318       e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
319                                                                E2setupResponseIEs__value_PR_GlobalRIC_ID;
320
321       if(BuildGlobalRicId(&(e2SetupRsp->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID))!=ROK)
322       {
323          DU_LOG("\nERROR  -->  E2AP : Failed to build Global Ric Id");
324          break;
325       }
326       
327       /* E2 Node Component Configuration Addition Acknowledge List*/
328       idx++;
329       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck;
330       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
331       e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
332       E2setupResponseIEs__value_PR_E2nodeComponentConfigAdditionAck_List;
333       if(BuildE2nodeComponentConfigAdditionAck(&e2SetupRsp->protocolIEs.list.array[idx]->value.choice.E2nodeComponentConfigAdditionAck_List, duId)!=ROK)
334       {
335          DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config addition ack list");
336          break;
337       }
338
339       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
340       memset(encBuf, 0, ENC_BUF_MAX_LEN);
341       encBufSize = 0;
342       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
343
344       /* Check encode results */
345       if(encRetVal.encoded == ENCODE_FAIL)
346       {
347          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupResponse structure (at %s)\n",\
348                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
349          break;   
350       } 
351       else 
352       {
353          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SetupResponse\n");
354          for(int i=0; i< encBufSize; i++)
355          {
356             DU_LOG("%x",encBuf[i]);
357          } 
358       }
359
360       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL) != ROK)
361       {
362          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Response failed");      
363          break;   
364       }
365       break;
366    }
367
368    FreeE2SetupRsp(e2apMsg);
369    return ROK;
370 }
371
372 /*******************************************************************
373  *
374  * @brief Builds Ric Request Id
375  *
376  * @details
377  *
378  *    Function : BuildRicRequestId
379  *
380  *    Functionality: Building the Ric Request Id
381  *
382  * @params[in] RICrequestID_t *ricReqId
383  * @return ROK     - success
384  *         RFAILED - failure
385  *
386  * ****************************************************************/
387
388 uint8_t BuildRicRequestId(RICrequestID_t *ricReqId)
389 {
390
391    if(ricReqId != NULLP)
392    {
393       ricReqId->ricRequestorID = 1;
394       ricReqId->ricInstanceID  = 1;
395    }
396    return ROK;
397 }
398
399 /*******************************************************************
400  *
401  * @brief Fills Ric Action To be Setup Item
402  *
403  * @details
404  *
405  *    Function : fillSetupItems
406  *
407  *    Functionality: Filling ricAction Id, RicActionType
408  *
409  * @params[in] RICaction_ToBeSetup_Item_t *setupItems
410  * @return pointer of type RICaction_ToBeSetup_Item_t
411  *
412  * ****************************************************************/
413
414 RICaction_ToBeSetup_Item_t* fillSetupItems(RICaction_ToBeSetup_Item_t *setupItems)
415 {
416    if(setupItems != NULLP)
417    {
418       setupItems->ricActionID = 0;
419       setupItems->ricActionType = RICactionType_report;
420    }
421
422    return (setupItems);
423 }
424
425 /*******************************************************************
426  *
427  * @brief Fills RIC Subscription Details Item List
428  *
429  * @details
430  *
431  *    Function : fillSubsDetails
432  *
433  *    Functionality: Fill the RIC Subscription Details Items List
434  *
435  * @params[in] RICaction_ToBeSetup_ItemIEs_t *items
436  * @return ROK     - success
437  *         RFAILED - failure
438  *
439  * ****************************************************************/
440
441 uint8_t fillSubsDetails(RICaction_ToBeSetup_ItemIEs_t *items)
442 {
443    if(items != NULLP)
444    {
445       items->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item;
446       items->criticality   =  CriticalityE2_ignore;
447       items->value.present =  RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
448       fillSetupItems(&(items->value.choice.RICaction_ToBeSetup_Item));
449    }
450    return ROK;
451 }
452
453 /*******************************************************************
454  *
455  * @brief builds RIC Subscription Details
456  *
457  * @details
458  *
459  *    Function : BuildsRicSubsDetails
460  *
461  *    Functionality: Builds the RIC Subscription Details
462  *
463  * @params[in] RICsubscriptionDetails_t *subsDetails
464  * @return ROK     - success
465  *         RFAILED - failure
466  *
467  * ****************************************************************/
468
469 uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails)
470 {
471
472    uint8_t elementCnt;
473
474    if(subsDetails != NULLP)
475    {
476       /* Octet string to be build here */
477       /* Sending PLMN as Octect string */
478       uint8_t byteSize = 3;
479       subsDetails->ricEventTriggerDefinition.size = byteSize * sizeof(uint8_t);
480       RIC_ALLOC(subsDetails->ricEventTriggerDefinition.buf,  subsDetails->ricEventTriggerDefinition.size);
481       buildPlmnId(ricCfgParams.plmn, subsDetails->ricEventTriggerDefinition.buf);
482       elementCnt = 1;
483       subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt;
484       subsDetails->ricAction_ToBeSetup_List.list.size = \
485                       elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t);
486       RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, \
487                 subsDetails->ricAction_ToBeSetup_List.list.size);
488       if(subsDetails->ricAction_ToBeSetup_List.list.array  == NULLP)
489       {
490          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICactionToBeSetup Items failed");
491          return RFAILED;
492       } 
493       RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[0],\
494                    sizeof(RICaction_ToBeSetup_ItemIEs_t));
495       fillSubsDetails(subsDetails->ricAction_ToBeSetup_List.list.array[0]);
496    }
497    return ROK;
498 }
499
500 /*******************************************************************
501  *
502  * @brief Builds and Send the RicSubscriptionReq
503  *
504  * @details
505  *
506  *    Function : BuildAndSendRicSubscriptionReq
507  *
508  * Functionality:Fills the RicSubscriptionReq
509  *
510  * @return ROK     - success
511  *         RFAILED - failure
512  *
513  ******************************************************************/
514
515 uint8_t BuildAndSendRicSubscriptionReq()
516 {
517
518    E2AP_PDU_t                 *e2apRicMsg = NULL;
519    RICsubscriptionRequest_t   *ricSubscriptionReq;
520    uint8_t         elementCnt;
521    uint8_t         idx;
522    uint8_t         ieId;
523    uint8_t         ret; 
524    asn_enc_rval_t  encRetVal;        /* Encoder return value */
525    ricCfgParams.ricSubsStatus = TRUE;
526
527    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Request\n");
528
529    RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
530    if(e2apRicMsg == NULLP)
531    {
532       DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
533       return RFAILED;
534    }
535
536    e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
537    RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
538    if(e2apRicMsg->choice.initiatingMessage == NULLP)
539    {
540       DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
541       RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
542       return RFAILED;
543    }
544    e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
545    e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
546    e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
547    
548    RIC_ALLOC(ricSubscriptionReq, sizeof(RICsubscriptionRequest_t));
549    ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
550    
551    elementCnt = 3;
552    ricSubscriptionReq->protocolIEs.list.count = elementCnt;
553    ricSubscriptionReq->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
554
555    /* Initialize the subscription members */
556    RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, \
557               ricSubscriptionReq->protocolIEs.list.size);
558    if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
559    {
560       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICSubscriptionRequestIEs failed");
561       RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
562       RIC_FREE(e2apRicMsg, (Size)sizeof(E2AP_PDU_t));
563       return RFAILED;
564    }
565    
566    for(idx=0; idx<elementCnt; idx++)
567    {
568       RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx],\
569             sizeof(RICsubscriptionRequest_IEs_t));
570       if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
571       {
572          for(ieId=0; ieId<idx; ieId++)
573          {
574             RIC_FREE(ricSubscriptionReq->protocolIEs.list.array[ieId],\
575                   sizeof(RICsubscriptionRequest_IEs_t));
576          }
577          RIC_FREE(ricSubscriptionReq->protocolIEs.list.array,\
578                   ricSubscriptionReq->protocolIEs.list.size);
579          RIC_FREE(e2apRicMsg->choice.initiatingMessage, \
580                sizeof(InitiatingMessageE2_t));
581          RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
582          return RFAILED;
583       }
584    }
585
586    /* Filling RIC Request Id */
587    idx = 0;
588    ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
589    ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
590    ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
591                                     RICsubscriptionRequest_IEs__value_PR_RICrequestID;
592  
593    BuildRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID);
594
595
596    /* Filling RAN Function Id */
597    idx++;
598    ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
599    ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
600    ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
601                                     RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
602    ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1;
603
604
605    /* Filling RIC Subscription Details */
606    idx++;
607    ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
608    ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
609    ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
610                                     RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
611
612    BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails));
613
614
615    /* Prints the Msg formed */
616    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
617
618    memset(encBuf, 0, ENC_BUF_MAX_LEN);
619    encBufSize = 0;
620    encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\
621                encBuf);
622    if(encRetVal.encoded == ENCODE_FAIL)
623    {
624       DU_LOG("\nERROR  -->  E2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
625       encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
626       return RFAILED;
627    }
628    else
629    {
630       DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
631       for(int i=0; i< encBufSize; i++)
632       {
633           DU_LOG("%x",encBuf[i]);
634       } 
635    }
636
637
638    /* Sending msg */
639    if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL) != ROK)
640    {
641       DU_LOG("\nERROR  -->  E2AP : Sending RIC subscription Request failed");
642       return RFAILED;
643    }
644
645    return ROK;
646 }
647
648 /*******************************************************************
649  *
650  * @brief process the e2setup request 
651  *
652  * @details
653  *
654  *    Function : ProcE2SetupReq
655  *
656  * Functionality: process the e2setup request
657  *
658  * @return ROK     - success
659  *         RFAILED - failure
660  *
661  ******************************************************************/
662
663 uint8_t ProcE2SetupReq(E2setupRequest_t  *e2SetupReq)
664 {
665    uint8_t arrIdx = 0, e2NodeAddListIdx =0;;
666    E2nodeComponentConfigAddition_List_t *e2NodeAddList;
667    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
668
669    if(e2SetupReq)
670    {
671         if(e2SetupReq->protocolIEs.list.array)      
672         {
673             for(arrIdx=0; arrIdx<e2SetupReq->protocolIEs.list.count; arrIdx++)
674             {
675                if(e2SetupReq->protocolIEs.list.array[arrIdx])
676                {
677                   switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
678                   {
679                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
680                      {
681                         e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;      
682                         if(e2NodeAddList->list.array)
683                         {
684                            for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
685                            {
686                               if(e2NodeAddList->list.array[e2NodeAddListIdx])
687                               {
688                                  e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
689                                  if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1)
690                                  {
691                                     if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->\
692                                     gNB_DU_ID.buf)
693                                     {
694                                        if(BuildAndSendE2SetupRsp(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
695                                        e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]) !=ROK)
696                                        {
697                                            DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 setup response");
698                                            return RFAILED;
699                                        }
700                                     }
701                                  }
702                               }
703                            }
704                         }
705                         break;
706                      }
707                      default:
708                         break;
709                   }
710                }
711             }
712         }
713    }
714    return ROK;   
715 }
716
717 /*******************************************************************
718  *
719  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
720  *
721  * @details
722  *
723  *    Function : FreeE2NodeConfigUpdate 
724  *
725  *    Functionality:
726  *       - freeing the memory allocated for E2nodeConfigurationUpdate
727  *
728  * @params[in] E2AP_PDU_t *e2apMsg 
729  * @return ROK     - success
730  *         RFAILED - failure
731  *
732  * ****************************************************************/
733 void FreeE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg)
734 {
735    uint8_t arrIdx =0;
736    E2nodeConfigurationUpdate_t *e2NodeConfigUpdateAck;
737
738    if(e2apMsg != NULLP)
739    {
740       if(e2apMsg->choice.successfulOutcome != NULLP)
741       {
742          e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
743          if(e2NodeConfigUpdateAck->protocolIEs.list.array != NULLP)
744          {
745             for(arrIdx = 0; arrIdx < e2NodeConfigUpdateAck->protocolIEs.list.count; arrIdx++)
746             {
747                RIC_FREE(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_t));
748             }
749             RIC_FREE(e2NodeConfigUpdateAck->protocolIEs.list.array, e2NodeConfigUpdateAck->protocolIEs.list.size);
750          }
751          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
752       }
753       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
754    }
755 }
756
757 /*******************************************************************
758  *
759  * @brief Buld and send the E2 node config update msg 
760  *
761  * @details
762  *
763  *    Function : BuildAndSendE2NodeConfigUpdate
764  *
765  *    Functionality:
766  *         - Buld and send the E2 node config update msg
767  * @return ROK     - success
768  *         RFAILED - failure
769  *
770  * ****************************************************************/
771
772 uint8_t BuildAndSendE2NodeConfigUpdateAck()
773 {
774    uint8_t arrIdx = 0,elementCnt = 1;
775    uint8_t ret = ROK;
776    E2AP_PDU_t        *e2apMsg = NULLP;
777    E2nodeConfigurationUpdateAcknowledge_t *e2NodeConfigUpdateAck = NULLP;
778    asn_enc_rval_t     encRetVal;       /* Encoder return value */
779
780    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update Ack Message\n");
781    do
782    {
783       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
784       if(e2apMsg == NULLP)
785       {
786          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
787          break;
788       }
789       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
790       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
791       if(e2apMsg->choice.successfulOutcome == NULLP)
792       {
793          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
794          RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
795          return RFAILED;
796       }
797       
798       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
799       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
800       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge;
801       e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
802
803       e2NodeConfigUpdateAck->protocolIEs.list.count = elementCnt;
804       e2NodeConfigUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t*);
805       /* Initialize the Ric Indication members */
806       RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array, \
807             e2NodeConfigUpdateAck->protocolIEs.list.size);
808       if(e2NodeConfigUpdateAck->protocolIEs.list.array == NULLP)
809       {
810          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdateAck failed");
811          break;
812       }
813       
814       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
815       {
816          RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t));
817          if(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
818          {
819             
820             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdateAck failed");
821             break;
822          }
823       }
824
825       arrIdx = 0;
826       /* TransactionID */
827       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
828       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
829       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_TransactionID;
830       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = TRANS_ID;
831
832
833       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
834
835       memset(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("\nERROR  -->  E2AP : Could not encode E2 Node config update ack structure (at %s)\n",\
842                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
843          return RFAILED;
844       }
845       else
846       {
847          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Node config update ack \n");
848          for(int i=0; i< encBufSize; i++)
849          {
850             DU_LOG("%x",encBuf[i]);
851          } 
852       }
853
854
855       /* Sending msg */
856       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL) != ROK)
857       {
858          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Node config update ack ");
859          return RFAILED;
860       }
861
862       break;
863    }while(true);
864    
865    FreeE2NodeConfigUpdateAck(e2apMsg);
866    return ret;
867 }
868
869 /*******************************************************************
870 *
871 * @brief Handles received E2AP message and sends back response  
872 *
873 * @details
874 *
875 *    Function : E2APMsgHdlr
876 *
877 *    Functionality:
878 *         - Decodes received E2AP control message
879 *         - Prepares response message, encodes and sends to SCTP
880 *
881 * @params[in] 
882 * @return ROK     - success
883 *         RFAILED - failure
884 *
885 * ****************************************************************/
886 void E2APMsgHdlr(Buffer *mBuf)
887 {
888    int             i;
889    char            *recvBuf;
890    MsgLen          copyCnt;
891    MsgLen          recvBufLen;
892    E2AP_PDU_t      *e2apMsg;
893    asn_dec_rval_t  rval; /* Decoder return value */
894    E2AP_PDU_t      e2apasnmsg ;
895  
896    DU_LOG("\nINFO  -->  E2AP : Received E2AP message buffer");
897    ODU_PRINT_MSG(mBuf, 0,0);
898  
899    /* Copy mBuf into char array to decode it */
900    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
901    RIC_ALLOC(recvBuf, (Size)recvBufLen);
902
903    if(recvBuf == NULLP)
904    {
905       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
906       return;
907    }
908    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
909    {
910       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
911       return;
912    }
913
914    DU_LOG("\nDEBUG  -->  E2AP : Received flat buffer to be decoded : ");
915    for(i=0; i< recvBufLen; i++)
916    {
917         DU_LOG("%x",recvBuf[i]);
918    }
919
920    /* Decoding flat buffer into E2AP messsage */
921    e2apMsg = &e2apasnmsg;
922    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
923
924    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
925    RIC_FREE(recvBuf, (Size)recvBufLen);
926
927    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
928    {
929       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
930       return;
931    }
932    DU_LOG("\n");
933    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
934
935    switch(e2apMsg->present)
936    {
937       case E2AP_PDU_PR_initiatingMessage:
938       {
939          switch(e2apMsg->choice.initiatingMessage->value.present)
940          {
941             case InitiatingMessageE2__value_PR_E2setupRequest:
942             {
943                DU_LOG("\nINFO  -->  E2AP : E2 setup request received");
944                ProcE2SetupReq(&e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest);
945                     break;
946             }
947             case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate:
948             {
949                DU_LOG("\nINFO  -->  E2AP : E2 node config update received");
950                BuildAndSendE2NodeConfigUpdateAck();
951                break;
952             }
953             case InitiatingMessageE2__value_PR_RICindication:
954             {
955                DU_LOG("\nINFO  -->  E2AP : RIC Indication Acknowledged");
956                break;
957             }
958             default:
959             {
960                DU_LOG("\nERROR  -->  E2AP : Invalid type of intiating message [%d]",e2apMsg->choice.initiatingMessage->value.present);
961                return;
962             }
963          }/* End of switch(initiatingMessage) */
964          break;
965       }
966       case E2AP_PDU_PR_successfulOutcome: 
967       {
968          switch(e2apMsg->choice.successfulOutcome->value.present)
969          {
970             case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:  
971             {
972                DU_LOG("\nINFO  -->  E2AP : RICsubscriptionResponse Msg Acknowledged");
973                break;
974             }
975             default:
976             {
977                DU_LOG("\nERROR  -->  E2AP : Invalid type of successfulOutcome message [%d]",e2apMsg->choice.successfulOutcome->value.present);
978                return;
979             }
980             break;
981          }
982          break; 
983       }
984       default:
985       {
986          DU_LOG("\nERROR  -->  E2AP : Invalid type message type ");
987          return;
988       }
989  
990     }/* End of switch(e2apMsg->present) */
991
992     if(!ricCfgParams.ricSubsStatus)
993       BuildAndSendRicSubscriptionReq(); 
994        
995 } /* End of E2APMsgHdlr */
996
997
998 /**********************************************************************
999   End of file
1000  **********************************************************************/