[Issue-ID : ODUHIGH-486] SCTP Port fix at F1 and E2 interface
[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, uint32_t duId)
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(duId, 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(ricCb.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(uint32_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, duId) != ROK)
361       {
362          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Response failed");      
363          break;   
364       }
365       break;
366    }
367
368    FreeE2SetupRsp(e2apMsg);
369    BuildAndSendRicSubscriptionReq(duId);
370    return ROK;
371 }
372
373 /*******************************************************************
374  *
375  * @brief Builds Ric Request Id
376  *
377  * @details
378  *
379  *    Function : BuildRicRequestId
380  *
381  *    Functionality: Building the Ric Request Id
382  *
383  * @params[in] RICrequestID_t *ricReqId
384  * @return ROK     - success
385  *         RFAILED - failure
386  *
387  * ****************************************************************/
388
389 uint8_t BuildRicRequestId(RICrequestID_t *ricReqId)
390 {
391
392    if(ricReqId != NULLP)
393    {
394       ricReqId->ricRequestorID = 1;
395       ricReqId->ricInstanceID  = 1;
396    }
397    return ROK;
398 }
399
400 /*******************************************************************
401  *
402  * @brief Fills Ric Action To be Setup Item
403  *
404  * @details
405  *
406  *    Function : fillSetupItems
407  *
408  *    Functionality: Filling ricAction Id, RicActionType
409  *
410  * @params[in] RICaction_ToBeSetup_Item_t *setupItems
411  * @return pointer of type RICaction_ToBeSetup_Item_t
412  *
413  * ****************************************************************/
414
415 RICaction_ToBeSetup_Item_t* fillSetupItems(RICaction_ToBeSetup_Item_t *setupItems)
416 {
417    if(setupItems != NULLP)
418    {
419       setupItems->ricActionID = 0;
420       setupItems->ricActionType = RICactionType_report;
421    }
422
423    return (setupItems);
424 }
425
426 /*******************************************************************
427  *
428  * @brief Fills RIC Subscription Details Item List
429  *
430  * @details
431  *
432  *    Function : fillSubsDetails
433  *
434  *    Functionality: Fill the RIC Subscription Details Items List
435  *
436  * @params[in] RICaction_ToBeSetup_ItemIEs_t *items
437  * @return ROK     - success
438  *         RFAILED - failure
439  *
440  * ****************************************************************/
441
442 uint8_t fillSubsDetails(RICaction_ToBeSetup_ItemIEs_t *items)
443 {
444    if(items != NULLP)
445    {
446       items->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item;
447       items->criticality   =  CriticalityE2_ignore;
448       items->value.present =  RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
449       fillSetupItems(&(items->value.choice.RICaction_ToBeSetup_Item));
450    }
451    return ROK;
452 }
453
454 /*******************************************************************
455  *
456  * @brief builds RIC Subscription Details
457  *
458  * @details
459  *
460  *    Function : BuildsRicSubsDetails
461  *
462  *    Functionality: Builds the RIC Subscription Details
463  *
464  * @params[in] RICsubscriptionDetails_t *subsDetails
465  * @return ROK     - success
466  *         RFAILED - failure
467  *
468  * ****************************************************************/
469
470 uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails)
471 {
472
473    uint8_t elementCnt;
474
475    if(subsDetails != NULLP)
476    {
477       /* Octet string to be build here */
478       /* Sending PLMN as Octect string */
479       uint8_t byteSize = 3;
480       subsDetails->ricEventTriggerDefinition.size = byteSize * sizeof(uint8_t);
481       RIC_ALLOC(subsDetails->ricEventTriggerDefinition.buf,  subsDetails->ricEventTriggerDefinition.size);
482       buildPlmnId(ricCb.ricCfgParams.plmn, subsDetails->ricEventTriggerDefinition.buf);
483       elementCnt = 1;
484       subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt;
485       subsDetails->ricAction_ToBeSetup_List.list.size = \
486                       elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t);
487       RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, \
488                 subsDetails->ricAction_ToBeSetup_List.list.size);
489       if(subsDetails->ricAction_ToBeSetup_List.list.array  == NULLP)
490       {
491          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICactionToBeSetup Items failed");
492          return RFAILED;
493       } 
494       RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[0],\
495                    sizeof(RICaction_ToBeSetup_ItemIEs_t));
496       fillSubsDetails(subsDetails->ricAction_ToBeSetup_List.list.array[0]);
497    }
498    return ROK;
499 }
500
501 /*******************************************************************
502  *
503  * @brief Builds and Send the RicSubscriptionReq
504  *
505  * @details
506  *
507  *    Function : BuildAndSendRicSubscriptionReq
508  *
509  * Functionality:Fills the RicSubscriptionReq
510  *
511  * @return ROK     - success
512  *         RFAILED - failure
513  *
514  ******************************************************************/
515
516 uint8_t BuildAndSendRicSubscriptionReq(uint32_t duId)
517 {
518
519    E2AP_PDU_t                 *e2apRicMsg = NULL;
520    RICsubscriptionRequest_t   *ricSubscriptionReq;
521    uint8_t         elementCnt;
522    uint8_t         idx;
523    uint8_t         ieId;
524    uint8_t         ret; 
525    asn_enc_rval_t  encRetVal;        /* Encoder return value */
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, duId) != 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 RicSubscriptionResponse
651  *
652  * @details
653  *
654  *    Function : ProcRicSubscriptionRsp
655  *
656  * Functionality: Processes RicSubscriptionRsp
657  *
658  * @return ROK     - void
659  *
660  ******************************************************************/
661
662 void ProcRicSubscriptionResponse(uint32_t duId)
663 {
664    uint8_t duIdx = 0;
665    DuDb *duDb;
666
667    DU_LOG("\nINFO  -->  E2AP : RICsubscriptionResponse Msg Acknowledged");
668
669    SEARCH_DU_DB(duIdx, duId, duDb);
670    if(duDb)
671       duDb->ricSubscribedToDu = true;
672 }
673
674 /*******************************************************************
675  *
676  * @brief process the e2setup request 
677  *
678  * @details
679  *
680  *    Function : ProcE2SetupReq
681  *
682  * Functionality: process the e2setup request
683  *
684  * @return ROK     - success
685  *         RFAILED - failure
686  *
687  ******************************************************************/
688
689 uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
690 {
691    uint8_t arrIdx = 0, e2NodeAddListIdx =0, duIdx = 0;
692    DuDb    *duDb = NULLP;
693    E2nodeComponentConfigAddition_List_t *e2NodeAddList;
694    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
695
696    if(e2SetupReq)
697    {
698         if(e2SetupReq->protocolIEs.list.array)      
699         {
700             for(arrIdx=0; arrIdx<e2SetupReq->protocolIEs.list.count; arrIdx++)
701             {
702                if(e2SetupReq->protocolIEs.list.array[arrIdx])
703                {
704                   switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
705                   {
706                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
707                      {
708                         e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;      
709                         if(e2NodeAddList->list.array)
710                         {
711                            for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
712                            {
713                               if(e2NodeAddList->list.array[e2NodeAddListIdx])
714                               {
715                                  e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
716                                  if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
717                                     e2nodeComponentInterfaceTypeF1)
718                                  {
719                                     if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
720                                        e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf)
721                                     {
722                                        *duId = e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.\
723                                                choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0];
724                                        SEARCH_DU_DB(duIdx, duId, duDb); 
725                                        if(duDb == NULLP)
726                                        {
727                                           duDb = &ricCb.duInfo[ricCb.numDu];
728                                           ricCb.numDu++;
729                                        }
730                                        memset(duDb, 0, sizeof(DuDb));
731                                        duDb->duId = *duId;
732
733                                        if(BuildAndSendE2SetupRsp(*duId) !=ROK)
734                                        {
735                                            DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 setup response");
736                                            return RFAILED;
737                                        }
738                                     }
739                                  }
740                               }
741                            }
742                         }
743                         break;
744                      }
745                      default:
746                         break;
747                   }
748                }
749             }
750         }
751    }
752    return ROK;   
753 }
754
755 /*******************************************************************
756  *
757  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
758  *
759  * @details
760  *
761  *    Function : FreeE2NodeConfigUpdate 
762  *
763  *    Functionality:
764  *       - freeing the memory allocated for E2nodeConfigurationUpdate
765  *
766  * @params[in] E2AP_PDU_t *e2apMsg 
767  * @return ROK     - success
768  *         RFAILED - failure
769  *
770  * ****************************************************************/
771 void FreeE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg)
772 {
773    uint8_t arrIdx =0;
774    E2nodeConfigurationUpdate_t *e2NodeConfigUpdateAck;
775
776    if(e2apMsg != NULLP)
777    {
778       if(e2apMsg->choice.successfulOutcome != NULLP)
779       {
780          e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
781          if(e2NodeConfigUpdateAck->protocolIEs.list.array != NULLP)
782          {
783             for(arrIdx = 0; arrIdx < e2NodeConfigUpdateAck->protocolIEs.list.count; arrIdx++)
784             {
785                RIC_FREE(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_t));
786             }
787             RIC_FREE(e2NodeConfigUpdateAck->protocolIEs.list.array, e2NodeConfigUpdateAck->protocolIEs.list.size);
788          }
789          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
790       }
791       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
792    }
793 }
794
795 /*******************************************************************
796  *
797  * @brief Buld and send the E2 node config update msg 
798  *
799  * @details
800  *
801  *    Function : BuildAndSendE2NodeConfigUpdate
802  *
803  *    Functionality:
804  *         - Buld and send the E2 node config update msg
805  * @return ROK     - success
806  *         RFAILED - failure
807  *
808  * ****************************************************************/
809
810 uint8_t BuildAndSendE2NodeConfigUpdateAck(uint32_t duId)
811 {
812    uint8_t arrIdx = 0,elementCnt = 1;
813    uint8_t ret = ROK;
814    E2AP_PDU_t        *e2apMsg = NULLP;
815    E2nodeConfigurationUpdateAcknowledge_t *e2NodeConfigUpdateAck = NULLP;
816    asn_enc_rval_t     encRetVal;       /* Encoder return value */
817
818    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update Ack Message\n");
819    do
820    {
821       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
822       if(e2apMsg == NULLP)
823       {
824          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
825          break;
826       }
827       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
828       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
829       if(e2apMsg->choice.successfulOutcome == NULLP)
830       {
831          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
832          RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
833          return RFAILED;
834       }
835       
836       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
837       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
838       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge;
839       e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
840
841       e2NodeConfigUpdateAck->protocolIEs.list.count = elementCnt;
842       e2NodeConfigUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t*);
843       /* Initialize the Ric Indication members */
844       RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array, \
845             e2NodeConfigUpdateAck->protocolIEs.list.size);
846       if(e2NodeConfigUpdateAck->protocolIEs.list.array == NULLP)
847       {
848          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdateAck failed");
849          break;
850       }
851       
852       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
853       {
854          RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t));
855          if(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
856          {
857             
858             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdateAck failed");
859             break;
860          }
861       }
862
863       arrIdx = 0;
864       /* TransactionID */
865       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
866       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
867       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_TransactionID;
868       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = TRANS_ID;
869
870
871       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
872
873       memset(encBuf, 0, ENC_BUF_MAX_LEN);
874       encBufSize = 0;
875       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
876             encBuf);
877       if(encRetVal.encoded == ENCODE_FAIL)
878       {
879          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Node config update ack structure (at %s)\n",\
880                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
881          return RFAILED;
882       }
883       else
884       {
885          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Node config update ack \n");
886          for(int i=0; i< encBufSize; i++)
887          {
888             DU_LOG("%x",encBuf[i]);
889          } 
890       }
891
892
893       /* Sending msg */
894       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
895       {
896          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Node config update ack ");
897          return RFAILED;
898       }
899
900       break;
901    }while(true);
902    
903    FreeE2NodeConfigUpdateAck(e2apMsg);
904    return ret;
905 }
906
907 /*******************************************************************
908 *
909 * @brief Handles received E2AP message and sends back response  
910 *
911 * @details
912 *
913 *    Function : E2APMsgHdlr
914 *
915 *    Functionality:
916 *         - Decodes received E2AP control message
917 *         - Prepares response message, encodes and sends to SCTP
918 *
919 * @params[in] 
920 * @return ROK     - success
921 *         RFAILED - failure
922 *
923 * ****************************************************************/
924 void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
925 {
926    int             i;
927    char            *recvBuf;
928    MsgLen          copyCnt;
929    MsgLen          recvBufLen;
930    E2AP_PDU_t      *e2apMsg;
931    asn_dec_rval_t  rval; /* Decoder return value */
932    E2AP_PDU_t      e2apasnmsg ;
933  
934    DU_LOG("\nINFO  -->  E2AP : Received E2AP message buffer");
935    ODU_PRINT_MSG(mBuf, 0,0);
936  
937    /* Copy mBuf into char array to decode it */
938    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
939    RIC_ALLOC(recvBuf, (Size)recvBufLen);
940
941    if(recvBuf == NULLP)
942    {
943       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
944       return;
945    }
946    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
947    {
948       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
949       return;
950    }
951
952    DU_LOG("\nDEBUG  -->  E2AP : Received flat buffer to be decoded : ");
953    for(i=0; i< recvBufLen; i++)
954    {
955         DU_LOG("%x",recvBuf[i]);
956    }
957
958    /* Decoding flat buffer into E2AP messsage */
959    e2apMsg = &e2apasnmsg;
960    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
961
962    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
963    RIC_FREE(recvBuf, (Size)recvBufLen);
964
965    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
966    {
967       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
968       return;
969    }
970    DU_LOG("\n");
971    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
972
973    switch(e2apMsg->present)
974    {
975       case E2AP_PDU_PR_initiatingMessage:
976       {
977          switch(e2apMsg->choice.initiatingMessage->value.present)
978          {
979             case InitiatingMessageE2__value_PR_E2setupRequest:
980             {
981                DU_LOG("\nINFO  -->  E2AP : E2 setup request received");
982                ProcE2SetupReq(duId, &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest);
983                     break;
984             }
985             case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate:
986             {
987                DU_LOG("\nINFO  -->  E2AP : E2 node config update received");
988                BuildAndSendE2NodeConfigUpdateAck(*duId);
989                break;
990             }
991             case InitiatingMessageE2__value_PR_RICindication:
992             {
993                DU_LOG("\nINFO  -->  E2AP : RIC Indication Acknowledged");
994                break;
995             }
996             default:
997             {
998                DU_LOG("\nERROR  -->  E2AP : Invalid type of intiating message [%d]",e2apMsg->choice.initiatingMessage->value.present);
999                return;
1000             }
1001          }/* End of switch(initiatingMessage) */
1002          break;
1003       }
1004       case E2AP_PDU_PR_successfulOutcome: 
1005       {
1006          switch(e2apMsg->choice.successfulOutcome->value.present)
1007          {
1008             case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:  
1009             {
1010                ProcRicSubscriptionResponse(*duId);
1011                break;
1012             }
1013             default:
1014             {
1015                DU_LOG("\nERROR  -->  E2AP : Invalid type of successfulOutcome message [%d]",e2apMsg->choice.successfulOutcome->value.present);
1016                return;
1017             }
1018             break;
1019          }
1020          break; 
1021       }
1022       default:
1023       {
1024          DU_LOG("\nERROR  -->  E2AP : Invalid type message type ");
1025          return;
1026       }
1027  
1028     }/* End of switch(e2apMsg->present) */
1029 } /* End of E2APMsgHdlr */
1030
1031
1032 /**********************************************************************
1033   End of file
1034  **********************************************************************/