adedf73cd75d8eac4d2f651c375fa8f6d5648e9e
[o-du/l2.git] / src / du_app / du_e2ap_msg_hdl.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
5 #   Licensed under the Apache License, Version 2.0 (the "License");            #
6 #   you may not use this file except in compliance with the License.           #
7 #   You may obtain a copy of the License at                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
11 #   Unless required by applicable law or agreed to in writing, software        #
12 #   distributed under the License is distributed on an "AS IS" BASIS,          #
13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
14 #   See the License for the specific language governing permissions and        #
15 #   limitations under the License.                                             #
16 ################################################################################
17 *******************************************************************************/
18 #include "common_def.h"
19 #include "du_tmr.h"
20 #include "lrg.h"
21 #include "lkw.x"
22 #include "lrg.x"
23 #include "legtp.h"
24 #include "du_app_mac_inf.h"
25 #include "du_app_rlc_inf.h"
26 #include "du_e2ap_mgr.h"
27 #include "du_e2ap_msg_hdl.h"
28 #include "du_cfg.h"
29 #include "du_mgr.h"
30 #include "du_mgr_main.h"
31 #include "du_utils.h"
32 #include "GlobalE2node-gNB-ID.h"
33 #include "ProtocolIE-FieldE2.h"
34 #include "E2setupRequest.h"
35 #include "InitiatingMessageE2.h"
36 #include "SuccessfulOutcomeE2.h"
37 #include "UnsuccessfulOutcomeE2.h"
38 #include "E2AP-PDU.h"
39 #include "odu_common_codec.h"
40 #include "E2nodeComponentInterfaceF1.h"
41 #include "E2setupRequest.h"
42 #include "du_e2_conversions.h"
43
44 /*******************************************************************
45  *
46  * @brief Builds Global gNodeB Params
47  *
48  * @details
49  *
50  *    Function : BuildGlobalgNBId
51  *
52  *    Functionality: Building the Plmn and gNB id
53  *
54  * @params[in] GlobalE2node_gNB_ID_t *gNbId
55  * @return ROK     - success
56  *         RFAILED - failure
57  *
58  ******************************************************************/
59
60 uint8_t BuildGlobalgNBId(GlobalE2node_gNB_ID_t *gNbId)
61 {
62    uint8_t unused = 0;
63    uint8_t byteSize = 4;
64    uint8_t gnbId = 1;
65    uint8_t ret = ROK;
66
67    /* Allocate Buffer size */
68    gNbId->global_gNB_ID.plmn_id.size = 3 * sizeof(uint8_t);
69    gNbId->global_gNB_ID.plmn_id.buf = NULLP;
70    DU_ALLOC(gNbId->global_gNB_ID.plmn_id.buf , gNbId->global_gNB_ID.plmn_id.size);
71    if(gNbId->global_gNB_ID.plmn_id.buf == NULLP)
72    {
73       DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for Plmn buffer");
74       ret = RFAILED;
75    }
76    else
77    {
78       buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
79             gNbId->global_gNB_ID.plmn_id.buf);
80       /* fill gND Id */
81       gNbId->global_gNB_ID.gnb_id.present = GNB_ID_Choice_PR_gnb_ID;
82       /* Allocate Buffer size */
83       gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size = byteSize * sizeof(uint8_t);
84       gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf = NULLP;
85       DU_ALLOC(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf, \
86             gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size);
87       if(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf == NULLP)
88       {
89          DU_LOG("\nERROR  -->  E2AP: Memory allocation failed for gnb buffer");
90          ret = RFAILED;
91       }
92       else
93       {
94          fillBitString(&gNbId->global_gNB_ID.gnb_id.choice.gnb_ID, unused, byteSize, gnbId);
95       }
96    }
97    return ret;
98 }
99
100 /******************************************************************
101  *
102  * @brief Search E2 node component with the help of action type
103  *
104  * @details
105  *
106  *    Function : searchE2NodeComponentInfo 
107  *
108  *    Functionality: Search E2 node component with the help of action type 
109  *
110  * @params[in] uint8_t componentActionType
111  * @return CmLList
112  *
113  * ****************************************************************/
114
115 CmLList *searchE2NodeComponentInfo(InterfaceType interfaceType, uint8_t componentActionType)
116 {
117    E2NodeComponent *e2NodeComponentInfo;
118    CmLList         *node;
119
120    if(duCb.e2apDb.e2NodeComponentList.count)
121    {
122       CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node);
123       while(node)
124       {
125          e2NodeComponentInfo = (E2NodeComponent*)node->node;
126          if((e2NodeComponentInfo->interfaceType == interfaceType) && (e2NodeComponentInfo->componentActionType == componentActionType))
127             break;
128          else
129             node = node->next;
130       }
131    }
132    return node; 
133 }
134 /*******************************************************************
135  *
136  * @brief Builds E2 node config addition list 
137  *
138  * @details
139  *
140  *    Function : BuildE2NodeConfigAddList
141  *
142  *    Functionality: Building E2 node config addition list
143  *
144  * @params[in] E2nodeComponentConfigAddition_List_t *e2NodeAddList 
145  * @return ROK     - success
146  *         RFAILED - failure
147  *
148  ******************************************************************/
149
150 uint8_t BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAddList)
151 {
152    uint8_t arrIdx = 0;
153    CmLList         *node;
154    E2NodeComponent *e2NodeComponentInfo;
155    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItemIe;
156    E2nodeComponentConfigAddition_Item_t *e2NodeAddItem;
157
158    e2NodeAddList->list.count = 1;
159    e2NodeAddList->list.size = e2NodeAddList->list.count * sizeof(E2nodeComponentConfigAddition_ItemIEs_t *);
160    DU_ALLOC(e2NodeAddList->list.array, e2NodeAddList->list.size);
161    if(e2NodeAddList->list.array == NULLP)
162    {
163        DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
164        return RFAILED;
165    }
166
167    for(arrIdx = 0; arrIdx< e2NodeAddList->list.count; arrIdx++)
168    {
169       DU_ALLOC(e2NodeAddList->list.array[arrIdx], sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
170       if(e2NodeAddList->list.array[arrIdx] == NULLP)
171       {
172          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
173          return RFAILED;
174       }
175    }
176    
177    node = searchE2NodeComponentInfo(F1, E2_NODE_COMPONENT_ADD);
178    if(!node)
179    {
180       DU_LOG("\nERROR  --> E2AP : Received e2NodeComponentInfo is null");
181       return RFAILED;
182    }
183    e2NodeComponentInfo = (E2NodeComponent*)node->node;
184    
185    arrIdx = 0;
186    e2NodeAddItemIe = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[arrIdx];
187    e2NodeAddItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition_Item;
188    e2NodeAddItemIe->criticality = CriticalityE2_reject;
189    e2NodeAddItemIe->value.present = E2nodeComponentConfigAddition_ItemIEs__value_PR_E2nodeComponentConfigAddition_Item;
190    e2NodeAddItem = &e2NodeAddItemIe->value.choice.E2nodeComponentConfigAddition_Item;
191    
192    /* E2nodeComponentInterfaceType */
193    e2NodeAddItem->e2nodeComponentInterfaceType = E2nodeComponentInterfaceType_f1;
194
195    /* E2 Node Component Request Part */
196    if(e2NodeComponentInfo->componentRequestPart)
197    {
198       e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.size = e2NodeComponentInfo->reqBufSize ;
199       DU_ALLOC(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\
200             e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.size);
201       if(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf == NULLP)
202       {
203          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
204          return RFAILED;
205       }
206
207       memcpy(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\
208             e2NodeComponentInfo->componentRequestPart, e2NodeAddItem->e2nodeComponentConfiguration.\
209             e2nodeComponentRequestPart.size);
210    }
211    else
212    {
213       DU_LOG("\nERROR  --> E2AP: componentRequestPart is null ");
214       return RFAILED;
215    }
216
217
218    /* E2 Node Component Response Part */
219    if(e2NodeComponentInfo->componentResponsePart)
220    {
221       e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.size = e2NodeComponentInfo->rspBufSize; 
222       DU_ALLOC(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.buf, \
223             e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.size);
224       if(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.buf == NULLP)
225       {
226          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
227          return RFAILED;
228       }
229       memcpy(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.buf, \
230             e2NodeComponentInfo->componentResponsePart, e2NodeAddItem->e2nodeComponentConfiguration.\
231             e2nodeComponentResponsePart.size);
232    }
233    else
234    {
235       DU_LOG("\nERROR  --> E2AP: componentResponsePart is null");
236       return RFAILED;
237    }
238    
239    /* E2 Node Component ID */
240    e2NodeAddItem->e2nodeComponentID.present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1;
241    DU_ALLOC(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\
242    sizeof(E2nodeComponentInterfaceF1_t));
243    if(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1 == NULLP)
244    {
245        DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
246        return RFAILED;
247    }
248    e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t);
249    DU_ALLOC(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
250    e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
251
252    if(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP)
253    {
254       DU_LOG("\nERROR  -->list.  E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__);
255       return RFAILED;
256    }
257    e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[arrIdx]  = e2NodeComponentInfo->componentId;
258    return ROK;
259
260 }
261
262 /*******************************************************************
263  *
264  * @brief De Allocate E2 Setup Request Message
265  *
266  * @details
267  *
268  *    Function : FreeE2SetupReq
269  *
270  *    Functionality: De-Allocating E2 Setup request Message
271  *
272  * @params[in] E2AP_PDU_t *e2apMsg
273  
274  * @return void
275  *
276  * ****************************************************************/
277
278 void FreeE2SetupReq(E2AP_PDU_t *e2apMsg)
279 {
280    uint8_t arrIdx = 0;
281    uint8_t e2NodeAddListIdx =0;
282    E2setupRequest_t *e2SetupReq;
283    E2nodeComponentConfigAddition_List_t *e2NodeAddList;
284    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
285
286    /* De-allocating Memory */
287    if(e2apMsg != NULLP)
288    {
289       if(e2apMsg->choice.initiatingMessage != NULLP)
290       {
291          e2SetupReq = &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest; 
292          if(e2SetupReq->protocolIEs.list.array != NULLP)
293          {
294             for(arrIdx = 0; arrIdx < e2SetupReq->protocolIEs.list.count; arrIdx++)
295             {
296                if(e2SetupReq->protocolIEs.list.array[arrIdx] != NULLP)
297                {
298                   switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
299                   {
300                      case ProtocolIE_IDE2_id_TransactionID:
301                           break;
302                      case ProtocolIE_IDE2_id_GlobalE2node_ID:
303                         {
304                            if(e2SetupReq->protocolIEs.list.array[arrIdx]->\
305                                  value.choice.GlobalE2node_ID.choice.gNB != NULLP)
306                            {
307                               GlobalE2node_gNB_ID_t *gNbId = NULLP;
308                               gNbId = e2SetupReq->protocolIEs.list.array[arrIdx]->\
309                                       value.choice.GlobalE2node_ID.choice.gNB;
310                               if(gNbId->global_gNB_ID.plmn_id.buf != NULLP)
311                               {
312                                  DU_FREE(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf,\
313                                           gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size);
314                                  DU_FREE(gNbId->global_gNB_ID.plmn_id.buf,\
315                                        gNbId->global_gNB_ID.plmn_id.size);
316                               }
317                               DU_FREE(e2SetupReq->protocolIEs.list.array[arrIdx]->value.\
318                                     choice.GlobalE2node_ID.choice.gNB, sizeof(GlobalE2node_gNB_ID_t));
319                            }
320                            break;
321                         }
322                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
323                      {
324                          e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;
325                          if(e2NodeAddList->list.array)
326                          {
327                              for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
328                              {
329                                 e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
330                                 
331                                 /* Free E2 Node Component Request Part */
332                                 DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\
333                                       e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentRequestPart.size);
334                                 
335                                 /* Free E2 Node Component Response Part */
336                                 DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.\
337                                       e2nodeComponentResponsePart.buf, \
338                                       e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration.e2nodeComponentResponsePart.size);
339                                  
340                                  /* Free E2 Node Component ID */
341                                 if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1)
342                                 {
343                                     DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
344                                     e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
345                                     e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
346                                     e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
347                                     DU_FREE(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\
348                                     sizeof(E2nodeComponentInterfaceF1_t));
349                                 }
350                                 DU_FREE(e2NodeAddList->list.array[e2NodeAddListIdx], sizeof(E2nodeComponentConfigAddition_ItemIEs_t));
351                              }
352                              DU_FREE(e2NodeAddList->list.array, e2NodeAddList->list.size);
353                          }
354                          break;
355                      }
356                      default:
357                         DU_LOG("\nERROR  --> E2AP: Invalid event at e2SetupRequet %ld ",\
358                               (e2SetupReq->protocolIEs.list.array[arrIdx]->id));
359                         break;
360                   }
361                   DU_FREE(e2SetupReq->protocolIEs.list.array[arrIdx], sizeof(E2setupRequestIEs_t));
362                }
363             }
364             DU_FREE(e2SetupReq->protocolIEs.list.array, e2SetupReq->protocolIEs.list.size);
365          }
366          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
367       }
368       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
369    }
370 }
371
372 /*******************************************************************
373  *
374  * @brief Builds and Send the E2SetupRequest
375  *
376  * @details
377  *
378  *    Function : BuildAndSendE2SetupReq
379  *
380  * Functionality:Fills the E2SetupRequest
381  *
382  * @return ROK     - success
383  *         RFAILED - failure
384  *
385  ******************************************************************/
386
387 uint8_t BuildAndSendE2SetupReq()
388 {
389    uint8_t arrIdx = 0, elementCnt=0;
390    uint8_t transId = 0, ret = ROK;
391    bool memAllocFailed;
392    E2AP_PDU_t        *e2apMsg = NULLP;
393    E2setupRequest_t  *e2SetupReq = NULLP;
394    asn_enc_rval_t     encRetVal;       /* Encoder return value */
395
396    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup Request\n");
397    do
398    {
399       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
400       if(e2apMsg == NULLP)
401       {
402          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
403          break;
404       }
405       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
406       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
407       if(e2apMsg->choice.initiatingMessage == NULLP)
408       {
409          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
410          break;
411       }
412       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
413       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2setup;
414       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2setupRequest;
415       e2SetupReq = &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest;
416
417       elementCnt = 3;
418       e2SetupReq->protocolIEs.list.count = elementCnt;
419       e2SetupReq->protocolIEs.list.size = elementCnt * sizeof(E2setupRequestIEs_t*);
420
421       /* Initialize the E2Setup members */
422       DU_ALLOC(e2SetupReq->protocolIEs.list.array, \
423             e2SetupReq->protocolIEs.list.size);
424       if(e2SetupReq->protocolIEs.list.array == NULLP)
425       {
426          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
427          break;
428       }
429       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
430       {
431          DU_ALLOC(e2SetupReq->protocolIEs.list.array[arrIdx],\
432                sizeof(E2setupRequestIEs_t));
433          if(e2SetupReq->protocolIEs.list.array[arrIdx] == NULLP)
434          {
435             memAllocFailed = true;
436             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayarrIdx [%d]", arrIdx);
437             break;
438          }
439       }
440       if(memAllocFailed == true)
441          break;
442
443       arrIdx = 0;
444
445       /* TransactionID */
446       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
447       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
448       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
449       transId = assignTransactionId();
450       e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
451
452       arrIdx++;
453       /* GlobalE2node_gNB_ID */
454       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_GlobalE2node_ID;
455       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
456       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_GlobalE2node_ID;
457       e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.present = GlobalE2node_ID_PR_gNB;
458
459       DU_ALLOC(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.\
460             GlobalE2node_ID.choice.gNB, sizeof(GlobalE2node_gNB_ID_t));
461       if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.\
462             GlobalE2node_ID.choice.gNB == NULLP)
463       {
464          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for gNbId");
465          break;
466       }
467       else
468       {
469          ret = BuildGlobalgNBId(e2SetupReq->protocolIEs.list.array[arrIdx]->value.\
470                choice.GlobalE2node_ID.choice.gNB);
471          if(ret != ROK)
472          {
473              DU_LOG("\nERROR  -->  E2AP : Failed to build Global Gnb Id");
474              break;
475          }
476       }
477       
478       arrIdx++;
479       /* E2 Node Component Configuration Addition List */
480       e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition;
481       e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
482       e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_E2nodeComponentConfigAddition_List;
483       if(BuildE2NodeConfigAddList(&(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List))!=ROK)
484       {
485          DU_LOG("\nERROR  -->  E2AP : Failed to E2 Node config addition list");
486          break;
487       }
488
489
490
491       /* Prints the Msg formed */
492       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
493
494       memset(encBuf, 0, ENC_BUF_MAX_LEN);
495       encBufSize = 0;
496       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
497             encBuf);
498       if(encRetVal.encoded == ENCODE_FAIL)
499       {
500          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupRequest structure (at %s)\n",\
501                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
502          break;
503       }
504       else
505       {
506          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2SetupRequest\n");
507 #ifdef DEBUG_ASN_PRINT
508          for(int i=0; i< encBufSize; i++)
509          {
510             printf("%x",encBuf[i]);
511          }
512 #endif
513       }
514       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
515       {
516          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
517       }
518       break;
519    }while(true);
520
521    duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].transactionId = transId;
522    duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
523    
524    FreeE2SetupReq(e2apMsg);
525    return ret;
526 }/* End of BuildAndSendE2SetupReq */
527
528 /*******************************************************************
529  *
530  * @brief Builds Ric Request Id
531  *
532  * @details
533  *
534  *    Function : BuildRicRequestId
535  *
536  *    Functionality: Building the Ric Request Id
537  *
538  * @params[in] RICrequestID_t *ricReqId
539  * @return ROK     - success
540  *         RFAILED - failure
541  *
542  * ****************************************************************/
543
544 uint8_t BuildRicRequestId(RICrequestID_t *ricReqId)
545 {
546    if(ricReqId == NULLP)
547    {
548       return RFAILED;
549    }
550
551    ricReqId->ricRequestorID = 1;
552    ricReqId->ricInstanceID  = 1;
553    return ROK;
554 }
555
556 /*******************************************************************
557  *
558  * @brief Fills the mandatory RicAdmitted List Items
559  *
560  * @details
561  *
562  *    Function : fillRicAdmitList
563  *
564  *    Functionality: Fills the mandatory Ric Admitted List Items
565  *
566  * @params[in] RICaction_Admitted_ItemIEs_t *ricAdmitItems
567  * @return ROK     - success
568  *         RFAILED - failure
569  *
570  * ****************************************************************/
571
572 uint8_t fillRicAdmitList(RICaction_Admitted_ItemIEs_t *ricAdmitItems)
573 {
574
575    if(ricAdmitItems != NULLP)
576    {
577       ricAdmitItems->id = ProtocolIE_IDE2_id_RICaction_Admitted_Item;
578       ricAdmitItems->criticality = CriticalityE2_reject;
579       ricAdmitItems->value.present = RICaction_Admitted_ItemIEs__value_PR_RICaction_Admitted_Item;
580       ricAdmitItems->value.choice.RICaction_Admitted_Item.ricActionID = 1; 
581    }
582    else
583    {
584       return RFAILED;
585    }
586    return ROK;
587 }
588 /*******************************************************************
589  *
590  * @brief Builds the mandatory RicAdmitted List Params
591  *
592  * @details
593  *
594  *    Function : BuildRicAdmitList
595  *
596  *    Functionality: Builds the mandatory Ric Admitted List Params
597  *
598  * @params[in] RICaction_Admitted_List_t *admitListPtr
599  * @return ROK     - success
600  *         RFAILED - failure
601  *
602  * ****************************************************************/
603
604 uint8_t BuildRicAdmitList(RICaction_Admitted_List_t *admitListPtr)
605 {
606    uint8_t idx ;
607    uint8_t elementCnt;  
608    uint8_t ret= ROK;
609    elementCnt = 1;
610
611    if(admitListPtr == NULLP)
612    {
613       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC Admit List failed");
614       ret = RFAILED;
615    }
616    else
617    {
618       admitListPtr->list.count = elementCnt;
619       admitListPtr->list.size  = elementCnt * sizeof(RICaction_Admitted_ItemIEs_t);
620       DU_ALLOC(admitListPtr->list.array, admitListPtr->list.size);
621       if(admitListPtr->list.array == NULLP)
622       {
623          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC Admit List failed");
624          ret = RFAILED;
625       }
626       else
627       {
628          for(idx=0 ; idx<elementCnt ; idx++ )
629          {
630             DU_ALLOC(admitListPtr->list.array[idx], sizeof(RICaction_Admitted_ItemIEs_t));
631             if(admitListPtr->list.array[idx] == NULLP)
632             {
633                ret = RFAILED;
634             }
635          }
636          if(ret != RFAILED)
637          {
638             idx=0;
639             fillRicAdmitList((RICaction_Admitted_ItemIEs_t *)admitListPtr->list.array[idx]);
640          }
641       }
642    }    
643    return ret;
644 }
645 /*******************************************************************
646  *
647  * @breif Deallocation of BuildAndSendRicSubscriptionRsp memory
648  *
649  * @details
650  *
651  *    Function : FreeRicSubscriptionRsp
652  *
653  * Functionality:Free the RicSubscriptionRsp
654  *
655  * @param[in] E2AP_PDU_t *e2apRicMsg
656  *
657  * @return void
658  *      
659  *
660  ******************************************************************/
661 void FreeRicSubscriptionRsp(E2AP_PDU_t  *e2apRicMsg)
662 {
663    RICsubscriptionResponse_t  *ricSubscriptionRsp= NULLP;
664    uint8_t idx=0;
665    uint8_t idx1=0;
666    RICaction_Admitted_List_t *admitListPtr;
667
668    if(e2apRicMsg != NULLP)
669    {
670       if(e2apRicMsg->choice.successfulOutcome != NULLP)
671       {
672          ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
673          if(ricSubscriptionRsp)
674          {
675             if(ricSubscriptionRsp->protocolIEs.list.array != NULLP)
676             {
677                for(idx=0; idx<ricSubscriptionRsp->protocolIEs.list.count; idx++)
678                {
679                   if(ricSubscriptionRsp->protocolIEs.list.array[idx] != NULLP)
680                   {
681                      switch(ricSubscriptionRsp->protocolIEs.list.array[idx]->id)
682                      {
683                         case ProtocolIE_IDE2_id_RICrequestID:
684                            break;
685
686                         case ProtocolIE_IDE2_id_RANfunctionID:
687                            break;
688
689                         case ProtocolIE_IDE2_id_RICactions_Admitted:
690                            {
691                               admitListPtr = &ricSubscriptionRsp->protocolIEs.list.\
692                                              array[idx]->value.choice.RICaction_Admitted_List;
693                               if(admitListPtr->list.array != NULLP)
694                               {
695                                  for(idx1=0 ; idx1<admitListPtr->list.count; idx1++ )
696                                  {
697                                     if(admitListPtr->list.array[idx1] != NULLP)
698                                     {
699                                        DU_FREE(admitListPtr->list.array[idx1],
700                                              sizeof(RICaction_Admitted_ItemIEs_t));
701                                     }
702                                  }
703                                  DU_FREE(admitListPtr->list.array, admitListPtr->list.size);     
704                               }
705                               break;
706                            }
707                         default:
708                            break;
709                      }
710                      DU_FREE(ricSubscriptionRsp->protocolIEs.list.array[idx], \
711                            sizeof(RICsubscriptionResponse_IEs_t));
712                   }
713                }
714                DU_FREE(ricSubscriptionRsp->protocolIEs.list.array, \
715                      ricSubscriptionRsp->protocolIEs.list.size);
716             }
717          }   
718          DU_FREE(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
719       }         
720       DU_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));        
721    }
722 }
723 /*******************************************************************
724  *
725  * @brief Builds and Send the RicSubscriptionRsp
726  *
727  * @details
728  *
729  *    Function : BuildAndSendRicSubscriptionRsp
730  *
731  * functionality:Fills the RicSubscriptionRsp
732  *
733  * @return ROK     - success
734  *         RFAILED - failure
735  *
736  ******************************************************************/
737 uint8_t  FillRicSubscriptionRsp(RICsubscriptionResponse_t  *ricSubscriptionRsp )
738 {
739    uint8_t idx=0;
740    uint8_t ret = ROK;
741    uint8_t elementCnt = 0;
742    uint8_t BuildRicRequestIdret=ROK;
743    uint8_t BuildRicAdmitListret=ROK;
744
745    elementCnt=3;
746    ricSubscriptionRsp->protocolIEs.list.count = elementCnt;
747    ricSubscriptionRsp->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionResponse_IEs_t);
748    DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array, \
749          ricSubscriptionRsp->protocolIEs.list.size);
750    if(ricSubscriptionRsp->protocolIEs.list.array == NULLP)
751    {
752       DU_LOG("\nERROR  -->  E2AP : Memory allocation for FillRicSubscriptionRsp  failed");
753       ret = RFAILED;
754    }
755    else
756    {
757       for(idx=0; idx<ricSubscriptionRsp->protocolIEs.list.count; idx++)
758       {
759          DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array[idx], \
760                sizeof(RICsubscriptionResponse_IEs_t));
761          if(ricSubscriptionRsp->protocolIEs.list.array[idx] == NULLP)
762          {
763             ret = RFAILED;
764          }
765       }
766       if(ret != RFAILED)
767       {
768
769          idx=0;
770          ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
771          ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
772          ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
773                                                                          RICsubscriptionRequest_IEs__value_PR_RICrequestID;
774          BuildRicRequestIdret =
775             BuildRicRequestId(&ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RICrequestID);
776          if(BuildRicRequestIdret != ROK)
777          {
778             ret = RFAILED;
779          }
780          else
781          {
782             idx++;
783             ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
784             ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
785             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
786                                                                             RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
787             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1;
788
789             idx++;
790             ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactions_Admitted;
791             ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
792             ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\
793                                                                             RICsubscriptionResponse_IEs__value_PR_RICaction_Admitted_List;
794             BuildRicAdmitListret =
795                BuildRicAdmitList(&ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RICaction_Admitted_List);
796             if(BuildRicAdmitListret != ROK)
797             {
798                ret = RFAILED;
799             }
800          }
801       }
802    }    
803    return ret;
804 }
805 /*******************************************************************
806  *
807  * @brief Builds and Send the RicSubscriptionRsp
808  *
809  * @details
810  *
811  *    Function : BuildAndSendRicSubscriptionRsp
812  *
813  * Functionality:Fills the RicSubscriptionRsp
814  *
815  * @return ROK     - success
816  *         RFAILED - failure
817  *
818  ******************************************************************/
819
820 uint8_t BuildAndSendRicSubscriptionRsp()
821 {
822
823    E2AP_PDU_t         *e2apRicMsg = NULLP;
824    RICsubscriptionResponse_t  *ricSubscriptionRsp=NULLP;
825    asn_enc_rval_t     encRetVal; 
826    uint8_t ret = RFAILED;
827    uint8_t FillRicricSubscriptionRspret;
828
829    while(true)
830    {
831       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Response\n");
832
833       DU_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t)); 
834       if(e2apRicMsg == NULLP)
835       {
836          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
837          break;
838       }
839       e2apRicMsg->present =  E2AP_PDU_PR_successfulOutcome;
840       DU_ALLOC(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
841       if(e2apRicMsg->choice.successfulOutcome == NULLP)
842       {
843          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RIC subscription Response failed");
844          break;
845       }
846
847       e2apRicMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
848       e2apRicMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
849       e2apRicMsg->choice.successfulOutcome->value.present = \
850                                                             SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse;
851       ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse;
852
853       FillRicricSubscriptionRspret = FillRicSubscriptionRsp(ricSubscriptionRsp);
854       if(FillRicricSubscriptionRspret != ROK)
855       {
856          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICsubscriptionResponseIE failed");
857          break;
858       }
859
860       /* Prints the Msg formed */
861       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
862
863       memset(encBuf, 0, ENC_BUF_MAX_LEN);
864       encBufSize = 0;
865       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\
866             encBuf);
867       if(encRetVal.encoded == ENCODE_FAIL)
868       {
869          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Response structure (at %s)\n",\
870                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
871          break;
872       }
873       else
874       {
875          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for RIC subscription response \n");
876 #ifdef DEBUG_ASN_PRINT
877          for(int i=0; i< encBufSize; i++)
878          {
879             printf("%x",encBuf[i]);
880          } 
881 #endif
882       } 
883
884       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
885       {
886          DU_LOG("\nERROR  -->  E2AP : Sending RIC Subscription Response failed");      
887          break;
888       }
889
890       ret = ROK;
891       break;
892
893    }
894    FreeRicSubscriptionRsp(e2apRicMsg);
895
896    return ret;
897 }
898
899 /******************************************************************
900  *
901  * @brief Deallocation of memory allocated bu aper decoder for e2 setup response
902  *
903  * @details
904  *
905  *    Function : freeAperDecodingOfE2SetupRsp
906  *
907  *    Functionality: Deallocation of memory allocated bu aper decoder for e2
908  *    setup response
909  *
910  * @params[in] E2setupResponse_t *e2SetRspMsg;
911  * @return void
912  *
913  * ****************************************************************/
914 void freeAperDecodingOfE2SetupRsp(E2setupResponse_t *e2SetRspMsg)
915 {
916    uint8_t arrIdx, e2NodeConfigAddAckListIdx;
917    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem;
918    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAddAckList;
919
920    if(e2SetRspMsg)
921    {
922       if(e2SetRspMsg->protocolIEs.list.array)
923       {
924          for(arrIdx=0; arrIdx<e2SetRspMsg->protocolIEs.list.count; arrIdx++)
925          {
926             if(e2SetRspMsg->protocolIEs.list.array[arrIdx])
927             {
928                switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
929                {
930                   case ProtocolIE_IDE2_id_TransactionID:
931                      break;
932
933                   case ProtocolIE_IDE2_id_GlobalRIC_ID:
934                      {
935                         free(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.pLMN_Identity.buf);
936                         free(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID.buf);
937                         break;
938                      }
939
940                   case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
941                      {
942                         e2NodeConfigAddAckList = &e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
943                         if(e2NodeConfigAddAckList->list.array )
944                         {
945                            for(e2NodeConfigAddAckListIdx = 0; e2NodeConfigAddAckListIdx< e2NodeConfigAddAckList->list.count; e2NodeConfigAddAckListIdx++)
946                            {
947                               if(e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx])
948                               {
949                                  e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx];
950                                  free(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.\
951                                        e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf);
952                                  free(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.\
953                                        e2nodeComponentInterfaceTypeF1);
954                                  free(e2NodeConfigAddAckList->list.array[e2NodeConfigAddAckListIdx]);
955                               }
956                            }
957                            free(e2NodeConfigAddAckList->list.array);
958                         }
959                         break;
960                      }
961                }
962                free(e2SetRspMsg->protocolIEs.list.array[arrIdx]);  
963             }
964          }
965          free(e2SetRspMsg->protocolIEs.list.array);
966       }
967    }
968 }
969 /******************************************************************
970  *
971  * @brief Processes E2 Setup Response sent by RIC
972  *
973  * @details
974  *
975  *    Function : procE2SetupRsp
976  *
977  *    Functionality: Processes E2 Setup Response sent by RIC
978  *
979  * @params[in] E2AP_PDU_t ASN decoded E2AP message
980  * @return ROK     - success
981  *         RFAILED - failure
982  *
983  * ****************************************************************/
984 uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg)
985 {
986    uint8_t arrIdx =0, transId=0; 
987    uint32_t recvBufLen;             
988    E2setupResponse_t *e2SetRspMsg;
989    CmLList         *node;
990    E2NodeComponent *e2NodeComponentInfo;
991
992    DU_LOG("\nINFO   -->  E2AP : E2 Setup Response received"); 
993    duCb.e2Status = TRUE; //Set E2 status as true
994    e2SetRspMsg = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
995
996    for(arrIdx=0; arrIdx<e2SetRspMsg->protocolIEs.list.count; arrIdx++)
997    {
998       switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
999       {
1000          case ProtocolIE_IDE2_id_TransactionID:
1001             {
1002                transId = e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
1003                if((duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].transactionId == transId) &&\
1004                      (duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
1005                   memset(&duCb.e2apDb.e2TransInfo.onGoingTransaction[transId], 0, sizeof(E2TransInfo));
1006                else
1007                {
1008                   DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
1009                   return RFAILED;
1010                }
1011                break;
1012             }
1013
1014          case ProtocolIE_IDE2_id_GlobalRIC_ID:
1015             {
1016                /* To store the Ric Id Params */
1017                recvBufLen = sizeof(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value\
1018                      .choice.GlobalRIC_ID.pLMN_Identity.size);
1019                   memcpy(&duCb.e2apDb.ricId.plmnId, e2SetRspMsg->protocolIEs.list.array[arrIdx]\
1020                         ->value.choice.GlobalRIC_ID.pLMN_Identity.buf, recvBufLen);
1021                bitStringToInt(&e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID, &duCb.e2apDb.ricId);
1022                /*TODO : duCb.e2apDb.ricId.plmnId memory to be deallocated after the usage */
1023                break;
1024             }
1025
1026          case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
1027             break;
1028
1029          default:
1030             DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2SetupRsp:%ld",
1031                   e2SetRspMsg->protocolIEs.list.array[arrIdx]->id);
1032             break;
1033       }
1034    }
1035    freeAperDecodingOfE2SetupRsp(e2SetRspMsg);
1036    
1037    node = searchE2NodeComponentInfo(F1, E2_NODE_COMPONENT_ADD);
1038    if(!node)
1039    {
1040       DU_LOG("\nERROR  --> E2AP : Received e2NodeComponentInfo is null");
1041       return RFAILED;
1042    }
1043    else
1044    {
1045       e2NodeComponentInfo = (E2NodeComponent*)node->node;
1046       cmLListDelFrm(&duCb.e2apDb.e2NodeComponentList, node);
1047       DU_FREE(e2NodeComponentInfo->componentRequestPart, e2NodeComponentInfo->reqBufSize);
1048       DU_FREE(e2NodeComponentInfo->componentResponsePart, e2NodeComponentInfo->rspBufSize);
1049       DU_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent));
1050       DU_FREE(node, sizeof(CmLList));
1051    }
1052
1053    BuildAndSendE2NodeConfigUpdate();
1054    return ROK;
1055 }
1056
1057 /******************************************************************
1058  *
1059  * @brief Processes RIC Subscription Req sent by RIC
1060  *
1061  * @details
1062  *
1063  *    Function : procRicSubsReq
1064  *
1065  *    Functionality: Processes E2 Setup Response sent by CU
1066  *
1067  * @params[in] E2AP_PDU_t ASN decoded E2AP message
1068  * @return ROK     - success
1069  *         RFAILED - failure
1070  *
1071  * ****************************************************************/
1072
1073 uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg)
1074 {
1075    uint8_t idx; 
1076    uint8_t ied; 
1077    uint8_t ret = ROK;
1078    CmLList  *ricSubscriptionNode = NULLP;
1079    RICsubscriptionRequest_t *ricSubsReq;
1080    RicSubscription *ricSubscriptionInfo;
1081    RICaction_ToBeSetup_ItemIEs_t *actionItem;
1082
1083    DU_LOG("\nINFO   -->  E2AP : RIC Subscription request received"); 
1084    ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
1085
1086    for(idx=0; idx<ricSubsReq->protocolIEs.list.count; idx++)
1087    {
1088       if(ricSubsReq->protocolIEs.list.array[idx])
1089       {
1090          switch(ricSubsReq->protocolIEs.list.array[idx]->id)
1091          {
1092             case ProtocolIE_IDE2_id_RICrequestID:
1093                {
1094                   /* TODO :- ricSubscriptionInfo details will be stored based on
1095                    * RAN function id, so first we need to search RAN function and then add
1096                    * subscription details to that ran function */
1097                   DU_ALLOC(ricSubscriptionInfo, sizeof(RicSubscription));
1098                   if(!ricSubscriptionInfo)
1099                   {
1100                      DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for ricSubscriptionInfo");
1101                      return RFAILED;
1102                   }
1103                   ricSubscriptionInfo->requestId.requestorId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID;
1104                   ricSubscriptionInfo->requestId.instanceId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID;
1105                   DU_ALLOC(ricSubscriptionNode, sizeof(CmLList));
1106                   if(ricSubscriptionNode)
1107                   {
1108                      ricSubscriptionNode->node = (PTR) ricSubscriptionInfo;
1109                      cmLListAdd2Tail(&duCb.e2apDb.ranFunction[0].subscriptionList,ricSubscriptionNode);
1110                   }
1111                   break;
1112                }
1113             case ProtocolIE_IDE2_id_RANfunctionID:
1114                {
1115                   duCb.e2apDb.ranFunction[0].id = ricSubsReq->protocolIEs.list.array[idx]-> \
1116                                           value.choice.RANfunctionID; 
1117                   break;
1118                }
1119             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
1120                {
1121                   if(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\
1122                         list.array)
1123                   {
1124                      actionItem =(RICaction_ToBeSetup_ItemIEs_t *)ricSubsReq->protocolIEs.list\
1125                                  .array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List\
1126                                  .list.array[0];
1127
1128                      for(ied = 0; ied < ricSubsReq->protocolIEs.list.array[idx]->value.choice.\
1129                            RICsubscriptionDetails.ricAction_ToBeSetup_List.list.count; ied++)
1130                      {
1131                         switch(actionItem->id)
1132                         {
1133                            case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item:
1134                               {
1135                                  ricSubscriptionInfo->actionSequence[0].id  = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
1136                                  ricSubscriptionInfo->actionSequence[0].type = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType;
1137                                  break;
1138                               }
1139                            default:
1140                               DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id);
1141                               break;
1142                         }
1143                         free(actionItem);
1144                      }
1145                      free(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\
1146                            list.array);
1147                   }
1148                   break;
1149                }
1150
1151             default:
1152                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RIC SubsReq:%ld",
1153                      ricSubsReq->protocolIEs.list.array[idx]->id);
1154                break;
1155          }
1156          free(ricSubsReq->protocolIEs.list.array[idx]);
1157       }
1158    }
1159    free(ricSubsReq->protocolIEs.list.array);
1160    ret = BuildAndSendRicSubscriptionRsp();
1161    {
1162       BuildAndSendRicIndication(ricSubscriptionInfo);
1163    }
1164
1165    return ret;
1166 }
1167
1168 /*******************************************************************
1169  *
1170  * @brief Free the RicIndication Message
1171  *
1172  * @details
1173  *
1174  *    Function : FreeRicIndication
1175  *
1176  * Functionality: Free the RicIndication Message
1177  *
1178  * @return void
1179  *         
1180  *
1181  ******************************************************************/
1182 void FreeRicIndication(E2AP_PDU_t  *e2apMsg) 
1183 {
1184    uint8_t idx=0;
1185    RICindication_t *ricIndicationMsg= NULLP;
1186
1187
1188    if(e2apMsg != NULLP)
1189    {
1190       if(e2apMsg->choice.initiatingMessage != NULLP)
1191       {
1192          ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
1193          if(ricIndicationMsg!= NULLP)
1194          {
1195             if(ricIndicationMsg->protocolIEs.list.array != NULLP)
1196             {
1197                for(idx=0; idx<ricIndicationMsg->protocolIEs.list.count; idx++)
1198                {
1199                   if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP)
1200                   {
1201                      switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
1202                      {
1203                         case ProtocolIE_IDE2_id_RICrequestID:
1204                            break;
1205
1206                         case ProtocolIE_IDE2_id_RANfunctionID:
1207                            break;
1208
1209                         case ProtocolIE_IDE2_id_RICactionID:
1210                            break;
1211
1212                         case ProtocolIE_IDE2_id_RICindicationType:
1213                            break;
1214
1215                         case ProtocolIE_IDE2_id_RICindicationHeader:
1216                            {
1217                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\
1218                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
1219                               break;
1220                            }
1221                         case ProtocolIE_IDE2_id_RICindicationMessage:
1222                            {
1223                               DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\
1224                                     ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
1225                               break;
1226                            }
1227                         default:
1228                            break;
1229                      }
1230                      DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t));
1231                   }
1232                }
1233                DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size);
1234             }
1235          }
1236          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1237       }
1238       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1239    }
1240 }
1241 /*******************************************************************
1242  *
1243  * brief Fill the RicIndication Message
1244  *
1245  * @details
1246  *
1247  *    Function : FillRicIndication
1248  *
1249  * Functionality:Fills the RicIndication Message
1250  *
1251  * @return ROK     - success
1252  *         RFAILED - failure
1253  *
1254  ******************************************************************/
1255 uint8_t FillRicIndication(RICindication_t *ricIndicationMsg, RicSubscription *ricSubscriptionInfo)
1256 {
1257    uint8_t elementCnt=0;
1258    uint8_t idx=0;
1259    uint8_t ret = ROK;
1260    elementCnt = 6;
1261
1262    ricIndicationMsg->protocolIEs.list.count = elementCnt;
1263    ricIndicationMsg->protocolIEs.list.size  = elementCnt * sizeof(RICindication_t);
1264    /* Initialize the Ric Indication members */
1265    DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, \
1266          ricIndicationMsg->protocolIEs.list.size);
1267    if(ricIndicationMsg->protocolIEs.list.array == NULLP)
1268    {
1269       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1270       ret = RFAILED;
1271    }
1272    else
1273    {
1274       for(idx=0; idx<elementCnt; idx++)
1275       {
1276          DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx],\
1277                sizeof(RICindication_IEs_t));
1278          if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
1279          {
1280             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1281             ret = RFAILED;
1282          }
1283       }
1284       if(ret != RFAILED)
1285       {
1286          idx = 0;
1287
1288          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
1289          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1290          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1291                                                                         RICindication_IEs__value_PR_RICrequestID;
1292          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID =ricSubscriptionInfo->requestId.requestorId;
1293          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID = ricSubscriptionInfo->requestId.instanceId;
1294
1295          idx++;
1296          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
1297          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1298          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1299                                                                         RICindication_IEs__value_PR_RANfunctionID;
1300          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = duCb.e2apDb.ranFunction[0].id;
1301
1302          idx++;
1303          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
1304          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1305          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1306                                                                         RICindication_IEs__value_PR_RICactionID;
1307          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = ricSubscriptionInfo->actionSequence[0].id;
1308
1309          idx++;
1310          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
1311          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1312          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1313                                                                         RICindication_IEs__value_PR_RICindicationType;
1314          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = ricSubscriptionInfo->actionSequence[0].type;
1315
1316          idx++;
1317          ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
1318          ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1319          ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1320                                                                         RICindication_IEs__value_PR_RICindicationHeader;
1321          ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size = 3 *
1322             sizeof(uint8_t);
1323          DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf ,\
1324                ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
1325          if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf == NULLP)
1326          {
1327             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1328             ret = RFAILED;
1329          }
1330          else
1331          {
1332             buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
1333                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf);
1334             idx++;
1335             /* TO BE CHANGED: RIC INDICATION DATA */
1336             /* For now filling a dummy octect data, need to tested with PRBs*/
1337             ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
1338             ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1339             ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
1340                                                                            RICindication_IEs__value_PR_RICindicationMessage;
1341             ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size = 3 *
1342                sizeof(uint8_t);
1343             DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf ,\
1344                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
1345             if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf == NULLP)
1346             {
1347                DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICindicationIEs failed");
1348                ret = RFAILED;
1349             }
1350             else
1351             {
1352                buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
1353                      ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf);
1354             }
1355          }
1356       }
1357    }
1358    return ret;
1359 }
1360
1361 /*******************************************************************
1362  *
1363  * @brief Builds and Send the RicIndication Message
1364  *
1365  * @details
1366  *
1367  *    Function : BuildAndSendRicIndication
1368  *
1369  * Functionality:Fills the RicIndication Message
1370  *
1371  * @return ROK     - success
1372  *         RFAILED - failure
1373  *
1374  ******************************************************************/
1375
1376 uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo)
1377 {
1378    E2AP_PDU_t                 *e2apMsg = NULLP;
1379    RICindication_t            *ricIndicationMsg=NULLP;
1380    asn_enc_rval_t             encRetVal;        /* Encoder return value */
1381    uint8_t ret = RFAILED; 
1382    uint8_t FillRicIndicationret = ROK;
1383
1384    while(true)
1385    {
1386       DU_LOG("\nINFO   -->  E2AP : Building RIC Indication Message\n");
1387
1388       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1389       if(e2apMsg == NULLP)
1390       {
1391          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1392          break;
1393       }
1394
1395       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
1396       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1397       if(e2apMsg->choice.initiatingMessage == NULLP)
1398       {
1399          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1400          break;
1401       }
1402       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
1403       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
1404       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication;
1405
1406       ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
1407
1408       FillRicIndicationret = FillRicIndication(ricIndicationMsg, ricSubscriptionInfo);
1409       if(FillRicIndicationret != ROK)
1410       {
1411          break;
1412       }
1413       /* Prints the Msg formed */
1414       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1415       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1416       encBufSize = 0;
1417       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
1418             encBuf);
1419       if(encRetVal.encoded == ENCODE_FAIL)
1420       {
1421          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Indication Message (at %s)\n",\
1422                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1423          break;
1424       }
1425       else
1426       {
1427          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Indication Message \n");
1428 #ifdef DEBUG_ASN_PRINT
1429          for(int i=0; i< encBufSize; i++)
1430          {
1431             printf("%x",encBuf[i]);
1432          } 
1433 #endif
1434       }
1435
1436       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
1437       {
1438          DU_LOG("\nINFO   -->  E2AP : Sending RIC Indication Message");      
1439
1440       }
1441       ret = ROK;
1442       break;
1443    }
1444    FreeRicIndication(e2apMsg);  
1445    return ret;
1446 }
1447
1448 /*******************************************************************
1449  *
1450  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
1451  *
1452  * @details
1453  *
1454  *    Function : FreeE2NodeConfigUpdate 
1455  *
1456  *    Functionality:
1457  *       - freeing the memory allocated for E2nodeConfigurationUpdate
1458  *
1459  * @params[in] E2AP_PDU_t *e2apMsg 
1460  * @return ROK     - success
1461  *         RFAILED - failure
1462  *
1463  * ****************************************************************/
1464 void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg)
1465 {
1466    uint8_t arrIdx =0;
1467    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate;
1468
1469    if(e2apMsg != NULLP)
1470    {
1471       if(e2apMsg->choice.initiatingMessage != NULLP)
1472       {
1473          e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
1474          if(e2NodeConfigUpdate->protocolIEs.list.array != NULLP)
1475          {
1476             for(arrIdx = 0; arrIdx < e2NodeConfigUpdate->protocolIEs.list.count; arrIdx++)
1477             {
1478                DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
1479             }
1480             DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size);
1481          }
1482          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1483       }
1484       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1485    }
1486 }
1487
1488 /*******************************************************************
1489  *
1490  * @brief Buld and send the E2 node config update msg 
1491  *
1492  * @details
1493  *
1494  *    Function : BuildAndSendE2NodeConfigUpdate
1495  *
1496  *    Functionality:
1497  *         - Buld and send the E2 node config update msg
1498  *
1499  * @params[in] 
1500  * @return ROK     - success
1501  *         RFAILED - failure
1502  *
1503  * ****************************************************************/
1504
1505 uint8_t BuildAndSendE2NodeConfigUpdate()
1506 {
1507    uint8_t arrIdx = 0,elementCnt = 1;
1508    uint8_t ret = ROK;
1509    E2AP_PDU_t        *e2apMsg = NULLP;
1510    E2nodeConfigurationUpdate_t *e2NodeConfigUpdate = NULLP;
1511    asn_enc_rval_t     encRetVal;       /* Encoder return value */
1512
1513    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update\n");
1514    do
1515    {
1516       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1517       if(e2apMsg == NULLP)
1518       {
1519          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1520          break;
1521       }
1522       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
1523       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1524       if(e2apMsg->choice.initiatingMessage == NULLP)
1525       {
1526          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1527          DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1528          return RFAILED;
1529       }
1530       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
1531       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
1532       e2apMsg->choice.initiatingMessage->value.present = \
1533       InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate;
1534       e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate;
1535
1536       e2NodeConfigUpdate->protocolIEs.list.count = elementCnt;
1537       e2NodeConfigUpdate->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdate_IEs_t*);
1538       /* Initialize the Ric Indication members */
1539       DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array, \
1540             e2NodeConfigUpdate->protocolIEs.list.size);
1541       if(e2NodeConfigUpdate->protocolIEs.list.array == NULLP)
1542       {
1543          DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
1544          break;
1545       }
1546       
1547       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
1548       {
1549          DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t));
1550          if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx] == NULLP)
1551          {
1552             
1553             DU_LOG("\nERROR  -->  E2AP : Memory allocation for e2NodeConfigUpdate failed");
1554             break;
1555          }
1556       }
1557
1558       arrIdx = 0;
1559       /* TransactionID */
1560       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
1561       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1562       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_TransactionID;
1563       e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = TRANS_ID;
1564
1565
1566       /* Prints the Msg formed */
1567       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1568
1569       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1570       encBufSize = 0;
1571       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
1572             encBuf);
1573       if(encRetVal.encoded == ENCODE_FAIL)
1574       {
1575          DU_LOG("\nERROR  -->  E2AP : Could not encode E2nodeConfigurationUpdate structure (at %s)\n",\
1576                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1577          break;
1578       }
1579       else
1580       {
1581          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2nodeConfigurationUpdate\n");
1582 #ifdef DEBUG_ASN_PRINT
1583          for(int i=0; i< encBufSize; i++)
1584          {
1585             printf("%x",encBuf[i]);
1586          }
1587 #endif
1588       }
1589       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize))
1590       {
1591          DU_LOG("\nERROR  -->  E2AP : Sending E2 node config update failed");
1592          return RFAILED;
1593       }
1594
1595       break;
1596    }while(true);
1597    
1598    FreeE2NodeConfigUpdate(e2apMsg);
1599    return ret;
1600 }
1601
1602 /*******************************************************************
1603  *
1604  * @brief Deallocate the memory allocated for E2ResetRequest msg
1605  *
1606  * @details
1607  *
1608  *    Function : FreeE2ResetRequest
1609  *
1610  *    Functionality:
1611  *       - freeing the memory allocated for E2ResetRequest
1612  *
1613  * @params[in] E2AP_PDU_t *e2apMsg
1614  * @return ROK     - success
1615  *         RFAILED - failure
1616  *
1617  * ****************************************************************/
1618 void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg)
1619 {
1620    uint8_t ieIdx =0;
1621    ResetRequestE2_t  *resetReq = NULLP;
1622
1623    if(e2apMsg != NULLP)
1624    {
1625       if(e2apMsg->choice.initiatingMessage != NULLP)
1626       {
1627          resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
1628          if(resetReq->protocolIEs.list.array)
1629          {
1630             for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
1631             {
1632                DU_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
1633             }
1634             DU_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
1635          }
1636          DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1637       }
1638       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1639    }
1640 }
1641
1642 /*******************************************************************
1643  *
1644  * @brief Build and send the E2 reset request msg
1645  *
1646  * @details
1647  *
1648  *    Function : BuildAndSendE2ResetRequest
1649  *
1650  *    Functionality:
1651  *         - Buld and send the E2 reset request msg to RIC
1652  *
1653  * @params[in]
1654  * @return ROK     - success
1655  *         RFAILED - failure
1656  *
1657  * ****************************************************************/
1658 uint8_t BuildAndSendE2ResetRequest(E2CauseType failureType, E2Cause failureCause)
1659 {
1660    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
1661    uint8_t ret = RFAILED;
1662    E2AP_PDU_t        *e2apMsg = NULLP;
1663    ResetRequestE2_t  *resetReq = NULLP;
1664    asn_enc_rval_t     encRetVal;       /* Encoder return value */
1665
1666    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Request\n");
1667
1668    do
1669    {
1670       DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1671       if(e2apMsg == NULLP)
1672       {
1673          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for E2AP-PDU failed");
1674          break;
1675       }
1676
1677       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
1678       DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1679       if(e2apMsg->choice.initiatingMessage == NULLP)
1680       {
1681          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation for initiatingMessage");
1682          break;
1683       }
1684
1685       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
1686       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
1687       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
1688       resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
1689
1690       elementCnt = 2;
1691       resetReq->protocolIEs.list.count = elementCnt;
1692       resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
1693
1694       DU_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
1695       if(!resetReq->protocolIEs.list.array)
1696       {
1697          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
1698             Reset Request IE array");
1699          break;
1700       }
1701
1702       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
1703       {
1704          DU_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
1705          if(!resetReq->protocolIEs.list.array[ieIdx])
1706          {
1707             DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \
1708             Reset Request IE array element");
1709             break;
1710          }
1711       }
1712
1713       /* In case of failure */
1714       if(ieIdx < elementCnt)
1715          break;
1716
1717       ieIdx = 0;
1718       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
1719       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
1720       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
1721       transId = assignTransactionId();
1722       resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
1723
1724       ieIdx++;
1725       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
1726       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
1727       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
1728       resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present = failureType;
1729       switch(resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present)
1730       {
1731          case CauseE2_PR_NOTHING:
1732             break;
1733          case CauseE2_PR_ricRequest:
1734             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricRequest = failureCause;
1735             break;
1736          case CauseE2_PR_ricService:
1737             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricService = failureCause;
1738             break;
1739          case CauseE2_PR_e2Node:
1740             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.e2Node = failureCause;
1741             break;
1742          case CauseE2_PR_transport:
1743             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.transport = failureCause;
1744             break;
1745          case CauseE2_PR_protocol:
1746             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.protocol = failureCause;
1747             break;
1748          case CauseE2_PR_misc:
1749             resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.misc = failureCause;
1750             break;
1751       }
1752
1753       /* Prints the Msg formed */
1754       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1755
1756       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1757       encBufSize = 0;
1758       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
1759             encBuf);
1760       if(encRetVal.encoded == ENCODE_FAIL)
1761       {
1762          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupRequest structure (at %s)\n",\
1763                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1764          break;
1765       }
1766       else
1767       {
1768          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for E2SetupRequest\n");
1769 #ifdef DEBUG_ASN_PRINT
1770          for(int i=0; i< encBufSize; i++)
1771          {
1772             printf("%x",encBuf[i]);
1773          }
1774 #endif
1775       }
1776       if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
1777       {
1778          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
1779          break;
1780       }
1781
1782       /* In case the message is sent successfully, store the transaction info to
1783        * be used when response is received */
1784       duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].transactionId = transId;
1785       duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
1786
1787       ret = ROK;
1788       break;
1789    }while(true);
1790
1791    /* Free all memory */
1792    FreeE2ResetRequest(e2apMsg);
1793    return ret;
1794 }
1795
1796 /*******************************************************************
1797  *
1798  * @brief Deallocate the memory allocated for Reset Response msg
1799  *
1800  * @details
1801  *
1802  *    Function : freeAperDecodingOfE2ResetRsp
1803  *
1804  *    Functionality:
1805  *       - freeing the memory allocated for Reset response
1806  *
1807  * @params[in] ResetResponseE2_t *resetResponse
1808  * @return void
1809  *
1810  * ****************************************************************/
1811 void freeAperDecodingOfE2ResetRsp(ResetResponseE2_t *resetResponse)
1812 {
1813    uint8_t ieIdx;
1814
1815    if(resetResponse)
1816    {
1817       if(resetResponse->protocolIEs.list.array)
1818       {
1819          for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
1820          {
1821             if(resetResponse->protocolIEs.list.array[ieIdx])
1822             {
1823                switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
1824                {
1825                   case ProtocolIE_IDE2_id_TransactionID:
1826                      break;
1827
1828                   case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
1829                      break;
1830                }
1831                free(resetResponse->protocolIEs.list.array[ieIdx]);
1832             }
1833          }
1834          free(resetResponse->protocolIEs.list.array);
1835       }
1836    }
1837 }
1838
1839 /******************************************************************
1840  *
1841  * @brief Processes E2 Reset Response sent by RIC
1842  *
1843  * @details
1844  *
1845  *    Function : procResetResponse
1846  *
1847  *    Functionality: Processes E2 Reset Response sent by RIC
1848  *
1849  * @params[in] E2AP_PDU_t ASN decoded E2AP message
1850  * @return ROK     - success
1851  *         RFAILED - failure
1852  *
1853  * ****************************************************************/
1854 uint8_t procResetResponse(E2AP_PDU_t *e2apMsg)
1855 {
1856    uint8_t ieIdx =0, transId;
1857    ResetResponseE2_t *resetResponse;
1858
1859    DU_LOG("\nINFO   -->  E2AP : E2 Reset Response received");
1860    resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;;
1861
1862    for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
1863    {
1864       switch(resetResponse->protocolIEs.list.array[ieIdx]->id)
1865       {
1866          case ProtocolIE_IDE2_id_TransactionID:
1867             transId = resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
1868             if((duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].transactionId == transId) && \
1869                   (duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
1870               memset(&duCb.e2apDb.e2TransInfo.onGoingTransaction[transId], 0, sizeof(E2TransInfo));
1871             else
1872             {
1873                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
1874                return RFAILED;
1875             }
1876             break;
1877          case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
1878             /* As per ORAN WG3 E2AP spec v3.0, section 9.2.2
1879                Criticality Diagnostics IE is sent by Near-RT RIC when parts of a received message i.e. 
1880                Reset Request in this case, have not been comprehended or were missing, or if the message 
1881                contained logical errors.
1882
1883                Processing of this ID should be implemented when negative call flows are to be supported.
1884              */
1885             break;
1886          default:
1887             DU_LOG("\nERROR  -->  E2AP : Invalid IE received in E2 Reset Response : %ld",
1888                   resetResponse->protocolIEs.list.array[ieIdx]->id);
1889             break;
1890       }
1891    }
1892
1893    freeAperDecodingOfE2ResetRsp(resetResponse);
1894    return ROK;
1895 }
1896
1897 /******************************************************************
1898  *
1899  * @brief Deallocation of memory allocated bu aper decoder for e2 setup Failure
1900  *
1901  * @details
1902  *
1903  *    Function : freeAperDecodingOfE2SetupFailure
1904  *
1905  *    Functionality: Deallocation of memory allocated bu aper decoder for e2
1906  *    setup Failure
1907  *
1908  * @params[in] E2setupFailure_t *e2SetupFailure;
1909  * @return void
1910  *
1911  * ****************************************************************/
1912 void freeAperDecodingOfE2SetupFailure(E2setupFailure_t *e2SetupFailure)
1913 {
1914    uint8_t arrIdx;
1915
1916    if(e2SetupFailure)
1917    {
1918       if(e2SetupFailure->protocolIEs.list.array)
1919       {
1920          for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
1921          {
1922             if(e2SetupFailure->protocolIEs.list.array[arrIdx])
1923             {
1924                free(e2SetupFailure->protocolIEs.list.array[arrIdx]);  
1925             }
1926          }
1927          free(e2SetupFailure->protocolIEs.list.array);
1928       }
1929    }
1930 }
1931 /******************************************************************
1932  *
1933  * @brief Processes E2 Setup Failure sent by RIC
1934  *
1935  * @details
1936  *
1937  *    Function : procE2SetupFailure
1938  *
1939  *    Functionality: Processes E2 Setup failure sent by RIC
1940  *
1941  * @params[in] E2AP_PDU_t ASN decoded E2AP message
1942  * @return ROK     - success
1943  *         RFAILED - failure
1944  *
1945  * ****************************************************************/
1946 void procE2SetupFailure(E2AP_PDU_t *e2apMsg)
1947 {
1948    uint8_t arrIdx =0, transId =0, timerValue=0; 
1949    E2setupFailure_t *e2SetupFailure;
1950
1951    DU_LOG("\nINFO   -->  E2AP : E2 Setup failure received"); 
1952    e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
1953
1954    for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
1955    {
1956       switch(e2SetupFailure->protocolIEs.list.array[arrIdx]->id)
1957       {
1958          case ProtocolIE_IDE2_id_TransactionID:
1959          {
1960             transId = e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
1961             if((duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].transactionId == transId) &&\
1962             (duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
1963               memset(&duCb.e2apDb.e2TransInfo.onGoingTransaction[transId], 0, sizeof(E2TransInfo));
1964             else
1965             {
1966                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
1967                return ;
1968             }
1969             break;
1970          }
1971          case ProtocolIE_IDE2_id_TimeToWaitE2:
1972             {
1973                timerValue = covertE2WaitTimerEnumToValue(e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
1974                if((duChkTmr((PTR)&(duCb.e2apDb), EVENT_E2_SETUP_TMR)) == FALSE)
1975                {
1976                   duStartTmr((PTR)&(duCb.e2apDb), EVENT_E2_SETUP_TMR, timerValue);
1977                }
1978                else
1979                {
1980                   DU_LOG("\nERROR   -->  E2AP : EVENT_E2_SETUP_TMR timer is already running");
1981                   return;
1982                }
1983                break; 
1984             }
1985       }
1986    }
1987
1988    freeAperDecodingOfE2SetupFailure(e2SetupFailure);
1989 }
1990 /*******************************************************************
1991  *
1992  * @brief Handles received E2AP message and sends back response  
1993  *
1994  * @details
1995  *
1996  *    Function : E2APMsgHdlr
1997  *
1998  *    Functionality:
1999  *         - Decodes received E2AP control message
2000  *         - Prepares response message, encodes and sends to SCTP
2001  *
2002  * @params[in] 
2003  * @return ROK     - success
2004  *         RFAILED - failure
2005  *
2006  * ****************************************************************/
2007 void E2APMsgHdlr(Buffer *mBuf)
2008 {
2009    int i =0;
2010    char *recvBuf = NULLP;
2011    MsgLen copyCnt =0;
2012    MsgLen recvBufLen =0;
2013    E2AP_PDU_t *e2apMsg = NULLP;
2014    asn_dec_rval_t rval ={0}; /* Decoder return value */
2015    E2AP_PDU_t e2apasnmsg={0} ;
2016
2017    DU_LOG("\nDEBUG   -->  E2AP : Received E2AP message buffer");
2018    ODU_PRINT_MSG(mBuf, 0,0);
2019
2020    /* Copy mBuf into char array to decode it */
2021    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
2022    DU_ALLOC(recvBuf, (Size)recvBufLen);
2023
2024    if(recvBuf == NULLP)
2025    {
2026       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
2027       return;
2028    }
2029    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
2030    {
2031       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
2032       return;
2033    }
2034
2035 #ifdef DEBUG_ASN_PRINT
2036    printf("\nDEBUG   -->  E2AP : Received flat buffer to be decoded : ");
2037    for(i=0; i< recvBufLen; i++)
2038    {
2039       printf("%x",recvBuf[i]);
2040    }
2041 #endif
2042
2043    /* Decoding flat buffer into E2AP messsage */
2044    e2apMsg = &e2apasnmsg;
2045    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
2046
2047    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
2048    DU_FREE(recvBuf, (Size)recvBufLen);
2049
2050    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
2051    {
2052       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
2053       return;
2054    }
2055    printf("\n");
2056    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2057
2058    switch(e2apMsg->present)
2059    {
2060       case E2AP_PDU_PR_unsuccessfulOutcome:
2061          {
2062             switch(e2apMsg->choice.unsuccessfulOutcome->value.present)
2063             {
2064                case UnsuccessfulOutcomeE2__value_PR_E2setupFailure:
2065                   {
2066                      procE2SetupFailure(e2apMsg);
2067                      break;
2068                   }
2069                default:
2070                   {
2071                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome  [%d]",\
2072                            e2apMsg->choice.unsuccessfulOutcome->value.present);
2073                      return;
2074                   }
2075             }
2076             break;
2077          }
2078       case E2AP_PDU_PR_successfulOutcome:
2079          {
2080             switch(e2apMsg->choice.successfulOutcome->value.present)
2081             {
2082                case SuccessfulOutcomeE2__value_PR_E2setupResponse:
2083                   {
2084                      if(!duCb.e2Status)
2085                      {
2086                         procE2SetupRsp(e2apMsg);
2087                      }
2088                      break;
2089                   }
2090                case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge:
2091                   {
2092                      DU_LOG("\nDEBUG   -->  E2AP : E2 node Config update ack message recevied");
2093                      break;
2094                   }
2095                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
2096                   {
2097                      procResetResponse(e2apMsg);
2098                      break;
2099                   }
2100                default:
2101                   {
2102                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome  [%d]",\
2103                            e2apMsg->choice.successfulOutcome->value.present);
2104                      return;
2105                   }
2106             }/* End of switch(successfulOutcome) */
2107             free(e2apMsg->choice.successfulOutcome);
2108             break;
2109          }
2110
2111       case E2AP_PDU_PR_initiatingMessage:
2112          {
2113             switch(e2apMsg->choice.initiatingMessage->value.present)
2114             {
2115                case InitiatingMessageE2__value_PR_RICsubscriptionRequest: 
2116                   {
2117                      procRicSubsReq(e2apMsg);
2118                      break;
2119                   }
2120                default:
2121                   {
2122                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\
2123                            e2apMsg->choice.initiatingMessage->value.present);
2124                      return;
2125                   }
2126             }/* End of switch(initiatingMessage) */
2127             free(e2apMsg->choice.initiatingMessage);
2128             break;
2129          }
2130       default:
2131          {
2132             DU_LOG("\nERROR  -->  E2AP : Invalid type of e2apMsg->present [%d]",e2apMsg->present);
2133             return;
2134          }
2135          free(e2apMsg);
2136
2137    }/* End of switch(e2apMsg->present) */
2138
2139 } /* End of E2APMsgHdlr */
2140
2141 /**********************************************************************
2142   End of file
2143  **********************************************************************/