[Epic-ID: ODUHIGH-510][Task-ID: ODUHIGH-512] Implementation of E2 setup failure
[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 "UnsuccessfulOutcomeE2.h"
32 #include "E2AP-PDU.h"
33 #include "du_log.h"
34 #include "E2nodeComponentInterfaceF1.h"
35
36
37 /*******************************************************************
38 *
39 * @brief Sends E2 msg over SCTP
40 *
41 * @details
42 *
43 *    Function : SendE2APMsg
44 *
45 *    Functionality: Sends E2 msg over SCTP
46 *
47 * @params[in] Region region
48 *             Pool pool
49 * @return ROK     - success
50 *         RFAILED - failure
51 *
52 * ****************************************************************/
53
54 uint8_t SendE2APMsg(Region region, Pool pool, uint32_t duId)
55 {
56    Buffer *mBuf;
57
58    if(ODU_GET_MSG_BUF(region, pool, &mBuf) == ROK)
59    {
60       if(ODU_ADD_POST_MSG_MULT((Data *)encBuf, encBufSize, mBuf) == ROK)
61       {
62          ODU_PRINT_MSG(mBuf, 0,0);
63  
64          if(sctpSend(duId, mBuf) != ROK)
65          {
66             DU_LOG("\nERROR  -->  E2AP : SCTP Send for E2  failed");
67             ODU_PUT_MSG_BUF(mBuf);
68             return RFAILED;
69          }
70       }
71       else
72       {
73          DU_LOG("\nERROR  -->  E2AP : ODU_ADD_POST_MSG_MULT failed");
74          ODU_PUT_MSG_BUF(mBuf);
75          return RFAILED;
76       }
77       ODU_PUT_MSG_BUF(mBuf);
78    }
79    else
80    {
81       DU_LOG("\nERROR  -->  E2AP : Failed to allocate memory");
82       return RFAILED;
83    }
84  
85    return ROK;
86 } /* SendE2APMsg */
87
88 /*******************************************************************
89  *
90  * @brief Builds Global RIC Id Params
91  *
92  * @details
93  *
94  *    Function : BuildGlobalRicId
95  *
96  *    Functionality: Building the Plmn and ric id
97  *
98  * @params[in] GlobalRIC_ID_t *ricId
99  * @return ROK     - success
100  *         RFAILED - failure
101  *
102  * ****************************************************************/
103
104 uint8_t BuildGlobalRicId(GlobalRIC_ID_t *ricId)
105 {
106    uint8_t unused = 4;
107    uint8_t byteSize = 3;
108    uint8_t ricVal= 1;
109    if(ricId != NULLP)
110    {
111       ricId->pLMN_Identity.size = byteSize * sizeof(uint8_t);
112       RIC_ALLOC(ricId->pLMN_Identity.buf,  ricId->pLMN_Identity.size);
113       buildPlmnId(ricCb.ricCfgParams.plmn , ricId->pLMN_Identity.buf);
114       /* fill ric Id */
115       ricId->ric_ID.size = byteSize * sizeof(uint8_t);
116       RIC_ALLOC(ricId->ric_ID.buf, ricId->ric_ID.size);
117       fillBitString(&ricId->ric_ID, unused, byteSize, ricVal);
118    }
119    return ROK;   
120 }
121
122 /*******************************************************************
123  *
124  * @brief deallocate the memory allocated in E2SetupResponse
125  *
126  * @details
127  *
128  *    Function : FreeE2SetupRsp 
129  *
130  *    Functionality: deallocate the memory allocated in E2SetupResponse 
131  *
132  * @params[in] E2AP_PDU_t *e2apMsg
133  *
134  * @return void
135  * ****************************************************************/
136 void FreeE2SetupRsp(E2AP_PDU_t *e2apMsg)
137 {
138    uint8_t arrIdx = 0;
139    E2setupResponse_t  *e2SetupRsp;
140
141    if(e2apMsg)
142    {
143       if(e2apMsg->choice.successfulOutcome)
144       {
145          e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
146          if(e2SetupRsp->protocolIEs.list.array)
147          {
148             for(arrIdx=0; arrIdx<e2SetupRsp->protocolIEs.list.count; arrIdx++)
149             {
150                RIC_FREE(e2SetupRsp->protocolIEs.list.array[arrIdx], sizeof(E2setupResponseIEs_t)); 
151             }
152             RIC_FREE(e2SetupRsp->protocolIEs.list.array, e2SetupRsp->protocolIEs.list.size);
153          }
154          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
155       }
156       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
157    }
158 }
159
160 /*******************************************************************
161  *
162  * @brief Build E2node Component config addition ack list
163  *
164  * @details
165  *
166  *    Function :  BuildE2nodeComponentConfigAdditionAck
167  *
168  *    Functionality: deallocate the memory allocated in E2SetupResponse 
169  *
170  * @params[in] E2nodeComponentConfigAdditionAck_List_t
171  * *e2NodeConfigAdditionAckList
172  *
173  * @return ROK - success
174  *         RFAILED - failure
175  * ****************************************************************/
176 uint8_t BuildE2nodeComponentConfigAdditionAck(E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList, uint8_t duId)
177 {
178    uint8_t arrIdx = 0;
179    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem;
180    
181    e2NodeConfigAdditionAckList->list.count = 1;
182    e2NodeConfigAdditionAckList->list.size = e2NodeConfigAdditionAckList->list.count * sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t*);
183    RIC_ALLOC(e2NodeConfigAdditionAckList->list.array, e2NodeConfigAdditionAckList->list.size);
184    if(e2NodeConfigAdditionAckList->list.array == NULLP)
185    {
186       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
187       return RFAILED;
188    }
189
190    for(arrIdx = 0; arrIdx< e2NodeConfigAdditionAckList->list.count; arrIdx++)
191    {
192       RIC_ALLOC(e2NodeConfigAdditionAckList->list.array[arrIdx], sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
193       if(e2NodeConfigAdditionAckList->list.array[arrIdx] == NULLP)
194       {
195          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
196          return RFAILED;
197       }
198    }
199    e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[0];
200    e2NodeAddAckItem->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck_Item;
201    e2NodeAddAckItem->criticality = CriticalityE2_reject;
202    e2NodeAddAckItem->value.present = E2nodeComponentConfigAdditionAck_ItemIEs__value_PR_E2nodeComponentConfigAdditionAck_Item;
203    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentInterfaceType = E2nodeComponentInterfaceType_f1;
204
205    /* >E2 Node Component ID */
206    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1;
207    RIC_ALLOC(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\
208          sizeof(E2nodeComponentInterfaceF1_t));
209    if(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1 == NULLP)
210    {
211       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
212       return RFAILED;
213    }
214    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t);
215    RIC_ALLOC(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
216          e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
217
218    if(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP)
219    {
220       DU_LOG("\nERROR  -->list.  E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
221       return RFAILED;
222    }
223    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]  = duId;
224    
225    /* >E2 Node Component Configuration Acknowledge*/
226    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentConfigurationAck.updateOutcome = \
227    E2nodeComponentConfigurationAck__updateOutcome_success;
228    
229    return ROK;  
230 }
231 /*******************************************************************
232  *
233  * @brief Builds and sends the E2SetupResponse
234  *
235  * @details
236  *
237  *    Function : BuildAndSendE2SetupRsp
238  *
239  *    Functionality: Constructs the F1SetupResponse message and sends
240  *                   it back to the DU through SCTP.
241  *
242  * @params[in] void **buf,Buffer to which encoded pattern is written into
243  * @params[in] int *size,size of buffer
244  *
245  * @return ROK     - success
246  *         RFAILED - failure
247  *
248  * ****************************************************************/
249 uint8_t BuildAndSendE2SetupRsp(uint32_t duId, uint8_t transId)
250 {
251    E2AP_PDU_t         *e2apMsg = NULL;
252    E2setupResponse_t  *e2SetupRsp;
253    asn_enc_rval_t     encRetVal; 
254    uint8_t            idx;
255    uint8_t            elementCnt;
256    bool  memAllocFailed = false;
257  
258    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup Response\n");
259    while(true)
260    {
261       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); 
262       if(e2apMsg == NULLP)
263       {
264          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
265          break;
266       }
267       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
268       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
269       if(e2apMsg->choice.successfulOutcome == NULLP)
270       {
271          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
272          break;  
273       }
274
275       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
276       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
277       e2apMsg->choice.successfulOutcome->value.present = \
278                                                          SuccessfulOutcomeE2__value_PR_E2setupResponse;
279       e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
280
281       elementCnt = 3;
282       e2SetupRsp->protocolIEs.list.count = elementCnt;
283       e2SetupRsp->protocolIEs.list.size  = elementCnt * sizeof(E2setupResponseIEs_t*);
284
285       RIC_ALLOC(e2SetupRsp->protocolIEs.list.array, e2SetupRsp->protocolIEs.list.size);
286       if(e2SetupRsp->protocolIEs.list.array == NULLP)
287       {
288          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");
289          break;  
290       }
291
292       for(idx=0; idx<elementCnt; idx++)
293       {
294          RIC_ALLOC(e2SetupRsp->protocolIEs.list.array[idx], sizeof(E2setupResponseIEs_t)); 
295          if(e2SetupRsp->protocolIEs.list.array[idx] == NULLP)
296          { 
297             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");
298             memAllocFailed = true;
299             break;
300          }    
301       }
302       
303       if(memAllocFailed == true)
304       {
305           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");    
306           break;
307       }
308       /* Trans Id */
309       idx = 0;
310       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_TransactionID;
311       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
312       e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_TransactionID; 
313       e2SetupRsp->protocolIEs.list.array[idx]->value.choice.TransactionID  = transId;
314
315       /* Global RIC ID */
316       idx++;
317       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_GlobalRIC_ID;
318       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
319       e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
320                                                                E2setupResponseIEs__value_PR_GlobalRIC_ID;
321
322       if(BuildGlobalRicId(&(e2SetupRsp->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID))!=ROK)
323       {
324          DU_LOG("\nERROR  -->  E2AP : Failed to build Global Ric Id");
325          break;
326       }
327       
328       /* E2 Node Component Configuration Addition Acknowledge List*/
329       idx++;
330       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck;
331       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
332       e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
333       E2setupResponseIEs__value_PR_E2nodeComponentConfigAdditionAck_List;
334       if(BuildE2nodeComponentConfigAdditionAck(&e2SetupRsp->protocolIEs.list.array[idx]->value.choice.E2nodeComponentConfigAdditionAck_List, duId)!=ROK)
335       {
336          DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config addition ack list");
337          break;
338       }
339
340       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
341       memset(encBuf, 0, ENC_BUF_MAX_LEN);
342       encBufSize = 0;
343       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
344
345       /* Check encode results */
346       if(encRetVal.encoded == ENCODE_FAIL)
347       {
348          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupResponse structure (at %s)\n",\
349                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
350          break;   
351       } 
352       else 
353       {
354          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SetupResponse\n");
355          for(int i=0; i< encBufSize; i++)
356          {
357             DU_LOG("%x",encBuf[i]);
358          } 
359       }
360
361       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
362       {
363          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Response failed");      
364          break;   
365       }
366       break;
367    }
368
369    FreeE2SetupRsp(e2apMsg);
370    BuildAndSendRicSubscriptionReq(duId);
371    return ROK;
372 }
373
374 /*******************************************************************
375  *
376  * @brief Builds Ric Request Id
377  *
378  * @details
379  *
380  *    Function : BuildRicRequestId
381  *
382  *    Functionality: Building the Ric Request Id
383  *
384  * @params[in] RICrequestID_t *ricReqId
385  * @return ROK     - success
386  *         RFAILED - failure
387  *
388  * ****************************************************************/
389
390 uint8_t BuildRicRequestId(RICrequestID_t *ricReqId)
391 {
392
393    if(ricReqId != NULLP)
394    {
395       ricReqId->ricRequestorID = 1;
396       ricReqId->ricInstanceID  = 1;
397    }
398    return ROK;
399 }
400
401 /*******************************************************************
402  *
403  * @brief Fills Ric Action To be Setup Item
404  *
405  * @details
406  *
407  *    Function : fillSetupItems
408  *
409  *    Functionality: Filling ricAction Id, RicActionType
410  *
411  * @params[in] RICaction_ToBeSetup_Item_t *setupItems
412  * @return pointer of type RICaction_ToBeSetup_Item_t
413  *
414  * ****************************************************************/
415
416 RICaction_ToBeSetup_Item_t* fillSetupItems(RICaction_ToBeSetup_Item_t *setupItems)
417 {
418    if(setupItems != NULLP)
419    {
420       setupItems->ricActionID = 0;
421       setupItems->ricActionType = RICactionType_report;
422    }
423
424    return (setupItems);
425 }
426
427 /*******************************************************************
428  *
429  * @brief Fills RIC Subscription Details Item List
430  *
431  * @details
432  *
433  *    Function : fillSubsDetails
434  *
435  *    Functionality: Fill the RIC Subscription Details Items List
436  *
437  * @params[in] RICaction_ToBeSetup_ItemIEs_t *items
438  * @return ROK     - success
439  *         RFAILED - failure
440  *
441  * ****************************************************************/
442
443 uint8_t fillSubsDetails(RICaction_ToBeSetup_ItemIEs_t *items)
444 {
445    if(items != NULLP)
446    {
447       items->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item;
448       items->criticality   =  CriticalityE2_ignore;
449       items->value.present =  RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
450       fillSetupItems(&(items->value.choice.RICaction_ToBeSetup_Item));
451    }
452    return ROK;
453 }
454
455 /*******************************************************************
456  *
457  * @brief builds RIC Subscription Details
458  *
459  * @details
460  *
461  *    Function : BuildsRicSubsDetails
462  *
463  *    Functionality: Builds the RIC Subscription Details
464  *
465  * @params[in] RICsubscriptionDetails_t *subsDetails
466  * @return ROK     - success
467  *         RFAILED - failure
468  *
469  * ****************************************************************/
470
471 uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails)
472 {
473
474    uint8_t elementCnt;
475
476    if(subsDetails != NULLP)
477    {
478       /* Octet string to be build here */
479       /* Sending PLMN as Octect string */
480       uint8_t byteSize = 3;
481       subsDetails->ricEventTriggerDefinition.size = byteSize * sizeof(uint8_t);
482       RIC_ALLOC(subsDetails->ricEventTriggerDefinition.buf,  subsDetails->ricEventTriggerDefinition.size);
483       buildPlmnId(ricCb.ricCfgParams.plmn, subsDetails->ricEventTriggerDefinition.buf);
484       elementCnt = 1;
485       subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt;
486       subsDetails->ricAction_ToBeSetup_List.list.size = \
487                       elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t);
488       RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, \
489                 subsDetails->ricAction_ToBeSetup_List.list.size);
490       if(subsDetails->ricAction_ToBeSetup_List.list.array  == NULLP)
491       {
492          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICactionToBeSetup Items failed");
493          return RFAILED;
494       } 
495       RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[0],\
496                    sizeof(RICaction_ToBeSetup_ItemIEs_t));
497       fillSubsDetails(subsDetails->ricAction_ToBeSetup_List.list.array[0]);
498    }
499    return ROK;
500 }
501
502 /*******************************************************************
503  *
504  * @brief Builds and Send the RicSubscriptionReq
505  *
506  * @details
507  *
508  *    Function : BuildAndSendRicSubscriptionReq
509  *
510  * Functionality:Fills the RicSubscriptionReq
511  *
512  * @return ROK     - success
513  *         RFAILED - failure
514  *
515  ******************************************************************/
516
517 uint8_t BuildAndSendRicSubscriptionReq(uint32_t duId)
518 {
519
520    E2AP_PDU_t                 *e2apRicMsg = NULL;
521    RICsubscriptionRequest_t   *ricSubscriptionReq;
522    uint8_t         elementCnt;
523    uint8_t         idx;
524    uint8_t         ieId;
525    uint8_t         ret; 
526    asn_enc_rval_t  encRetVal;        /* Encoder return value */
527
528    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Request\n");
529
530    RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
531    if(e2apRicMsg == NULLP)
532    {
533       DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
534       return RFAILED;
535    }
536
537    e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
538    RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
539    if(e2apRicMsg->choice.initiatingMessage == NULLP)
540    {
541       DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
542       RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
543       return RFAILED;
544    }
545    e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
546    e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
547    e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
548    
549    RIC_ALLOC(ricSubscriptionReq, sizeof(RICsubscriptionRequest_t));
550    ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
551    
552    elementCnt = 3;
553    ricSubscriptionReq->protocolIEs.list.count = elementCnt;
554    ricSubscriptionReq->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
555
556    /* Initialize the subscription members */
557    RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, \
558               ricSubscriptionReq->protocolIEs.list.size);
559    if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
560    {
561       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICSubscriptionRequestIEs failed");
562       RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
563       RIC_FREE(e2apRicMsg, (Size)sizeof(E2AP_PDU_t));
564       return RFAILED;
565    }
566    
567    for(idx=0; idx<elementCnt; idx++)
568    {
569       RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx],\
570             sizeof(RICsubscriptionRequest_IEs_t));
571       if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
572       {
573          for(ieId=0; ieId<idx; ieId++)
574          {
575             RIC_FREE(ricSubscriptionReq->protocolIEs.list.array[ieId],\
576                   sizeof(RICsubscriptionRequest_IEs_t));
577          }
578          RIC_FREE(ricSubscriptionReq->protocolIEs.list.array,\
579                   ricSubscriptionReq->protocolIEs.list.size);
580          RIC_FREE(e2apRicMsg->choice.initiatingMessage, \
581                sizeof(InitiatingMessageE2_t));
582          RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
583          return RFAILED;
584       }
585    }
586
587    /* Filling RIC Request Id */
588    idx = 0;
589    ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
590    ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
591    ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
592                                     RICsubscriptionRequest_IEs__value_PR_RICrequestID;
593  
594    BuildRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID);
595
596
597    /* Filling RAN Function Id */
598    idx++;
599    ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
600    ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
601    ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
602                                     RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
603    ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1;
604
605
606    /* Filling RIC Subscription Details */
607    idx++;
608    ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
609    ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
610    ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
611                                     RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
612
613    BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails));
614
615
616    /* Prints the Msg formed */
617    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
618
619    memset(encBuf, 0, ENC_BUF_MAX_LEN);
620    encBufSize = 0;
621    encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\
622                encBuf);
623    if(encRetVal.encoded == ENCODE_FAIL)
624    {
625       DU_LOG("\nERROR  -->  E2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
626       encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
627       return RFAILED;
628    }
629    else
630    {
631       DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
632       for(int i=0; i< encBufSize; i++)
633       {
634           DU_LOG("%x",encBuf[i]);
635       } 
636    }
637
638
639    /* Sending msg */
640    if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
641    {
642       DU_LOG("\nERROR  -->  E2AP : Sending RIC subscription Request failed");
643       return RFAILED;
644    }
645
646    return ROK;
647 }
648
649 /*******************************************************************
650  *
651  * @brief Process RicSubscriptionResponse
652  *
653  * @details
654  *
655  *    Function : ProcRicSubscriptionRsp
656  *
657  * Functionality: Processes RicSubscriptionRsp
658  *
659  * @return ROK     - void
660  *
661  ******************************************************************/
662
663 void ProcRicSubscriptionResponse(uint32_t duId)
664 {
665    uint8_t duIdx = 0;
666    DuDb *duDb;
667
668    DU_LOG("\nINFO  -->  E2AP : RICsubscriptionResponse Msg Acknowledged");
669
670    SEARCH_DU_DB(duIdx, duId, duDb);
671    if(duDb)
672       duDb->ricSubscribedToDu = true;
673 }
674
675 /*******************************************************************
676  *
677  * @brief deallocate the memory allocated in E2SetupFailure
678  *
679  * @details
680  *
681  *    Function : FreeE2SetupFailure 
682  *
683  *    Functionality: deallocate the memory allocated in E2SetupFailure 
684  *
685  * @params[in] E2AP_PDU_t *e2apMsg
686  *
687  * @return void
688  * ****************************************************************/
689 void FreeE2SetupFailure(E2AP_PDU_t *e2apMsg)
690 {
691    uint8_t arrIdx = 0;
692    E2setupFailure_t  *e2SetupFail;
693
694    if(e2apMsg)
695    {
696       if(e2apMsg->choice.unsuccessfulOutcome)
697       {
698          e2SetupFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
699          if(e2SetupFail->protocolIEs.list.array)
700          {
701             for(arrIdx=0; arrIdx<e2SetupFail->protocolIEs.list.count; arrIdx++)
702             {
703                RIC_FREE(e2SetupFail->protocolIEs.list.array[arrIdx], sizeof(E2setupFailureIEs_t)); 
704             }
705             RIC_FREE(e2SetupFail->protocolIEs.list.array, e2SetupFail->protocolIEs.list.size);
706          }
707          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
708       }
709       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
710    }
711 }
712
713 /*******************************************************************
714  *
715  * @brief Buld and send the E2 Setup failure
716  *
717  * @details
718  *
719  *    Function : BuildAndSendE2SetupFailure
720  *
721  *    Functionality:
722  *         - Buld and send the E2 Setup failure
723  * @return ROK     - success
724  *         RFAILED - failure
725  *
726  * ****************************************************************/
727
728 uint8_t BuildAndSendE2SetupFailure(uint32_t duId, uint8_t transId)
729 {
730    E2AP_PDU_t         *e2apMsg = NULL;
731    E2setupFailure_t   *e2SetupFailure;
732    asn_enc_rval_t     encRetVal;
733    uint8_t            arrIdx;
734    uint8_t            elementCnt;
735    bool  memAllocFailed = false;
736
737    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup failure\n");
738    while(true)
739    {
740       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
741       if(e2apMsg == NULLP)
742       {
743          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
744          break;
745       }
746       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
747       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
748       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
749       {
750          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
751          break;
752       }
753
754       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
755       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
756       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2setupFailure;
757       e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
758
759       elementCnt = 3;
760       e2SetupFailure->protocolIEs.list.count = elementCnt;
761       e2SetupFailure->protocolIEs.list.size  = elementCnt * sizeof(struct E2setupFailureIEs *);
762
763       RIC_ALLOC(e2SetupFailure->protocolIEs.list.array, e2SetupFailure->protocolIEs.list.size);
764       if(e2SetupFailure->protocolIEs.list.array == NULLP)
765       {
766          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
767          break;
768       }
769
770       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
771       {
772          RIC_ALLOC(e2SetupFailure->protocolIEs.list.array[arrIdx], sizeof(struct E2setupFailureIEs));
773          if(e2SetupFailure->protocolIEs.list.array[arrIdx] == NULLP)
774          {
775             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
776             memAllocFailed = true;
777             break;
778          }
779       }
780
781       if(memAllocFailed == true)
782       {
783           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
784           break;
785       }
786
787       /* Trans Id */
788       arrIdx = 0;
789       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
790       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
791       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TransactionID;
792       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
793
794       arrIdx++;
795       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
796       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
797       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_CauseE2;
798       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.present = CauseE2_PR_protocol;
799       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.protocol = CauseE2Protocol_unspecified;
800
801       arrIdx++;
802       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
803       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
804       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TimeToWaitE2;
805       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
806
807       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
808       memset(encBuf, 0, ENC_BUF_MAX_LEN);
809       encBufSize = 0;
810       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
811
812       /* Check encode results */
813       if(encRetVal.encoded == ENCODE_FAIL)
814       {
815          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Setup failure structure (at %s)\n",\
816                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
817          break;
818       }
819       else
820       {
821          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Setup Failure\n");
822          for(int i=0; i< encBufSize; i++)
823          {
824             DU_LOG("%x",encBuf[i]);
825          }
826       }
827
828       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
829       {
830          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Failure failed");
831          break;
832       }
833       break;
834    }
835
836    FreeE2SetupFailure(e2apMsg);
837 }
838
839 /*******************************************************************
840  *
841  * @brief process the e2setup request 
842  *
843  * @details
844  *
845  *    Function : ProcE2SetupReq
846  *
847  * Functionality: process the e2setup request
848  *
849  * @return ROK     - success
850  *         RFAILED - failure
851  *
852  ******************************************************************/
853
854 uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
855 {
856    uint8_t arrIdx = 0, e2NodeAddListIdx =0, duIdx = 0, transId =0;
857    DuDb    *duDb = NULLP;
858    E2nodeComponentConfigAddition_List_t *e2NodeAddList;
859    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
860
861    if(e2SetupReq)
862    {
863         if(e2SetupReq->protocolIEs.list.array)      
864         {
865             for(arrIdx=0; arrIdx<e2SetupReq->protocolIEs.list.count; arrIdx++)
866             {
867                if(e2SetupReq->protocolIEs.list.array[arrIdx])
868                {
869                   switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
870                   {
871                      case ProtocolIE_IDE2_id_TransactionID:
872                      {
873                         transId = e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; 
874                         break;
875                      }
876                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
877                      {
878                         e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;      
879                         if(e2NodeAddList->list.array)
880                         {
881                            for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
882                            {
883                               if(e2NodeAddList->list.array[e2NodeAddListIdx])
884                               {
885                                  e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
886                                  if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
887                                     e2nodeComponentInterfaceTypeF1)
888                                  {
889                                     if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
890                                        e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf)
891                                     {
892                                        *duId = e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.\
893                                                choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0];
894                                        SEARCH_DU_DB(duIdx, duId, duDb); 
895                                        if(duDb == NULLP)
896                                        {
897                                           duDb = &ricCb.duInfo[ricCb.numDu];
898                                           ricCb.numDu++;
899                                        }
900                                        memset(duDb, 0, sizeof(DuDb));
901                                        duDb->duId = *duId;
902
903                                        if(BuildAndSendE2SetupRsp(*duId, transId) !=ROK)
904                                        {
905                                            DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 setup response");
906                                            return RFAILED;
907                                        }
908                                     }
909                                  }
910                               }
911                            }
912                         }
913                         break;
914                      }
915                      default:
916                         break;
917                   }
918                }
919             }
920         }
921    }
922    return ROK;   
923 }
924
925 /*******************************************************************
926  *
927  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
928  *
929  * @details
930  *
931  *    Function : FreeE2NodeConfigUpdate 
932  *
933  *    Functionality:
934  *       - freeing the memory allocated for E2nodeConfigurationUpdate
935  *
936  * @params[in] E2AP_PDU_t *e2apMsg 
937  * @return ROK     - success
938  *         RFAILED - failure
939  *
940  * ****************************************************************/
941 void FreeE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg)
942 {
943    uint8_t arrIdx =0;
944    E2nodeConfigurationUpdate_t *e2NodeConfigUpdateAck;
945
946    if(e2apMsg != NULLP)
947    {
948       if(e2apMsg->choice.successfulOutcome != NULLP)
949       {
950          e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
951          if(e2NodeConfigUpdateAck->protocolIEs.list.array != NULLP)
952          {
953             for(arrIdx = 0; arrIdx < e2NodeConfigUpdateAck->protocolIEs.list.count; arrIdx++)
954             {
955                RIC_FREE(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_t));
956             }
957             RIC_FREE(e2NodeConfigUpdateAck->protocolIEs.list.array, e2NodeConfigUpdateAck->protocolIEs.list.size);
958          }
959          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
960       }
961       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
962    }
963 }
964
965 /*******************************************************************
966  *
967  * @brief Buld and send the E2 node config update msg 
968  *
969  * @details
970  *
971  *    Function : BuildAndSendE2NodeConfigUpdate
972  *
973  *    Functionality:
974  *         - Buld and send the E2 node config update msg
975  * @return ROK     - success
976  *         RFAILED - failure
977  *
978  * ****************************************************************/
979
980 uint8_t BuildAndSendE2NodeConfigUpdateAck(uint32_t duId)
981 {
982    uint8_t arrIdx = 0,elementCnt = 1;
983    uint8_t ret = ROK;
984    E2AP_PDU_t        *e2apMsg = NULLP;
985    E2nodeConfigurationUpdateAcknowledge_t *e2NodeConfigUpdateAck = NULLP;
986    asn_enc_rval_t     encRetVal;       /* Encoder return value */
987
988    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update Ack Message\n");
989    do
990    {
991       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
992       if(e2apMsg == NULLP)
993       {
994          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
995          break;
996       }
997       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
998       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
999       if(e2apMsg->choice.successfulOutcome == NULLP)
1000       {
1001          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1002          RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1003          return RFAILED;
1004       }
1005       
1006       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
1007       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
1008       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge;
1009       e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
1010
1011       e2NodeConfigUpdateAck->protocolIEs.list.count = elementCnt;
1012       e2NodeConfigUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t*);
1013       /* Initialize the Ric Indication members */
1014       RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array, \
1015             e2NodeConfigUpdateAck->protocolIEs.list.size);
1016       if(e2NodeConfigUpdateAck->protocolIEs.list.array == NULLP)
1017       {
1018          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdateAck failed");
1019          break;
1020       }
1021       
1022       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
1023       {
1024          RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t));
1025          if(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
1026          {
1027             
1028             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdateAck failed");
1029             break;
1030          }
1031       }
1032
1033       arrIdx = 0;
1034       /* TransactionID */
1035       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
1036       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1037       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_TransactionID;
1038       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = TRANS_ID;
1039
1040
1041       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1042
1043       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1044       encBufSize = 0;
1045       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
1046             encBuf);
1047       if(encRetVal.encoded == ENCODE_FAIL)
1048       {
1049          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Node config update ack structure (at %s)\n",\
1050                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1051          return RFAILED;
1052       }
1053       else
1054       {
1055          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Node config update ack \n");
1056          for(int i=0; i< encBufSize; i++)
1057          {
1058             DU_LOG("%x",encBuf[i]);
1059          } 
1060       }
1061
1062
1063       /* Sending msg */
1064       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
1065       {
1066          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Node config update ack ");
1067          return RFAILED;
1068       }
1069
1070       break;
1071    }while(true);
1072    
1073    FreeE2NodeConfigUpdateAck(e2apMsg);
1074    return ret;
1075 }
1076
1077 /*******************************************************************
1078  *
1079  * @brief Deallocate the memory allocated for E2 Reset Response
1080  *
1081  * @details
1082  *
1083  *    Function : FreeE2ResetResponse
1084  *
1085  *    Functionality:
1086  *       - freeing the memory allocated for E2ResetResponse
1087  *
1088  * @params[in] E2AP_PDU_t *e2apMsg
1089  * @return ROK     - success
1090  *         RFAILED - failure
1091  *
1092  * ****************************************************************/
1093 void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg)
1094 {
1095    uint8_t ieIdx =0;
1096    ResetResponseE2_t *resetResponse;
1097
1098    if(e2apMsg != NULLP)
1099    {
1100       if(e2apMsg->choice.successfulOutcome != NULLP)
1101       {
1102          resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
1103          if(resetResponse->protocolIEs.list.array)
1104          {
1105             for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
1106             {
1107                if(resetResponse->protocolIEs.list.array[ieIdx])
1108                {
1109                   RIC_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
1110                }
1111             }
1112             RIC_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
1113          }
1114          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1115       }
1116       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1117    }
1118 }
1119
1120 /*******************************************************************
1121  *
1122  * @brief Buld and send the E2 Reset Response msg
1123  *
1124  * @details
1125  *
1126  *    Function : BuildAndSendE2ResetResponse
1127  *
1128  *    Functionality:
1129  *         - Buld and send the E2 Reset Response Message
1130  * @return ROK     - success
1131  *         RFAILED - failure
1132  *
1133  * ****************************************************************/
1134 uint8_t BuildAndSendResetResponse(uint32_t duId, uint8_t transId)
1135 {
1136    uint8_t           ieIdx = 0, elementCnt = 0;
1137    uint8_t           ret = RFAILED;
1138    E2AP_PDU_t        *e2apMsg = NULLP;
1139    ResetResponseE2_t *resetResponse;
1140    asn_enc_rval_t    encRetVal;       /* Encoder return value */
1141
1142    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
1143    do
1144    {
1145       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1146       if(e2apMsg == NULLP)
1147       {
1148          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
1149          break;
1150       }
1151       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
1152
1153       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1154       if(e2apMsg->choice.successfulOutcome == NULLP)
1155       {
1156          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
1157          RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1158          return RFAILED;
1159       }
1160  
1161       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
1162       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
1163       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
1164       resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
1165
1166       elementCnt = 1;
1167       resetResponse->protocolIEs.list.count = elementCnt;
1168       resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
1169       RIC_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
1170       if(!resetResponse->protocolIEs.list.array)
1171       {
1172          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
1173          break;
1174       }
1175
1176       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
1177       {
1178          RIC_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
1179          if(!resetResponse->protocolIEs.list.array[ieIdx])
1180          {
1181             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
1182             break;
1183          }
1184       }
1185       if(ieIdx < elementCnt)
1186          break;
1187
1188       ieIdx = 0; 
1189       resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
1190       resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
1191       resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
1192       resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
1193
1194       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1195
1196       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1197       encBufSize = 0;
1198       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
1199       if(encRetVal.encoded == ENCODE_FAIL)
1200       {
1201          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
1202                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1203          return RFAILED;
1204       }
1205       else
1206       {
1207          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
1208          for(int i=0; i< encBufSize; i++)
1209          {
1210             DU_LOG("%x",encBuf[i]);
1211          }
1212       }
1213
1214       /* Sending msg */
1215       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
1216       {
1217          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
1218          return RFAILED;
1219       }
1220
1221       ret = ROK;
1222       break;
1223    }while(true);
1224
1225    FreeE2ResetResponse(e2apMsg);
1226    return ROK;
1227 }
1228
1229 /*******************************************************************
1230  *
1231  * @brief process the E2 Reset Request
1232  *
1233  * @details
1234  *
1235  *    Function : ProcE2ResetReq
1236  *
1237  * Functionality: Process E2 Reset Request
1238  *
1239  * @return ROK     - success
1240  *         RFAILED - failure
1241  *
1242  ******************************************************************/
1243
1244 uint8_t ProcE2ResetReq(uint32_t duId, ResetRequestE2_t  *resetReq)
1245 {
1246    uint8_t ieIdx = 0, duIdx = 0;
1247    uint8_t transId = 0, cause = 0;
1248    DuDb    *duDb = NULLP;
1249
1250    if(resetReq)
1251    {
1252       if(resetReq->protocolIEs.list.array)
1253       {
1254          for(ieIdx=0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
1255          {
1256             if(resetReq->protocolIEs.list.array[ieIdx])
1257             {
1258                switch(resetReq->protocolIEs.list.array[ieIdx]->id)
1259                {
1260                   case ProtocolIE_IDE2_id_TransactionID:
1261                      transId = resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
1262                      break;
1263                   case ProtocolIE_IDE2_id_CauseE2:
1264                      DU_LOG("\nDEBUG  -->  E2AP : Reset reason %d", resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present);
1265                      switch(resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present)
1266                      {
1267                         case CauseE2_PR_NOTHING:
1268                            break;
1269                         case CauseE2_PR_ricRequest:
1270                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricRequest;
1271                            break;
1272                         case CauseE2_PR_ricService:
1273                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricService;
1274                            break;
1275                         case CauseE2_PR_e2Node:
1276                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.e2Node;
1277                            break;
1278                         case CauseE2_PR_transport:
1279                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.transport;
1280                            break;
1281                         case CauseE2_PR_protocol:
1282                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.protocol;
1283                            break;
1284                         case CauseE2_PR_misc:
1285                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.misc;
1286                            break;
1287                      }
1288                      DU_LOG("\nDEBUG  -->  E2AP : Reset cause %d", cause);
1289                      break;
1290                }
1291             }
1292          }
1293       }
1294    }
1295    BuildAndSendResetResponse(duId, transId);
1296    return ROK;
1297 }
1298
1299 /*******************************************************************
1300 *
1301 * @brief Handles received E2AP message and sends back response  
1302 *
1303 * @details
1304 *
1305 *    Function : E2APMsgHdlr
1306 *
1307 *    Functionality:
1308 *         - Decodes received E2AP control message
1309 *         - Prepares response message, encodes and sends to SCTP
1310 *
1311 * @params[in] 
1312 * @return ROK     - success
1313 *         RFAILED - failure
1314 *
1315 * ****************************************************************/
1316 void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
1317 {
1318    int             i;
1319    char            *recvBuf;
1320    MsgLen          copyCnt;
1321    MsgLen          recvBufLen;
1322    E2AP_PDU_t      *e2apMsg;
1323    asn_dec_rval_t  rval; /* Decoder return value */
1324    E2AP_PDU_t      e2apasnmsg ;
1325  
1326    DU_LOG("\nINFO  -->  E2AP : Received E2AP message buffer");
1327    ODU_PRINT_MSG(mBuf, 0,0);
1328  
1329    /* Copy mBuf into char array to decode it */
1330    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
1331    RIC_ALLOC(recvBuf, (Size)recvBufLen);
1332
1333    if(recvBuf == NULLP)
1334    {
1335       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
1336       return;
1337    }
1338    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
1339    {
1340       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
1341       return;
1342    }
1343
1344    DU_LOG("\nDEBUG  -->  E2AP : Received flat buffer to be decoded : ");
1345    for(i=0; i< recvBufLen; i++)
1346    {
1347         DU_LOG("%x",recvBuf[i]);
1348    }
1349
1350    /* Decoding flat buffer into E2AP messsage */
1351    e2apMsg = &e2apasnmsg;
1352    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
1353
1354    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
1355    RIC_FREE(recvBuf, (Size)recvBufLen);
1356
1357    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
1358    {
1359       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
1360       return;
1361    }
1362    DU_LOG("\n");
1363    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1364
1365    switch(e2apMsg->present)
1366    {
1367       case E2AP_PDU_PR_initiatingMessage:
1368          {
1369             switch(e2apMsg->choice.initiatingMessage->value.present)
1370             {
1371                case InitiatingMessageE2__value_PR_E2setupRequest:
1372                   {
1373                      DU_LOG("\nINFO  -->  E2AP : E2 setup request received");
1374                      ProcE2SetupReq(duId, &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest);
1375                      break;
1376                   }
1377                case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate:
1378                   {
1379                      DU_LOG("\nINFO  -->  E2AP : E2 node config update received");
1380                      BuildAndSendE2NodeConfigUpdateAck(*duId);
1381                      break;
1382                   }
1383                case InitiatingMessageE2__value_PR_ResetRequestE2:
1384                   {
1385                      DU_LOG("\nINFO  -->  E2AP : E2 Reset Request received");
1386                      ProcE2ResetReq(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2);
1387                      break;
1388                   }
1389                case InitiatingMessageE2__value_PR_RICindication:
1390                   {
1391                      DU_LOG("\nINFO  -->  E2AP : RIC Indication Acknowledged");
1392                      break;
1393                   }
1394                default:
1395                   {
1396                      DU_LOG("\nERROR  -->  E2AP : Invalid type of intiating message [%d]",e2apMsg->choice.initiatingMessage->value.present);
1397                      return;
1398                   }
1399             }/* End of switch(initiatingMessage) */
1400             break;
1401          }
1402       case E2AP_PDU_PR_successfulOutcome: 
1403          {
1404             switch(e2apMsg->choice.successfulOutcome->value.present)
1405             {
1406                case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:  
1407                   {
1408                      ProcRicSubscriptionResponse(*duId);
1409                      break;
1410                   }
1411                default:
1412                   {
1413                      DU_LOG("\nERROR  -->  E2AP : Invalid type of successfulOutcome message [%d]",e2apMsg->choice.successfulOutcome->value.present);
1414                      return;
1415                   }
1416                   break;
1417             }
1418             break; 
1419          }
1420       default:
1421          {
1422             DU_LOG("\nERROR  -->  E2AP : Invalid type message type ");
1423             return;
1424          }
1425
1426    }/* End of switch(e2apMsg->present) */
1427 } /* End of E2APMsgHdlr */
1428
1429
1430 /**********************************************************************
1431   End of file
1432  **********************************************************************/