0ee331cc7d85cbfefcf1e4457b675f7c277a94fa
[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 #include "E2SM-KPM-RANfunction-Description.h"
36 #include "RANfunction-Name.h"
37 #include "RIC-EventTriggerStyle-Item.h"
38 #include "RIC-ReportStyle-Item.h"
39 #include "MeasurementInfo-Action-Item.h"
40 #include "MeasurementInfoItem.h"
41 #include "E2SM-KPM-ActionDefinition-Format1.h"
42 #include "E2SM-KPM-ActionDefinition.h"
43 #include "E2SM-KPM-EventTriggerDefinition-Format1.h"
44 #include "E2SM-KPM-EventTriggerDefinition.h"
45
46
47 /*******************************************************************
48  *
49  * @brief Assigns new transaction id to RIC initiated procedure
50  *
51  * @details
52  *
53  *    Function : assignTransactionId
54  *
55  *    Functionality: Assigns new transaction id to a RIC initiated
56  *       procedure
57  *
58  * @params[in] Region region
59  *             Pool pool
60  * @return ROK     - success
61  *         RFAILED - failure
62  *
63  * ****************************************************************/
64
65 uint8_t assignTransactionId(DuDb *duDb)
66 {
67    uint8_t currTransId = duDb->ricTransIdCounter;
68
69    /* Update to next valid value */
70    duDb->ricTransIdCounter++;
71    if(duDb->ricTransIdCounter == MAX_NUM_TRANSACTION)
72       duDb->ricTransIdCounter = 0;
73
74    return currTransId;
75 }
76
77 /*******************************************************************
78 *
79 * @brief Sends E2 msg over SCTP
80 *
81 * @details
82 *
83 *    Function : SendE2APMsg
84 *
85 *    Functionality: Sends E2 msg over SCTP
86 *
87 * @params[in] Region region
88 *             Pool pool
89 * @return ROK     - success
90 *         RFAILED - failure
91 *
92 * ****************************************************************/
93
94 uint8_t SendE2APMsg(Region region, Pool pool, uint32_t duId)
95 {
96    Buffer *mBuf;
97
98    if(ODU_GET_MSG_BUF(region, pool, &mBuf) == ROK)
99    {
100       if(ODU_ADD_POST_MSG_MULT((Data *)encBuf, encBufSize, mBuf) == ROK)
101       {
102          ODU_PRINT_MSG(mBuf, 0,0);
103
104          if(sctpSend(duId, mBuf) != ROK)
105          {
106             DU_LOG("\nERROR  -->  E2AP : SCTP Send for E2  failed");
107             ODU_PUT_MSG_BUF(mBuf);
108             return RFAILED;
109          }
110       }
111       else
112       {
113          DU_LOG("\nERROR  -->  E2AP : ODU_ADD_POST_MSG_MULT failed");
114          ODU_PUT_MSG_BUF(mBuf);
115          return RFAILED;
116       }
117       ODU_PUT_MSG_BUF(mBuf);
118    }
119    else
120    {
121       DU_LOG("\nERROR  -->  E2AP : Failed to allocate memory");
122       return RFAILED;
123    }
124
125    return ROK;
126 } /* SendE2APMsg */
127
128 /*******************************************************************
129  *
130  * @brief deallocate memory allocated in E2 Node Config Update Failure
131  *
132  * @details
133  *
134  *    Function : FreeE2ConfigUpdateFail
135  *
136  *    Functionality: deallocate memory allocated in E2 Node Config Update Failure
137  *
138  * @params[in] E2AP_PDU_t *e2apMsg
139  *
140  * @return void
141  * ****************************************************************/
142
143 void FreeE2ConfigUpdateFail(E2AP_PDU_t *e2apMsg)
144 {
145    uint8_t arrIdx = 0;
146    E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdFail=NULL;
147
148    if(e2apMsg)
149    {
150       if(e2apMsg->choice.unsuccessfulOutcome)
151       {
152          e2NodeCfgUpdFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2nodeConfigurationUpdateFailure;
153          if(e2NodeCfgUpdFail->protocolIEs.list.array)
154          {
155             for(arrIdx=0; arrIdx<e2NodeCfgUpdFail->protocolIEs.list.count; arrIdx++)
156             {
157                RIC_FREE(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateFailure_IEs_t));
158             }
159             RIC_FREE(e2NodeCfgUpdFail->protocolIEs.list.array, e2NodeCfgUpdFail->protocolIEs.list.size);
160          }
161          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
162       }
163       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
164    }
165 }
166
167 /*******************************************************************
168  *
169  * @brief Buld and send the E2 Node Config Update failure
170  *
171  * @details
172  *
173  *    Function : BuildAndSendE2NodeConfigUpdateFailure
174  *
175  *    Functionality:
176  *         - Buld and send the E2 Node Config Update failure
177  * @return ROK     - success
178  *         RFAILED - failure
179  *
180  * ****************************************************************/
181
182 uint8_t BuildAndSendE2NodeConfigUpdateFailure(uint32_t duId, uint8_t transId, uint8_t causeInfo, uint8_t causeReason)
183 {
184    E2AP_PDU_t         *e2apMsg = NULL;
185    asn_enc_rval_t     encRetVal;
186    uint8_t            arrIdx=0;
187    uint8_t            elementCnt=0;
188    bool  memAllocFailed = false;
189    E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdateFail=NULL;
190
191    DU_LOG("\nINFO   -->  E2AP : Building E2 Node Config Update failure\n");
192    while(true)
193    {
194       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
195       if(e2apMsg == NULLP)
196       {
197          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
198          break;
199       }
200       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
201       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
202       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
203       {
204          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
205          break;
206       }
207
208       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
209       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
210       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateFailure;
211       e2NodeCfgUpdateFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2nodeConfigurationUpdateFailure;
212
213       elementCnt = 3;
214       e2NodeCfgUpdateFail->protocolIEs.list.count = elementCnt;
215       e2NodeCfgUpdateFail->protocolIEs.list.size  = elementCnt * sizeof(struct E2nodeConfigurationUpdateFailure_IEs *);
216
217       RIC_ALLOC(e2NodeCfgUpdateFail->protocolIEs.list.array, e2NodeCfgUpdateFail->protocolIEs.list.size);
218       if(e2NodeCfgUpdateFail->protocolIEs.list.array == NULLP)
219       {
220          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2 node config update failure array failed");
221          break;
222       }
223
224       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
225       {
226          RIC_ALLOC(e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx], sizeof(struct E2nodeConfigurationUpdateFailure_IEs));
227          if(e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx] == NULLP)
228          {
229             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2 node config update failure IEs failed");
230             memAllocFailed = true;
231             break;
232          }
233       }
234
235       if(memAllocFailed == true)
236       {
237           break;
238       }
239
240       /* Trans Id */
241       arrIdx = 0;
242       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
243       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
244       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TransactionID;
245       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
246
247       arrIdx++;
248       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
249       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
250       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_CauseE2;
251       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.present = causeInfo;
252       if(causeInfo == CauseE2_PR_e2Node) 
253          e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.e2Node = causeReason;
254       else
255          e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.misc = causeReason;
256
257       arrIdx++;
258       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
259       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
260       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TimeToWaitE2;
261       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
262
263       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
264       memset(encBuf, 0, ENC_BUF_MAX_LEN);
265       encBufSize = 0;
266       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
267
268       /* Check encode results */
269       if(encRetVal.encoded == ENCODE_FAIL)
270       {
271          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Node Config Update failure structure (at %s)\n",\
272                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
273          break;
274       }
275       else
276       {
277          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Node Config Update Failure\n");
278          for(int i=0; i< encBufSize; i++)
279          {
280             DU_LOG("%x",encBuf[i]);
281          }
282       }
283
284       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
285       {
286          DU_LOG("\nERROR  -->  E2AP : Sending E2 Node Config Update Failure failed");
287          break;
288       }
289       break;
290    }
291
292    FreeE2ConfigUpdateFail(e2apMsg);
293    return ROK;
294 }
295
296 /*******************************************************************
297  *
298  * @brief process the E2 node configuration update
299  *
300  * @details
301  *
302  *    Function : ProcE2NodeConfigUpdate 
303  *
304  * Functionality: Process E2 node configuration update
305  *
306  * @return ROK     - success
307  *         RFAILED - failure
308  *
309  ******************************************************************/
310
311 void ProcE2NodeConfigUpdate(uint32_t duId, E2nodeConfigurationUpdate_t *e2NodeConfigUpdate)
312 {
313    uint8_t ieIdx = 0, duIdx = 0;
314    uint8_t transId = 0, e2NodeUpdateListIdx=0;
315    DuDb    *duDb = NULLP;
316    E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList=NULLP;
317    E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItemIe=NULLP;
318    E2nodeComponentConfigUpdate_Item_t *e2NodeUpdateItem =NULLP;
319
320    if(e2NodeConfigUpdate)
321    {
322       if(e2NodeConfigUpdate->protocolIEs.list.array)
323       {
324          for(ieIdx=0; ieIdx < e2NodeConfigUpdate->protocolIEs.list.count; ieIdx++)
325          {
326             if(e2NodeConfigUpdate->protocolIEs.list.array[ieIdx])
327             {
328                switch(e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]->id)
329                {
330                   case ProtocolIE_IDE2_id_TransactionID:
331                      transId = e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
332                      break;
333                   
334                   default:
335                   {
336                      /*TODO - Other IEs will be handling in next gerrit*/
337                      break;
338                   }
339                }
340             }
341          }
342       }
343    }
344 }
345
346 /*******************************************************************
347  *
348  * @brief Builds Global RIC Id Params
349  *
350  * @details
351  *
352  *    Function : BuildGlobalRicId
353  *
354  *    Functionality: Building the Plmn and ric id
355  *
356  * @params[in] GlobalRIC_ID_t *ricId
357  * @return ROK     - success
358  *         RFAILED - failure
359  *
360  * ****************************************************************/
361
362 uint8_t BuildGlobalRicId(GlobalRIC_ID_t *ricId)
363 {
364    uint8_t unused = 4;
365    uint8_t byteSize = 3;
366    uint8_t ricVal= 1;
367    if(ricId != NULLP)
368    {
369       ricId->pLMN_Identity.size = byteSize * sizeof(uint8_t);
370       RIC_ALLOC(ricId->pLMN_Identity.buf,  ricId->pLMN_Identity.size);
371       buildPlmnId(ricCb.ricCfgParams.plmn , ricId->pLMN_Identity.buf);
372       /* fill ric Id */
373       ricId->ric_ID.size = byteSize * sizeof(uint8_t);
374       RIC_ALLOC(ricId->ric_ID.buf, ricId->ric_ID.size);
375       fillBitString(&ricId->ric_ID, unused, byteSize, ricVal);
376    }
377    return ROK;   
378 }
379
380 /*******************************************************************
381  *
382  * @brief deallocate the memory allocated in E2SetupResponse
383  *
384  * @details
385  *
386  *    Function : FreeE2SetupRsp 
387  *
388  *    Functionality: deallocate the memory allocated in E2SetupResponse 
389  *
390  * @params[in] E2AP_PDU_t *e2apMsg
391  *
392  * @return void
393  * ****************************************************************/
394 void FreeE2SetupRsp(E2AP_PDU_t *e2apMsg)
395 {
396    uint8_t arrIdx = 0, e2NodeConfigIdx=0, ranFuncIdx=0;
397    RANfunctionsID_List_t *ranFuncAcceptedList=NULL;
398    E2setupResponse_t  *e2SetupRsp=NULL;
399    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItemIe=NULL;
400    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList=NULL;
401    E2nodeComponentInterfaceF1_t *f1InterfaceInfo=NULL;
402    
403    if(e2apMsg)
404    {
405       if(e2apMsg->choice.successfulOutcome)
406       {
407          e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
408          if(e2SetupRsp->protocolIEs.list.array)
409          {
410             for(arrIdx=0; arrIdx<e2SetupRsp->protocolIEs.list.count; arrIdx++)
411             {
412                switch(e2SetupRsp->protocolIEs.list.array[arrIdx]->id)
413                {
414                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
415                   {
416                      ranFuncAcceptedList= &e2SetupRsp->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
417                      if(ranFuncAcceptedList->list.array)
418                      {
419                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAcceptedList->list.count; ranFuncIdx++)
420                         {
421                            if(ranFuncAcceptedList->list.array[ranFuncIdx])
422                            {
423                               RIC_FREE(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
424                            }
425                         }
426                         RIC_FREE(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
427                      }
428                      break;
429                   }
430                   case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
431                   {
432                      e2NodeConfigAdditionAckList =&e2SetupRsp->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
433                      if(e2NodeConfigAdditionAckList->list.count)
434                      {
435                         for(e2NodeConfigIdx=0; e2NodeConfigIdx<e2NodeConfigAdditionAckList->list.count; e2NodeConfigIdx++)
436                         {
437                            e2NodeAddAckItemIe = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[e2NodeConfigIdx];
438                            if(e2NodeAddAckItemIe)
439                            {
440                               f1InterfaceInfo = e2NodeAddAckItemIe->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1; 
441                               if(f1InterfaceInfo)
442                               {
443                                  RIC_FREE(f1InterfaceInfo->gNB_DU_ID.buf, f1InterfaceInfo->gNB_DU_ID.size);
444                                  RIC_FREE(f1InterfaceInfo, sizeof(E2nodeComponentInterfaceF1_t));
445                               }
446                               RIC_FREE(e2NodeAddAckItemIe, sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
447                            }
448                         }
449                         RIC_FREE(e2NodeConfigAdditionAckList->list.array, e2NodeConfigAdditionAckList->list.size);
450                      }
451                      break;
452                   }
453                }
454                RIC_FREE(e2SetupRsp->protocolIEs.list.array[arrIdx], sizeof(E2setupResponseIEs_t)); 
455             }
456             RIC_FREE(e2SetupRsp->protocolIEs.list.array, e2SetupRsp->protocolIEs.list.size);
457          }
458          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
459       }
460       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
461    }
462 }
463
464 /*******************************************************************
465  *
466  * @brief Build E2node Component config addition ack list
467  *
468  * @details
469  *
470  *    Function :  BuildE2nodeComponentConfigAdditionAck
471  *
472  *    Functionality: deallocate the memory allocated in E2SetupResponse 
473  *
474  * @params[in] E2nodeComponentConfigAdditionAck_List_t
475  * *e2NodeConfigAdditionAckList
476  *
477  * @return ROK - success
478  *         RFAILED - failure
479  * ****************************************************************/
480
481 uint8_t BuildE2nodeComponentConfigAdditionAck(E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList, DuDb *duDb)
482 {
483    uint8_t arrIdx = 0;
484    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem;
485    
486    e2NodeConfigAdditionAckList->list.count = 1;
487    e2NodeConfigAdditionAckList->list.size = e2NodeConfigAdditionAckList->list.count * sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t*);
488    RIC_ALLOC(e2NodeConfigAdditionAckList->list.array, e2NodeConfigAdditionAckList->list.size);
489    if(e2NodeConfigAdditionAckList->list.array == NULLP)
490    {
491       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
492       return RFAILED;
493    }
494
495    for(arrIdx = 0; arrIdx< e2NodeConfigAdditionAckList->list.count; arrIdx++)
496    {
497       RIC_ALLOC(e2NodeConfigAdditionAckList->list.array[arrIdx], sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
498       if(e2NodeConfigAdditionAckList->list.array[arrIdx] == NULLP)
499       {
500          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
501          return RFAILED;
502       }
503    }
504    e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[0];
505    e2NodeAddAckItem->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck_Item;
506    e2NodeAddAckItem->criticality = CriticalityE2_reject;
507    e2NodeAddAckItem->value.present = E2nodeComponentConfigAdditionAck_ItemIEs__value_PR_E2nodeComponentConfigAdditionAck_Item;
508    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentInterfaceType = duDb->e2NodeComponent.interfaceType;
509
510    /* >E2 Node Component ID */
511    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1;
512    RIC_ALLOC(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\
513          sizeof(E2nodeComponentInterfaceF1_t));
514    if(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1 == NULLP)
515    {
516       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
517       return RFAILED;
518    }
519    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t);
520    RIC_ALLOC(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
521          e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
522
523    if(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP)
524    {
525       DU_LOG("\nERROR  -->list.  E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
526       return RFAILED;
527    }
528    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]  = duDb->e2NodeComponent.componentId;
529    
530    /* >E2 Node Component Configuration Acknowledge*/
531    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentConfigurationAck.updateOutcome = \
532    E2nodeComponentConfigurationAck__updateOutcome_success;
533    
534    return ROK;  
535 }
536
537 /*******************************************************************
538  *
539  * @brief Build RAN function accepted list
540  *
541  * @details
542  *
543  *    Function : BuildRanFunctionAcceptedList
544  *
545  *    Functionality: Build RAN function accepted list 
546  *     ->For ProcedureCodeE2_id_E2setup or ProcedureCodeE2_id_RICserviceQuery  
547  *     we add all the RAN Function list which is present in RIC database.
548  *     ->For any other procedures, we just fill the RAN functions whose ID 
549  *     is present in the recvList
550  *
551  * @params[in] 
552  *    Stored DU databse 
553  *    Count of ran functions to be accepted in the list 
554  *    Received list of RAN functions
555  *    RAN Function list  
556  *    Procedure Code 
557  *
558  * @return ROK - success
559  *         RFAILED - failure
560  * ****************************************************************/
561
562 uint8_t BuildRanFunctionAcceptedList(DuDb *duDb, uint8_t count, RanFunction *ranFunAcceptedList, RANfunctionsID_List_t *ranFuncAcceptedList, uint8_t procedureCode)
563 {
564    uint8_t ranFuncIdx = 0;
565    RANfunctionID_ItemIEs_t *ranFuncAcceptedItemIe=NULL;
566    
567    /* For ProcedureCodeE2_id_E2setup and ProcedureCodeE2_id_RICserviceQuery, 
568     * the number of RAN function list items is equal to the number of 
569     * ran function entries stored in the database.
570     * For any other procedure, the RAN function list count is equal
571     * to the count of ran functions obtained from the function's caller */
572
573    if((procedureCode == ProcedureCodeE2_id_RICserviceQuery)||(procedureCode == ProcedureCodeE2_id_E2setup))
574       ranFuncAcceptedList->list.count = duDb->numOfRanFunction;
575    else
576       ranFuncAcceptedList->list.count = count;
577    
578    ranFuncAcceptedList->list.size = ranFuncAcceptedList->list.count*sizeof(RANfunctionID_ItemIEs_t*);
579    RIC_ALLOC(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
580    if(ranFuncAcceptedList->list.array)
581    {
582       for(ranFuncIdx = 0; ranFuncIdx< ranFuncAcceptedList->list.count; ranFuncIdx++)
583       {
584          RIC_ALLOC(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
585          if(ranFuncAcceptedList->list.array[ranFuncIdx] == NULLP)
586          {
587             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function added list array item");
588             return RFAILED;
589          }
590          ranFuncAcceptedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAcceptedList->list.array[ranFuncIdx];
591          ranFuncAcceptedItemIe->id = ProtocolIE_IDE2_id_RANfunctionID_Item;
592          ranFuncAcceptedItemIe->criticality= CriticalityE2_ignore;
593          ranFuncAcceptedItemIe->value.present = RANfunctionID_ItemIEs__value_PR_RANfunctionID_Item;
594          if((procedureCode == ProcedureCodeE2_id_RICserviceQuery)||(procedureCode == ProcedureCodeE2_id_E2setup))
595          {
596             /* filling the RAN function information with the help of DuDb */
597             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionID = duDb->ranFunction[ranFuncIdx].id;
598             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision= duDb->ranFunction[ranFuncIdx].revisionCounter;
599          }
600          else
601          {
602             /* filling the the RAN function information with the help received list of RAN functions */
603             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionID = ranFunAcceptedList[ranFuncIdx].id;
604             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision= ranFunAcceptedList[ranFuncIdx].revisionCounter;
605          }
606       }
607    }
608    else
609    {
610       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function added list array");
611       return RFAILED;
612    }
613    return ROK;
614 }
615
616 /*******************************************************************
617  *
618  * @brief Builds and sends the E2SetupResponse
619  *
620  * @details
621  *
622  *    Function : BuildAndSendE2SetupRsp
623  *
624  *    Functionality: Constructs the F1SetupResponse message and sends
625  *                   it back to the DU through SCTP.
626  *
627  * @params[in] void **buf,Buffer to which encoded pattern is written into
628  * @params[in] int *size,size of buffer
629  *
630  * @return ROK     - success
631  *         RFAILED - failure
632  *
633  * ****************************************************************/
634
635 uint8_t BuildAndSendE2SetupRsp(DuDb *duDb, uint8_t transId)
636 {
637    E2AP_PDU_t         *e2apMsg = NULL;
638    E2setupResponse_t  *e2SetupRsp;
639    asn_enc_rval_t     encRetVal; 
640    uint8_t            idx;
641    uint8_t            elementCnt;
642    bool  memAllocFailed = false;
643  
644    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup Response\n");
645    while(true)
646    {
647       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); 
648       if(e2apMsg == NULLP)
649       {
650          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
651          break;
652       }
653       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
654       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
655       if(e2apMsg->choice.successfulOutcome == NULLP)
656       {
657          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
658          break;  
659       }
660
661       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
662       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
663       e2apMsg->choice.successfulOutcome->value.present = \
664                                                          SuccessfulOutcomeE2__value_PR_E2setupResponse;
665       e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
666
667       elementCnt = 3;
668       /* Fill Accepted RAN function IE If Ran function information is stored in databse */
669       if(duDb->numOfRanFunction)
670          elementCnt++;
671
672       e2SetupRsp->protocolIEs.list.count = elementCnt;
673       e2SetupRsp->protocolIEs.list.size  = elementCnt * sizeof(E2setupResponseIEs_t*);
674
675       RIC_ALLOC(e2SetupRsp->protocolIEs.list.array, e2SetupRsp->protocolIEs.list.size);
676       if(e2SetupRsp->protocolIEs.list.array == NULLP)
677       {
678          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");
679          break;  
680       }
681
682       for(idx=0; idx<elementCnt; idx++)
683       {
684          RIC_ALLOC(e2SetupRsp->protocolIEs.list.array[idx], sizeof(E2setupResponseIEs_t)); 
685          if(e2SetupRsp->protocolIEs.list.array[idx] == NULLP)
686          { 
687             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");
688             memAllocFailed = true;
689             break;
690          }    
691       }
692       
693       if(memAllocFailed == true)
694       {
695           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");    
696           break;
697       }
698       /* Trans Id */
699       idx = 0;
700       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_TransactionID;
701       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
702       e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_TransactionID; 
703       e2SetupRsp->protocolIEs.list.array[idx]->value.choice.TransactionID  = transId;
704
705       /* Global RIC ID */
706       idx++;
707       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_GlobalRIC_ID;
708       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
709       e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_GlobalRIC_ID;
710
711       if(BuildGlobalRicId(&(e2SetupRsp->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID))!=ROK)
712       {
713          DU_LOG("\nERROR  -->  E2AP : Failed to build Global Ric Id");
714          break;
715       }
716       
717       if(duDb->numOfRanFunction)
718       {
719          /* Accepted RAN function Id */
720          idx++;
721          e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
722          e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
723          e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_RANfunctionsID_List;
724          if(BuildRanFunctionAcceptedList(duDb, 0, NULL, &e2SetupRsp->protocolIEs.list.array[idx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_E2setup)!=ROK)
725          {
726             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
727             break;         
728          }
729       }
730
731       /* E2 Node Component Configuration Addition Acknowledge List*/
732       idx++;
733       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck;
734       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
735       e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
736          E2setupResponseIEs__value_PR_E2nodeComponentConfigAdditionAck_List;
737       if(BuildE2nodeComponentConfigAdditionAck(&e2SetupRsp->protocolIEs.list.array[idx]->\
738          value.choice.E2nodeComponentConfigAdditionAck_List, duDb) != ROK)
739       {
740          DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config addition ack list");
741          break;
742       }
743
744       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
745       memset(encBuf, 0, ENC_BUF_MAX_LEN);
746       encBufSize = 0;
747       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
748
749       /* Check encode results */
750       if(encRetVal.encoded == ENCODE_FAIL)
751       {
752          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupResponse structure (at %s)\n",\
753                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
754          break;   
755       } 
756       else 
757       {
758          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SetupResponse\n");
759          for(int i=0; i< encBufSize; i++)
760          {
761             DU_LOG("%x",encBuf[i]);
762          } 
763       }
764
765       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
766       {
767          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Response failed");      
768          break;   
769       }
770       break;
771    }
772
773    FreeE2SetupRsp(e2apMsg);
774    BuildAndSendRicSubscriptionReq(duDb);
775    return ROK;
776 }
777
778 /*******************************************************************
779  *
780  * @brief Free RIC Subscription Details
781  *
782  * @details
783  *
784  *    Function : FreeRicSubsDetails
785  *
786  *    Functionality: Free the RIC Subscription Details
787  *
788  * @params[in] RICsubscriptionDetails_t *subsDetails
789  * @return void
790  *
791  * ****************************************************************/
792 void FreeRicSubsDetails(RICsubscriptionDetails_t *subsDetails)
793 {
794    uint8_t elementIdx = 0;
795    RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
796
797    RIC_FREE(subsDetails->ricEventTriggerDefinition.buf, subsDetails->ricEventTriggerDefinition.size);
798
799    if(subsDetails->ricAction_ToBeSetup_List.list.array)
800    {
801       for(elementIdx = 0; elementIdx < subsDetails->ricAction_ToBeSetup_List.list.count; elementIdx++)
802       {
803          if(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
804          {
805             actionItem = (RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx];
806             if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
807             {
808                RIC_FREE(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf, \
809                   actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->size);
810                RIC_FREE(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, sizeof(RICactionDefinition_t));
811             }
812             RIC_FREE(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], sizeof(RICaction_ToBeSetup_ItemIEs_t))
813          }
814       }
815       RIC_FREE(subsDetails->ricAction_ToBeSetup_List.list.array, subsDetails->ricAction_ToBeSetup_List.list.size);
816    }
817 }
818
819 /*******************************************************************
820  *
821  * @brief Free RIC Subscription Request
822  *
823  * @details
824  *
825  *    Function : FreeRicSubscriptionReq
826  *
827  * Functionality : Free RIC Subscription Request
828  *
829  * @return ROK     - success
830  *         RFAILED - failure
831  *
832  ******************************************************************/
833 void FreeRicSubscriptionReq(E2AP_PDU_t *e2apRicMsg)
834 {
835    uint8_t idx = 0;
836    RICsubscriptionRequest_t   *ricSubscriptionReq;
837
838    if(e2apRicMsg)
839    {
840       if(e2apRicMsg->choice.initiatingMessage)
841       {
842          ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
843          if(ricSubscriptionReq->protocolIEs.list.array)
844          {
845             for(idx=0; idx < ricSubscriptionReq->protocolIEs.list.count; idx++)
846             {
847                switch(ricSubscriptionReq->protocolIEs.list.array[idx]->id)
848                {
849                   case ProtocolIE_IDE2_id_RICsubscriptionDetails:
850                      {
851                         FreeRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails));
852                         break;
853                      }
854                }               
855                RIC_FREE(ricSubscriptionReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionRequest_IEs_t));
856             }
857             RIC_FREE(ricSubscriptionReq->protocolIEs.list.array, ricSubscriptionReq->protocolIEs.list.size);
858          }
859          RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
860       }
861       RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
862    }
863 }
864
865 /*******************************************************************
866  *
867  * @brief Builds Ric Request Id
868  *
869  * @details
870  *
871  *    Function : BuildNewRicRequestId
872  *
873  *    Functionality: Assign new Ric Request ID
874  *
875  * @params[in] RIC request ID to be sent
876  *             RIC request ID stored in DB
877  * @return ROK     - success
878  *         RFAILED - failure
879  *
880  * ****************************************************************/
881
882 uint8_t BuildNewRicRequestId(RICrequestID_t *ricReqId, RicRequestId *reqIdDb)
883 {
884    static uint16_t requestorId = 0;
885    static uint16_t instanceId = 0;
886
887    if(ricReqId != NULLP)
888    {
889       ricReqId->ricRequestorID = ++requestorId;
890       ricReqId->ricInstanceID  = ++instanceId;
891
892       reqIdDb->requestorId = ricReqId->ricRequestorID;
893       reqIdDb->instanceId = ricReqId->ricInstanceID;
894    }
895    return ROK;
896 }
897
898 /*******************************************************************
899  *
900  * @brief Free RIC Action Definition
901  *
902  * @details
903  *
904  *    Function : FreeRicActionDefinition
905  *
906  *    Functionality: Free RIC Action Definition
907  *
908  * @params[in] E2SM-KPM Action definition
909  * @return void
910  *
911  * ****************************************************************/
912 void  FreeRicActionDefinition(E2SM_KPM_ActionDefinition_t actionDef)
913 {
914    uint8_t  elementIdx = 0;
915    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
916    MeasurementInfoItem_t *measItem = NULLP;
917
918    switch(actionDef.actionDefinition_formats.present)
919    {
920       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
921          {
922             if(actionDef.actionDefinition_formats.choice.actionDefinition_Format1)
923             {
924                actionFormat1 = actionDef.actionDefinition_formats.choice.actionDefinition_Format1;
925                if(actionFormat1->measInfoList.list.array)
926                {
927                   for(elementIdx = 0; elementIdx < actionFormat1->measInfoList.list.count; elementIdx++)
928                   {
929                      if(actionFormat1->measInfoList.list.array[elementIdx])
930                      {
931                         measItem = actionFormat1->measInfoList.list.array[elementIdx];
932                         switch(measItem->measType.present)
933                         {
934                            case MeasurementType_PR_NOTHING:
935                            case MeasurementType_PR_measID:
936                               break;
937                            case MeasurementType_PR_measName:
938                            {
939                               RIC_FREE(measItem->measType.choice.measName.buf, measItem->measType.choice.measName.size)
940                               break;
941                            }
942                         }
943                         RIC_FREE(measItem, sizeof(MeasurementInfoItem_t));
944                      }
945                   }
946                   RIC_FREE(actionFormat1->measInfoList.list.array, actionFormat1->measInfoList.list.size);
947                }
948                RIC_FREE(actionFormat1, sizeof(E2SM_KPM_ActionDefinition_Format1_t));
949             }
950             break;
951          }
952
953       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format2:
954       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format3:
955       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format4:
956       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format5:
957       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_NOTHING:
958          break;
959    }
960 }
961
962 /*******************************************************************
963  *
964  * @brief Fill RIC Action Definition
965  *
966  * @details
967  *
968  *    Function : fillRicActionDef
969  *
970  *    Functionality: Fill RIC Action Definition
971  *
972  * @params[in] RIC Action definition
973  * @return ROK 
974  *         RFAILED
975  *
976  * ****************************************************************/
977 uint8_t fillRicActionDef(RICactionDefinition_t *ricActionDef)
978 {
979    uint8_t ret = RFAILED;
980    asn_enc_rval_t  encRetVal;
981    uint8_t elementCnt = 0, elementIdx = 0;
982    char    *measurementTypeName[] = {"RRU.PrbTotDl", "RRU.PrbTotUl"};
983    E2SM_KPM_ActionDefinition_t actionDef;
984    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
985    MeasurementInfoItem_t *measItem = NULLP;
986    
987    while(true)
988    {
989       /* Fill E2SM-KPM Action Definition Format 1 */
990
991       /* RIC Stype Type */
992       actionDef.ric_Style_Type = RIC_STYLE_TYPE;
993
994       /* RIC Action Definition Format 1 */
995       actionDef.actionDefinition_formats.present = \
996            E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1;
997
998       RIC_ALLOC(actionDef.actionDefinition_formats.choice.actionDefinition_Format1, \
999             sizeof(E2SM_KPM_ActionDefinition_Format1_t));
1000       if(actionDef.actionDefinition_formats.choice.actionDefinition_Format1 == NULLP)
1001       {
1002          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1003          break;
1004       }
1005       actionFormat1 = actionDef.actionDefinition_formats.choice.actionDefinition_Format1;
1006
1007       /* Measurement Info List */
1008       elementCnt = 2;
1009       actionFormat1->measInfoList.list.count = elementCnt;
1010       actionFormat1->measInfoList.list.size = elementCnt * sizeof(MeasurementInfoItem_t *);
1011       RIC_ALLOC(actionFormat1->measInfoList.list.array, actionFormat1->measInfoList.list.size);
1012       if(actionFormat1->measInfoList.list.array == NULL)
1013       {
1014          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1015          break;
1016       }
1017
1018       for(elementIdx = 0; elementIdx < elementCnt; elementIdx++)
1019       {
1020          RIC_ALLOC(actionFormat1->measInfoList.list.array[elementIdx], sizeof(MeasurementInfoItem_t));
1021          if(actionFormat1->measInfoList.list.array[elementIdx] == NULLP)
1022          {
1023             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1024             break;
1025          }
1026
1027          measItem = actionFormat1->measInfoList.list.array[elementIdx];
1028          measItem->measType.present = MeasurementType_PR_measName;
1029
1030          measItem->measType.choice.measName.size = strlen(measurementTypeName[elementIdx]);
1031          RIC_ALLOC(measItem->measType.choice.measName.buf, measItem->measType.choice.measName.size);
1032          if(measItem->measType.choice.measName.buf == NULLP)
1033          {
1034             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1035             break;
1036          }
1037          memcpy(measItem->measType.choice.measName.buf, measurementTypeName[elementIdx], measItem->measType.choice.measName.size);
1038       }
1039       if(elementIdx < elementCnt)
1040          break;
1041
1042       /* Granularity Period */
1043       actionFormat1->granulPeriod = RIC_ACTION_GRANULARITY_PERIOD; /* In ms */
1044
1045       /* Prints the Msg formed */
1046       xer_fprint(stdout, &asn_DEF_E2SM_KPM_ActionDefinition, &actionDef);
1047
1048       /* Encode E2SM-KPM RIC Action Definition */
1049       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1050       encBufSize = 0;
1051       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_ActionDefinition, 0, &actionDef, PrepFinalEncBuf, encBuf);
1052       if(encRetVal.encoded == ENCODE_FAIL)
1053       {
1054          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM action definition structure (at %s)\n",\
1055                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1056          break;
1057       }
1058
1059       /* Copty encoded E2SM-KPM RIC action definition to E2AP octet string buffer */
1060       ricActionDef->size = encBufSize;
1061       RIC_ALLOC(ricActionDef->buf, encBufSize);
1062       if(ricActionDef->buf == NULLP)
1063       {
1064          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1065          break;
1066       }
1067       memcpy(ricActionDef->buf, encBuf, encBufSize);
1068
1069       ret = ROK;
1070       break;
1071    }
1072
1073    FreeRicActionDefinition(actionDef);
1074    return ret;
1075 }
1076
1077 /*******************************************************************
1078  *
1079  * @brief Fills RIC Action To Be Setup Item
1080  *
1081  * @details
1082  *
1083  *    Function : fillActionToBeSetup
1084  *
1085  *    Functionality: Fill the RIC Action To Be Setup Ite,
1086  *                   RIC subscription DB
1087  *
1088  * @params[in] RICaction_ToBeSetup_ItemIEs_t *items
1089  * @return ROK     - success
1090  *         RFAILED - failure
1091  *
1092  * ****************************************************************/
1093 uint8_t fillActionToBeSetup(RICaction_ToBeSetup_ItemIEs_t *actionItem, RicSubscription *ricSubsDb)
1094 {
1095    static uint8_t ricActionId = 0;
1096
1097    if(actionItem == NULLP)
1098    {
1099       DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1100       return RFAILED;
1101    }
1102
1103    while(true)
1104    {
1105       actionItem->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item;
1106       actionItem->criticality   =  CriticalityE2_ignore;
1107       actionItem->value.present =  RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
1108       
1109       /* RIC Action ID */
1110       actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID = ricActionId++;
1111       ricSubsDb->actionSequence[ricActionId].actionId = \
1112          actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
1113
1114       /* RIC Action Type */
1115       actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType = RICactionType_report;
1116
1117       /* RIC Action Definition */
1118       RIC_ALLOC(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, sizeof(RICactionDefinition_t));
1119       if(!actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
1120       {
1121          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1122          break;
1123       }
1124       if(fillRicActionDef(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition) != ROK)
1125       {
1126          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1127          break;
1128       }
1129       
1130       ricSubsDb->numOfActions++;
1131       return ROK;
1132    }
1133
1134    memset(&ricSubsDb->actionSequence[ricActionId], 0, sizeof(ActionInfo));
1135    ricSubsDb->actionSequence[ricActionId].actionId = -1;
1136    return RFAILED;
1137 }
1138
1139 /*******************************************************************
1140  *
1141  * @brief Free Event Trigger Definition
1142  *
1143  * @details
1144  *
1145  *    Function : FreeEventTriggerDef
1146  *
1147  *    Functionality: Free Event Trigger Definition
1148  *
1149  * @params[in] E2SM-KPM Event Trigger Definition
1150  * @return void
1151  *
1152  * ****************************************************************/
1153 void  FreeEventTriggerDef(E2SM_KPM_EventTriggerDefinition_t *eventTiggerDef)
1154 {
1155    if(eventTiggerDef)
1156    {
1157       switch(eventTiggerDef->eventDefinition_formats.present)
1158       {
1159          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING:
1160             break;
1161          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1: 
1162             RIC_FREE(eventTiggerDef->eventDefinition_formats.choice.eventDefinition_Format1, \
1163                   sizeof(E2SM_KPM_EventTriggerDefinition_Format1_t));
1164             break;                  
1165       }         
1166    }
1167 }
1168
1169 /*******************************************************************
1170  *
1171  * @brief Fill Event Trigger Definition
1172  *
1173  * @details
1174  *
1175  *    Function : fillEventTriggerDef
1176  *
1177  *    Functionality: Fill Event Trigger Definition
1178  *
1179  * @params[in] RIC Event Trigger Definition
1180  * @return ROK
1181  *         RFAILED
1182  *
1183  * ****************************************************************/
1184 uint8_t fillEventTriggerDef(RICeventTriggerDefinition_t *ricEventTriggerDef)
1185 {
1186    uint8_t ret = RFAILED;
1187    asn_enc_rval_t  encRetVal;
1188    E2SM_KPM_EventTriggerDefinition_t eventTiggerDef;
1189
1190    while(true)
1191    {
1192       /* Fill E2SM-KPM Event Trigger Definition Format 1 */
1193       eventTiggerDef.eventDefinition_formats.present = \
1194        E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1;
1195
1196       RIC_ALLOC(eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1, \
1197             sizeof(E2SM_KPM_EventTriggerDefinition_Format1_t));
1198       if(eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1 == NULLP)
1199       {
1200          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1201          break;
1202       }
1203
1204       eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1->reportingPeriod = 1000; /* In ms */
1205
1206       /* Prints the Msg formed */
1207       xer_fprint(stdout, &asn_DEF_E2SM_KPM_EventTriggerDefinition, &eventTiggerDef);
1208
1209       /* Encode E2SM-KPM Event Trigger Definition */
1210       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1211       encBufSize = 0;
1212       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_EventTriggerDefinition, 0, &eventTiggerDef, PrepFinalEncBuf, encBuf);
1213       if(encRetVal.encoded == ENCODE_FAIL)
1214       {
1215          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM event trigger definition structure (at %s)\n",\
1216                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1217          break;
1218       }
1219
1220       /* Copy encoded E2SM-KPM event trigger definition to E2AP octet string buffer */
1221       ricEventTriggerDef->size = encBufSize;
1222       RIC_ALLOC(ricEventTriggerDef->buf, encBufSize);
1223       if(ricEventTriggerDef->buf == NULLP)
1224       {
1225          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1226          break;
1227       }
1228       memcpy(ricEventTriggerDef->buf, encBuf, encBufSize);
1229
1230       ret = ROK;
1231       break;
1232    }
1233
1234    FreeEventTriggerDef(&eventTiggerDef);
1235    return ret;
1236 }
1237
1238 /*******************************************************************
1239  *
1240  * @brief builds RIC Subscription Details
1241  *
1242  * @details
1243  *
1244  *    Function : BuildsRicSubsDetails
1245  *
1246  *    Functionality: Builds the RIC Subscription Details
1247  *
1248  * @params[in] RIC Subscription details to be filled
1249  *             RIC subscriotion DB
1250  * @return ROK     - success
1251  *         RFAILED - failure
1252  *
1253  * ****************************************************************/
1254
1255 uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails, RicSubscription *ricSubsDb)
1256 {
1257    uint8_t actionIdx = 0;
1258    uint8_t elementCnt = 0;
1259    uint8_t elementIdx = 0;
1260
1261    if(subsDetails == NULLP)
1262    {
1263       DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1264       return RFAILED;
1265    }
1266
1267    while(true)
1268    {
1269       /* RIC Event Trigger Definition */
1270       if(fillEventTriggerDef(&subsDetails->ricEventTriggerDefinition) != ROK)
1271       {
1272          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1273          break;
1274       }
1275
1276       /* RIC Actions To Be Setup List */
1277       elementCnt = 1;
1278       subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt;
1279       subsDetails->ricAction_ToBeSetup_List.list.size = elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t *);
1280       RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, subsDetails->ricAction_ToBeSetup_List.list.size);
1281       if(subsDetails->ricAction_ToBeSetup_List.list.array  == NULLP)
1282       {
1283          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICactionToBeSetup Items failed");
1284          break;
1285       } 
1286
1287       for(elementIdx = 0; elementIdx < elementCnt; elementIdx++)
1288       {
1289          RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], sizeof(RICaction_ToBeSetup_ItemIEs_t));
1290          if(!subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
1291          {
1292             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1293             break;
1294          }
1295       }
1296       if(elementIdx < elementCnt)
1297          break;
1298
1299       for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
1300       {
1301          ricSubsDb->actionSequence[actionIdx].actionId = -1;
1302       }
1303
1304       elementIdx = 0;
1305       if(fillActionToBeSetup((RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], \
1306          ricSubsDb) != ROK)
1307       {
1308          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1309          break;
1310       }
1311
1312       return ROK;
1313    }
1314    return RFAILED;
1315 }
1316
1317 /*******************************************************************
1318  *
1319  * @brief Builds and Send the RicSubscriptionReq
1320  *
1321  * @details
1322  *
1323  *    Function : BuildAndSendRicSubscriptionReq
1324  *
1325  * Functionality:Fills the RicSubscriptionReq
1326  *
1327  * @return ROK     - success
1328  *         RFAILED - failure
1329  *
1330  ******************************************************************/
1331 uint8_t BuildAndSendRicSubscriptionReq(DuDb *duDb)
1332 {
1333    uint8_t         ret = RFAILED;
1334    E2AP_PDU_t                 *e2apRicMsg = NULL;
1335    RICsubscriptionRequest_t   *ricSubscriptionReq;
1336    uint8_t         elementCnt;
1337    uint8_t         idx;
1338    asn_enc_rval_t  encRetVal;        /* Encoder return value */
1339    RanFunction     *ranFuncDb = &duDb->ranFunction[0];
1340
1341    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Request\n");
1342
1343    while(true)
1344    {
1345       RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
1346       if(e2apRicMsg == NULLP)
1347       {
1348          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1349          break;
1350       }
1351
1352       e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
1353       RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1354       if(e2apRicMsg->choice.initiatingMessage == NULLP)
1355       {
1356          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1357          break;
1358       }
1359       e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
1360       e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
1361       e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
1362
1363       ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
1364
1365       elementCnt = 3;
1366       ricSubscriptionReq->protocolIEs.list.count = elementCnt;
1367       ricSubscriptionReq->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
1368
1369       /* Initialize the subscription members */
1370       RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, ricSubscriptionReq->protocolIEs.list.size);
1371       if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
1372       {
1373          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1374          break;
1375       }
1376
1377       for(idx=0; idx<elementCnt; idx++)
1378       {
1379          RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionRequest_IEs_t));
1380          if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
1381          {
1382             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1383             break;
1384          }
1385       }
1386       if(idx < elementCnt)
1387          break;
1388
1389       /* Filling RIC Request Id */
1390       idx = 0;
1391       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
1392       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1393       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
1394                                                                       RICsubscriptionRequest_IEs__value_PR_RICrequestID;
1395       if(BuildNewRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID, \
1396          &ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription].requestId) != ROK)
1397       {
1398          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : Line [%d]", __func__, __LINE__);
1399          break;
1400       }
1401
1402
1403       /* Filling RAN Function Id */
1404       idx++;
1405       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
1406       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1407       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
1408                                                                       RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
1409       ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ranFuncDb->id;
1410
1411       /* Filling RIC Subscription Details */
1412       idx++;
1413       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
1414       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1415       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
1416                                                                       RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
1417       if(BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails),\
1418          &ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription]) != ROK)
1419       {
1420          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : Line [%d]", __func__, __LINE__);
1421          break;
1422       }
1423
1424       /* Prints the Msg formed */
1425       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
1426
1427       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1428       encBufSize = 0;
1429       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf, encBuf);
1430       if(encRetVal.encoded == ENCODE_FAIL)
1431       {
1432          DU_LOG("\nERROR  -->  E2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
1433                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1434          break;               
1435       }
1436       else
1437       {
1438          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
1439          for(int i=0; i< encBufSize; i++)
1440          {
1441             DU_LOG("%x",encBuf[i]);
1442          } 
1443       }
1444
1445       /* Sending msg */
1446       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
1447       {
1448          DU_LOG("\nERROR  -->  E2AP : Sending RIC subscription Request failed");
1449          break;
1450       }
1451
1452       ranFuncDb->numOfSubscription++;
1453       ret = ROK;
1454       break;
1455    }
1456
1457    if(ret == RFAILED)
1458       memset(&ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription], 0, sizeof(RicSubscription));
1459    FreeRicSubscriptionReq(e2apRicMsg);
1460    return ret;
1461 }
1462
1463 /*******************************************************************
1464  *
1465  * @brief Process RicSubscriptionResponse
1466  *
1467  * @details
1468  *
1469  *    Function : ProcRicSubscriptionRsp
1470  *
1471  * Functionality: Processes RicSubscriptionRsp
1472  *
1473  * @return ROK     - void
1474  *
1475  ******************************************************************/
1476
1477 void ProcRicSubscriptionResponse(uint32_t duId, RICsubscriptionResponse_t  *ricSubscriptionRsp)
1478 {
1479    uint8_t duIdx = 0, ieIdx = 0,subsIdx = 0, notAdmitIdx = 0;
1480    uint8_t ranFuncId = 0, actionId = 0;
1481    DuDb *duDb = NULLP;
1482    bool ricReqIdDecoded = false;
1483    RicRequestId ricReqId;
1484    RanFunction  *ranFuncDb = NULLP;
1485    RICsubscriptionResponse_IEs_t *ricSubsRspIe = NULLP;
1486    RICaction_NotAdmitted_List_t *notAdmitList = NULLP;
1487
1488    DU_LOG("\nINFO  -->  E2AP : RIC Subscription Response received");
1489
1490    /* Fetch DU DB */
1491    SEARCH_DU_DB(duIdx, duId, duDb);
1492    if(duDb == NULLP)
1493    {
1494       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
1495       return;
1496    }
1497
1498    memset(&ricReqId, 0, sizeof(RicRequestId));
1499    if(ricSubscriptionRsp)
1500    {
1501       if(ricSubscriptionRsp->protocolIEs.list.array)
1502       {
1503          for(ieIdx=0; ieIdx<ricSubscriptionRsp->protocolIEs.list.count; ieIdx++)
1504          {
1505             if(ricSubscriptionRsp->protocolIEs.list.array[ieIdx])
1506             {
1507                ricSubsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
1508                switch(ricSubscriptionRsp->protocolIEs.list.array[ieIdx]->id)
1509                {
1510                   case ProtocolIE_IDE2_id_RICrequestID:
1511                      {
1512                         ricReqId.requestorId = ricSubsRspIe->value.choice.RICrequestID.ricRequestorID;
1513                         ricReqId.instanceId = ricSubsRspIe->value.choice.RICrequestID.ricInstanceID;
1514                         ricReqIdDecoded = true;
1515                         break;
1516                      }
1517                   case ProtocolIE_IDE2_id_RANfunctionID:
1518                      {
1519                         ranFuncId = ricSubsRspIe->value.choice.RANfunctionID;
1520                         if(duDb->ranFunction[ranFuncId-1].id == ranFuncId)
1521                         {
1522                            ranFuncDb = &duDb->ranFunction[ranFuncId-1];
1523                         }
1524                         else
1525                         {
1526                            DU_LOG("\nERROR  -->  E2AP : ProcRicSubscriptionResponse: RAN Function ID [%d] not found", ranFuncId);
1527                            return;
1528                         }
1529                         break; 
1530                      }
1531                   case ProtocolIE_IDE2_id_RICactions_Admitted:
1532                      {
1533                         break;
1534                      }
1535                   case ProtocolIE_IDE2_id_RICactions_NotAdmitted:
1536                      {
1537                         if(!(ranFuncDb && ricReqIdDecoded))
1538                            return;
1539
1540                         notAdmitList = &ricSubsRspIe->value.choice.RICaction_NotAdmitted_List;
1541                         for(notAdmitIdx = 0; notAdmitIdx < notAdmitList->list.count; notAdmitIdx++)
1542                         {
1543                            actionId = ((RICaction_NotAdmitted_ItemIEs_t *)(notAdmitList->list.array[notAdmitIdx]))->\
1544                               value.choice.RICaction_NotAdmitted_Item.ricActionID;
1545
1546                               /* Remove action from RAN Function's subscription list */
1547                               for(subsIdx = 0; subsIdx < ranFuncDb->numOfSubscription; subsIdx++)
1548                               {
1549                                  if((ranFuncDb->subscriptionList[subsIdx].requestId.requestorId == ricReqId.requestorId) &&
1550                                        (ranFuncDb->subscriptionList[subsIdx].requestId.instanceId == ricReqId.instanceId))
1551                                  {
1552                                     if(ranFuncDb->subscriptionList[subsIdx].actionSequence[actionId].actionId == actionId)
1553                                     {
1554                                        memset(&ranFuncDb->subscriptionList[subsIdx].actionSequence[actionId], 0, \
1555                                           sizeof(ActionInfo));
1556                                        ranFuncDb->subscriptionList[subsIdx].actionSequence[actionId].actionId = -1;
1557                                        ranFuncDb->subscriptionList[subsIdx].numOfActions--;
1558                                        break;
1559                                     }
1560                                  }
1561                               }
1562                         }
1563                         break;
1564                      }
1565                }
1566             }
1567          }
1568       }
1569    } 
1570 }
1571
1572 /*******************************************************************
1573  *
1574  * @brief deallocate the memory allocated in E2SetupFailure
1575  *
1576  * @details
1577  *
1578  *    Function : FreeE2SetupFailure 
1579  *
1580  *    Functionality: deallocate the memory allocated in E2SetupFailure 
1581  *
1582  * @params[in] E2AP_PDU_t *e2apMsg
1583  *
1584  * @return void
1585  * ****************************************************************/
1586 void FreeE2SetupFailure(E2AP_PDU_t *e2apMsg)
1587 {
1588    uint8_t arrIdx = 0;
1589    E2setupFailure_t  *e2SetupFail;
1590
1591    if(e2apMsg)
1592    {
1593       if(e2apMsg->choice.unsuccessfulOutcome)
1594       {
1595          e2SetupFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
1596          if(e2SetupFail->protocolIEs.list.array)
1597          {
1598             for(arrIdx=0; arrIdx<e2SetupFail->protocolIEs.list.count; arrIdx++)
1599             {
1600                RIC_FREE(e2SetupFail->protocolIEs.list.array[arrIdx], sizeof(E2setupFailureIEs_t)); 
1601             }
1602             RIC_FREE(e2SetupFail->protocolIEs.list.array, e2SetupFail->protocolIEs.list.size);
1603          }
1604          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
1605       }
1606       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1607    }
1608 }
1609
1610 /*******************************************************************
1611  *
1612  * @brief Buld and send the E2 Setup failure
1613  *
1614  * @details
1615  *
1616  *    Function : BuildAndSendE2SetupFailure
1617  *
1618  *    Functionality:
1619  *         - Buld and send the E2 Setup failure
1620  * @return ROK     - success
1621  *         RFAILED - failure
1622  *
1623  * ****************************************************************/
1624
1625 uint8_t BuildAndSendE2SetupFailure(uint32_t duId, uint8_t transId)
1626 {
1627    E2AP_PDU_t         *e2apMsg = NULL;
1628    E2setupFailure_t   *e2SetupFailure;
1629    asn_enc_rval_t     encRetVal;
1630    uint8_t            arrIdx;
1631    uint8_t            elementCnt;
1632    bool  memAllocFailed = false;
1633
1634    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup failure\n");
1635    while(true)
1636    {
1637       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1638       if(e2apMsg == NULLP)
1639       {
1640          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1641          break;
1642       }
1643       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
1644       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
1645       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
1646       {
1647          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1648          break;
1649       }
1650
1651       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
1652       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
1653       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2setupFailure;
1654       e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
1655
1656       elementCnt = 3;
1657       e2SetupFailure->protocolIEs.list.count = elementCnt;
1658       e2SetupFailure->protocolIEs.list.size  = elementCnt * sizeof(struct E2setupFailureIEs *);
1659
1660       RIC_ALLOC(e2SetupFailure->protocolIEs.list.array, e2SetupFailure->protocolIEs.list.size);
1661       if(e2SetupFailure->protocolIEs.list.array == NULLP)
1662       {
1663          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
1664          break;
1665       }
1666
1667       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
1668       {
1669          RIC_ALLOC(e2SetupFailure->protocolIEs.list.array[arrIdx], sizeof(struct E2setupFailureIEs));
1670          if(e2SetupFailure->protocolIEs.list.array[arrIdx] == NULLP)
1671          {
1672             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
1673             memAllocFailed = true;
1674             break;
1675          }
1676       }
1677
1678       if(memAllocFailed == true)
1679       {
1680           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
1681           break;
1682       }
1683
1684       /* Trans Id */
1685       arrIdx = 0;
1686       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
1687       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1688       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TransactionID;
1689       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
1690
1691       arrIdx++;
1692       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
1693       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1694       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_CauseE2;
1695       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.present = CauseE2_PR_protocol;
1696       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.protocol = CauseE2Protocol_unspecified;
1697
1698       arrIdx++;
1699       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
1700       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
1701       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TimeToWaitE2;
1702       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
1703
1704       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1705       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1706       encBufSize = 0;
1707       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
1708
1709       /* Check encode results */
1710       if(encRetVal.encoded == ENCODE_FAIL)
1711       {
1712          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Setup failure structure (at %s)\n",\
1713                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1714          break;
1715       }
1716       else
1717       {
1718          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Setup Failure\n");
1719          for(int i=0; i< encBufSize; i++)
1720          {
1721             DU_LOG("%x",encBuf[i]);
1722          }
1723       }
1724
1725       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
1726       {
1727          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Failure failed");
1728          break;
1729       }
1730       break;
1731    }
1732
1733    FreeE2SetupFailure(e2apMsg);
1734 }
1735
1736 /*******************************************************************
1737  *
1738  * @brief process the e2setup request 
1739  *
1740  * @details
1741  *
1742  *    Function : ProcE2SetupReq
1743  *
1744  * Functionality: process the e2setup request
1745  *
1746  * @return ROK     - success
1747  *         RFAILED - failure
1748  *
1749  ******************************************************************/
1750
1751 uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
1752 {
1753    uint8_t arrIdx = 0, e2NodeAddListIdx =0, duIdx = 0, transId =0, ranFuncIdx;
1754    DuDb    *duDb = NULLP;
1755    E2nodeComponentConfigAddition_List_t *e2NodeAddList;
1756    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
1757    RANfunction_ItemIEs_t *ranFuncItemIe;
1758    RANfunction_Item_t  *ranFunItem;
1759    RANfunctions_List_t *ranFunctionsList;
1760
1761    if(e2SetupReq)
1762    {
1763       if(e2SetupReq->protocolIEs.list.array)      
1764       {
1765          for(arrIdx=0; arrIdx<e2SetupReq->protocolIEs.list.count; arrIdx++)
1766          {
1767             if(e2SetupReq->protocolIEs.list.array[arrIdx])
1768             {
1769                switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
1770                {
1771                   case ProtocolIE_IDE2_id_TransactionID:
1772                      {
1773                         transId = e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; 
1774                         break;
1775                      }
1776                   case ProtocolIE_IDE2_id_GlobalE2node_ID:
1777                      {
1778                         if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID)
1779                         {
1780                             *duId =e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID->buf[0];
1781
1782                             SEARCH_DU_DB(duIdx, *duId, duDb); 
1783                             if(duDb == NULLP)
1784                             {
1785                                duDb = &ricCb.duInfo[ricCb.numDu];
1786                                ricCb.numDu++;
1787                             }
1788                             memset(duDb, 0, sizeof(DuDb));
1789                             duDb->duId = *duId;
1790                         }
1791                         break;
1792                      }
1793                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
1794                      {
1795                         ranFunctionsList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
1796
1797                         if(ranFunctionsList->list.array)
1798                         {
1799                            for(ranFuncIdx=0;ranFuncIdx<ranFunctionsList->list.count; ranFuncIdx++)
1800                            {
1801                               ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncIdx]; 
1802                               ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
1803                               duDb->ranFunction[ranFunItem->ranFunctionID-1].id = ranFunItem->ranFunctionID; 
1804                               duDb->ranFunction[ranFunItem->ranFunctionID-1].revisionCounter = ranFunItem->ranFunctionRevision; 
1805                               duDb->numOfRanFunction++;
1806                            }
1807                         }
1808                         break;
1809                      }
1810                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
1811                      {
1812                         e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;      
1813                         if(e2NodeAddList->list.array)
1814                         {
1815                            for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
1816                            {
1817                               if(e2NodeAddList->list.array[e2NodeAddListIdx])
1818                               {
1819                                  e2NodeAddItem = \
1820                                     (E2nodeComponentConfigAddition_ItemIEs_t *)e2NodeAddList->list.array[e2NodeAddListIdx];
1821                                  if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.\
1822                                     choice.e2nodeComponentInterfaceTypeF1)
1823                                  {
1824                                     duDb->e2NodeComponent.interfaceType = F1; 
1825                                     duDb->e2NodeComponent.componentId = \
1826                                        e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.\
1827                                        choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]; 
1828                                  }
1829                               }
1830                            }
1831                         }
1832                         break;
1833                      }
1834                      default:
1835                         break;
1836                   }
1837                }
1838             }
1839         }
1840    }
1841    
1842    if(BuildAndSendE2SetupRsp(duDb, transId) !=ROK)
1843    {
1844       DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 setup response");
1845       return RFAILED;
1846    }
1847    return ROK;   
1848 }
1849 /*******************************************************************
1850  *
1851  * @brief Deallocate the memory allocated for E2 Reset Response
1852  *
1853  * @details
1854  *
1855  *    Function : FreeE2ResetResponse
1856  *
1857  *    Functionality:
1858  *       - freeing the memory allocated for E2ResetResponse
1859  *
1860  * @params[in] E2AP_PDU_t *e2apMsg
1861  * @return ROK     - success
1862  *         RFAILED - failure
1863  *
1864  * ****************************************************************/
1865 void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg)
1866 {
1867    uint8_t ieIdx =0;
1868    ResetResponseE2_t *resetResponse;
1869
1870    if(e2apMsg != NULLP)
1871    {
1872       if(e2apMsg->choice.successfulOutcome != NULLP)
1873       {
1874          resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
1875          if(resetResponse->protocolIEs.list.array)
1876          {
1877             for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
1878             {
1879                if(resetResponse->protocolIEs.list.array[ieIdx])
1880                {
1881                   RIC_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
1882                }
1883             }
1884             RIC_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
1885          }
1886          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1887       }
1888       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1889    }
1890 }
1891
1892 /*******************************************************************
1893  *
1894  * @brief Buld and send the E2 Reset Response msg
1895  *
1896  * @details
1897  *
1898  *    Function : BuildAndSendE2ResetResponse
1899  *
1900  *    Functionality:
1901  *         - Buld and send the E2 Reset Response Message
1902  * @return ROK     - success
1903  *         RFAILED - failure
1904  *
1905  * ****************************************************************/
1906 uint8_t BuildAndSendResetResponse(uint32_t duId, uint8_t transId)
1907 {
1908    uint8_t           ieIdx = 0, elementCnt = 0;
1909    uint8_t           ret = RFAILED;
1910    E2AP_PDU_t        *e2apMsg = NULLP;
1911    ResetResponseE2_t *resetResponse;
1912    asn_enc_rval_t    encRetVal;       /* Encoder return value */
1913
1914    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
1915    do
1916    {
1917       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1918       if(e2apMsg == NULLP)
1919       {
1920          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
1921          break;
1922       }
1923       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
1924
1925       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1926       if(e2apMsg->choice.successfulOutcome == NULLP)
1927       {
1928          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
1929          RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1930          return RFAILED;
1931       }
1932  
1933       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
1934       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
1935       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
1936       resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
1937
1938       elementCnt = 1;
1939       resetResponse->protocolIEs.list.count = elementCnt;
1940       resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
1941       RIC_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
1942       if(!resetResponse->protocolIEs.list.array)
1943       {
1944          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
1945          break;
1946       }
1947
1948       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
1949       {
1950          RIC_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
1951          if(!resetResponse->protocolIEs.list.array[ieIdx])
1952          {
1953             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
1954             break;
1955          }
1956       }
1957       if(ieIdx < elementCnt)
1958          break;
1959
1960       ieIdx = 0; 
1961       resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
1962       resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
1963       resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
1964       resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
1965
1966       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1967
1968       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1969       encBufSize = 0;
1970       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
1971       if(encRetVal.encoded == ENCODE_FAIL)
1972       {
1973          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
1974                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1975          return RFAILED;
1976       }
1977       else
1978       {
1979          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
1980          for(int i=0; i< encBufSize; i++)
1981          {
1982             DU_LOG("%x",encBuf[i]);
1983          }
1984       }
1985
1986       /* Sending msg */
1987       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
1988       {
1989          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
1990          return RFAILED;
1991       }
1992
1993       ret = ROK;
1994       break;
1995    }while(true);
1996
1997    FreeE2ResetResponse(e2apMsg);
1998    return ROK;
1999 }
2000
2001 /*******************************************************************
2002  *
2003  * @brief process the E2 Reset Request
2004  *
2005  * @details
2006  *
2007  *    Function : ProcE2ResetReq
2008  *
2009  * Functionality: Process E2 Reset Request
2010  *
2011  * @return ROK     - success
2012  *         RFAILED - failure
2013  *
2014  ******************************************************************/
2015
2016 uint8_t ProcE2ResetReq(uint32_t duId, ResetRequestE2_t  *resetReq)
2017 {
2018    uint8_t ieIdx = 0, duIdx = 0;
2019    uint8_t transId = 0, cause = 0;
2020    DuDb    *duDb = NULLP;
2021
2022    if(resetReq)
2023    {
2024       if(resetReq->protocolIEs.list.array)
2025       {
2026          for(ieIdx=0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
2027          {
2028             if(resetReq->protocolIEs.list.array[ieIdx])
2029             {
2030                switch(resetReq->protocolIEs.list.array[ieIdx]->id)
2031                {
2032                   case ProtocolIE_IDE2_id_TransactionID:
2033                      transId = resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
2034                      break;
2035                   case ProtocolIE_IDE2_id_CauseE2:
2036                      DU_LOG("\nDEBUG  -->  E2AP : Reset reason %d", resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present);
2037                      switch(resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present)
2038                      {
2039                         case CauseE2_PR_NOTHING:
2040                            break;
2041                         case CauseE2_PR_ricRequest:
2042                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricRequest;
2043                            break;
2044                         case CauseE2_PR_ricService:
2045                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricService;
2046                            break;
2047                         case CauseE2_PR_e2Node:
2048                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.e2Node;
2049                            break;
2050                         case CauseE2_PR_transport:
2051                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.transport;
2052                            break;
2053                         case CauseE2_PR_protocol:
2054                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.protocol;
2055                            break;
2056                         case CauseE2_PR_misc:
2057                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.misc;
2058                            break;
2059                      }
2060                      DU_LOG("\nDEBUG  -->  E2AP : Reset cause %d", cause);
2061                      break;
2062                }
2063             }
2064          }
2065       }
2066    }
2067    BuildAndSendResetResponse(duId, transId);
2068    return ROK;
2069 }
2070
2071 /*******************************************************************
2072  *
2073  * @brief deallocate the memory allocated in building the
2074  *    Service Query message
2075  *
2076  * @details
2077  *
2078  *    Function : FreeRicServiceQuery 
2079  *
2080  *    Functionality: deallocate the memory allocated in building
2081  *    Ric Service Query message
2082  *
2083  * @params[in] E2AP_PDU_t *e2apMsg
2084  *
2085  * @return void
2086  * ****************************************************************/
2087
2088 void FreeRicServiceQuery(E2AP_PDU_t *e2apMsg)
2089 {
2090    uint8_t arrIdx = 0, ranFuncIdx=0;
2091    RANfunctionsID_List_t *ranFuncAcceptedList=NULL;
2092    RICserviceQuery_t *ricServiceQuery=NULL;
2093    
2094    if(e2apMsg)
2095    {
2096       if(e2apMsg->choice.initiatingMessage)
2097       {
2098          ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
2099          if(ricServiceQuery->protocolIEs.list.array)
2100          {
2101             for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
2102             {
2103                if(ricServiceQuery->protocolIEs.list.array[arrIdx])
2104                {
2105                   switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
2106                   {
2107                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
2108                         {
2109                            ranFuncAcceptedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
2110                            if(ranFuncAcceptedList->list.array)
2111                            {
2112                               for(ranFuncIdx=0;ranFuncIdx<ranFuncAcceptedList->list.count; ranFuncIdx++)
2113                               {
2114                                  RIC_FREE(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
2115                               }
2116                               RIC_FREE(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
2117                            }
2118                            break;
2119                         }
2120                      case RICserviceQuery_IEs__value_PR_TransactionID:
2121                         {
2122                            break;
2123                         }
2124                   }
2125                   RIC_FREE(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t)); 
2126                }
2127             }
2128             RIC_FREE(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
2129          }
2130          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2131       }
2132       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2133    }
2134 }
2135
2136 /*******************************************************************
2137  *
2138  * @brief build and send the ric service Query 
2139  *
2140  * @details
2141  *
2142  *    Function : BuildAndSendRicServiceQuery
2143  *
2144  * Functionality: build and send the ric service Query 
2145  * @return ROK     - success
2146  *         RFAILED - Acknowledge
2147  *
2148  ******************************************************************/
2149
2150 uint8_t BuildAndSendRicServiceQuery(DuDb *duDb)
2151 {
2152    uint8_t arrIdx;
2153    uint8_t elementCnt;
2154    uint8_t ret = RFAILED;
2155    bool  memAllocFailed = false;
2156    E2AP_PDU_t     *e2apMsg = NULL;
2157    asn_enc_rval_t encRetVal;
2158    RICserviceQuery_t *ricServiceQuery;
2159
2160    DU_LOG("\nINFO   -->  E2AP : Building Ric service Query\n");
2161    while(true)
2162    {
2163       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2164       if(e2apMsg == NULLP)
2165       {
2166          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2167          break;
2168       }
2169       e2apMsg->present =  E2AP_PDU_PR_initiatingMessage;
2170       RIC_ALLOC(e2apMsg->choice.initiatingMessage , sizeof(struct InitiatingMessageE2));
2171       if(e2apMsg->choice.initiatingMessage == NULLP)
2172       {
2173          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2174          break;
2175       }
2176
2177       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceQuery;
2178       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2179       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceQuery;
2180       ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
2181
2182       elementCnt = 1;
2183       /* Fill Accepted RAN function IE If Ran function information is stored in databse */
2184       if(duDb->numOfRanFunction)
2185          elementCnt++;
2186
2187       ricServiceQuery->protocolIEs.list.count = elementCnt;
2188       ricServiceQuery->protocolIEs.list.size  = elementCnt * sizeof(RICserviceQuery_IEs_t*);
2189
2190       RIC_ALLOC(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
2191       if(ricServiceQuery->protocolIEs.list.array == NULLP)
2192       {
2193          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2194          break;
2195       }
2196
2197       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2198       {
2199          RIC_ALLOC(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t));
2200          if(ricServiceQuery->protocolIEs.list.array[arrIdx] == NULLP)
2201          {
2202             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2203             memAllocFailed = true;
2204             break;
2205          }
2206       }
2207       if(memAllocFailed == true)
2208       {
2209          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2210          break;
2211       }
2212
2213       /* Trans Id */
2214       arrIdx = 0;
2215       ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2216       ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2217       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_TransactionID;
2218       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = assignTransactionId(duDb);
2219       
2220       if(duDb->numOfRanFunction)
2221       {
2222          /* Accepted RAN function Id */
2223          arrIdx++;
2224          ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
2225          ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2226          ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_RANfunctionsID_List;
2227          if(BuildRanFunctionAcceptedList(duDb, 0, NULL, &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceQuery)!=ROK)
2228          {
2229             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
2230             break;         
2231          }
2232       }
2233       
2234       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2235       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2236       encBufSize = 0;
2237       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2238
2239       /* Check encode results */
2240       if(encRetVal.encoded == ENCODE_FAIL)
2241       {
2242          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service Query structure (at %s)\n",\
2243                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2244          break;
2245       }
2246       else
2247       {
2248          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service Query\n");
2249          for(int i=0; i< encBufSize; i++)
2250          {
2251             DU_LOG("%x",encBuf[i]);
2252          }
2253       }
2254
2255       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
2256       {
2257          DU_LOG("\nERROR  -->  E2AP : Sending of RIC service  Query failed");
2258          break;
2259       }
2260
2261       ret =ROK;
2262       break;
2263    }
2264    FreeRicServiceQuery(e2apMsg);
2265    return ret;
2266 }
2267
2268 /*******************************************************************
2269  *
2270  * @brief deallocate the memory allocated in RicServiceUpdateFailure
2271  *
2272  * @details
2273  *
2274  *    Function : FreeRicServiceUpdateFailure 
2275  *
2276  *    Functionality: deallocate the memory allocated in RicServiceUpdatefailure
2277  *
2278  * @params[in] E2AP_PDU_t *e2apMsg
2279  *
2280  * @return void
2281  * ****************************************************************/
2282
2283 void FreeRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
2284 {
2285    uint8_t arrIdx = 0;
2286    RICserviceUpdateFailure_t *ricServiceUpdateFailure=NULL;
2287    
2288    if(e2apMsg)
2289    {
2290       if(e2apMsg->choice.unsuccessfulOutcome)
2291       {
2292          ricServiceUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
2293          if(ricServiceUpdateFailure->protocolIEs.list.array)
2294          {
2295             for(arrIdx=0; arrIdx<ricServiceUpdateFailure->protocolIEs.list.count; arrIdx++)
2296             {
2297                RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t)); 
2298             }
2299             RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array, ricServiceUpdateFailure->protocolIEs.list.size);
2300          }
2301          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
2302       }
2303       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2304    }
2305 }
2306
2307 /*******************************************************************
2308  *
2309  * @brief fill E2 failure cause 
2310  *
2311  * @details
2312  *
2313  *    Function : fillE2FailureCause
2314  *
2315  * Functionality: fill E2 failure cause
2316  * @return ROK     - success
2317  *         RFAILED - failure
2318  *
2319  ******************************************************************/
2320
2321 void fillE2FailureCause(CauseE2_t *cause, CauseE2_PR causePresent, uint8_t reason)
2322 {
2323    cause->present = causePresent;
2324
2325    switch(cause->present)
2326    {
2327       case CauseE2_PR_ricRequest:
2328          cause->choice.ricRequest = reason;
2329          break;
2330       case CauseE2_PR_ricService:
2331          cause->choice.ricService = reason;
2332          break;
2333       case CauseE2_PR_e2Node:
2334          cause->choice.e2Node = reason;
2335          break;
2336       case CauseE2_PR_transport:
2337          cause->choice.transport = reason;
2338          break;
2339       case CauseE2_PR_protocol:
2340          cause->choice.protocol = reason;
2341          break;
2342       case CauseE2_PR_misc:
2343          cause->choice.misc = reason;
2344          break;
2345       default:
2346          cause->choice.misc = CauseE2Misc_unspecified;
2347          break;
2348    }
2349 }
2350
2351 /*******************************************************************
2352  *
2353  * @brief build and send the ric service update failure 
2354  *
2355  * @details
2356  *
2357  *    Function : BuildAndSendRicServiceUpdateFailure
2358  *
2359  * Functionality: build and send the ric service update failure 
2360  * @return ROK     - success
2361  *         RFAILED - failure
2362  *
2363  ******************************************************************/
2364
2365 uint8_t BuildAndSendRicServiceUpdateFailure(uint32_t duId, int8_t transId, CauseE2_PR causePresent, uint8_t reason)
2366 {
2367
2368    E2AP_PDU_t         *e2apMsg = NULL;
2369    asn_enc_rval_t     encRetVal;
2370    uint8_t            ret = RFAILED;
2371    uint8_t            arrIdx=0;
2372    uint8_t            elementCnt=0;
2373    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
2374
2375    DU_LOG("\nINFO   -->  E2AP : Building Ric service update failure\n");
2376    while(true)
2377    {
2378       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2379       if(e2apMsg == NULLP)
2380       {
2381          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2382          break;
2383       }
2384       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
2385       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
2386       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
2387       {
2388          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2389          break;
2390       }
2391
2392       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
2393       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
2394       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure;
2395       ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
2396
2397       elementCnt = 3;
2398       ricServiceFailure->protocolIEs.list.count = elementCnt;
2399       ricServiceFailure->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateFailure_IEs_t *);
2400
2401       RIC_ALLOC(ricServiceFailure->protocolIEs.list.array, ricServiceFailure->protocolIEs.list.size);
2402       if(ricServiceFailure->protocolIEs.list.array == NULLP)
2403       {
2404          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2405          break;
2406       }
2407
2408       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2409       {
2410          RIC_ALLOC(ricServiceFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t));
2411          if(ricServiceFailure->protocolIEs.list.array[arrIdx] == NULLP)
2412          {
2413             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2414             break;
2415          }
2416       }
2417       if(arrIdx<elementCnt)
2418       {
2419          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2420          break;
2421       }
2422
2423       /* Trans Id */
2424       arrIdx = 0;
2425       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2426       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2427       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TransactionID;
2428       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
2429
2430       arrIdx++;
2431       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
2432       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2433       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_CauseE2;
2434       fillE2FailureCause(&ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, causePresent, reason);
2435
2436       arrIdx++;
2437       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
2438       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
2439       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TimeToWaitE2;
2440       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
2441
2442       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2443       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2444       encBufSize = 0;
2445       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2446
2447       /* Check encode results */
2448       if(encRetVal.encoded == ENCODE_FAIL)
2449       {
2450          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update failure structure (at %s)\n",\
2451                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2452          break;
2453       }
2454       else
2455       {
2456          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Failure\n");
2457          for(int i=0; i< encBufSize; i++)
2458          {
2459             DU_LOG("%x",encBuf[i]);
2460          }
2461       }
2462
2463       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
2464       {
2465          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update failed");
2466          break;
2467       }
2468       ret = ROK;
2469       break;
2470    }
2471
2472    FreeRicServiceUpdateFailure(e2apMsg);
2473    return ret;
2474 }
2475
2476
2477 /*******************************************************************
2478  *
2479  * @brief deallocate the memory allocated in RicServiceUpdateAck(
2480  *
2481  * @details
2482  *
2483  *    Function : FreeRicServiceUpdateAck 
2484  *
2485  *    Functionality: deallocate the memory allocated in RicServiceUpdateAck
2486  *
2487  * @params[in] E2AP_PDU_t *e2apMsg
2488  *
2489  * @return void
2490  * ****************************************************************/
2491
2492 void FreeRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
2493 {
2494    uint8_t arrIdx = 0, ranFuncIdx=0;
2495    RANfunctionsID_List_t *acceptedList=NULL;
2496    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
2497    RANfunctionsIDcause_List_t  *rejectedList=NULL;
2498
2499    if(e2apMsg)
2500    {
2501       if(e2apMsg->choice.successfulOutcome)
2502       {
2503          ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
2504          if(ricServiceUpdateAck->protocolIEs.list.array)
2505          {
2506             for(arrIdx=0; arrIdx<ricServiceUpdateAck->protocolIEs.list.count; arrIdx++)
2507             {
2508                if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx])
2509                {
2510                   switch(ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id)
2511                   {
2512                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
2513                         {
2514                            acceptedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
2515                            if(acceptedList->list.array)
2516                            {
2517                               for(ranFuncIdx=0;ranFuncIdx<acceptedList->list.count; ranFuncIdx++)
2518                               {
2519                                  RIC_FREE(acceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
2520                               }
2521                               RIC_FREE(acceptedList->list.array, acceptedList->list.size);
2522                            }
2523                            break;
2524                         }
2525
2526                      case ProtocolIE_IDE2_id_RANfunctionsRejected:
2527                         {
2528                            rejectedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
2529                            if(rejectedList->list.array)
2530                            {
2531                               for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
2532                               {
2533                                  RIC_FREE(rejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
2534                               }
2535                               RIC_FREE(rejectedList->list.array, rejectedList->list.size);
2536                            }
2537                            break;
2538                         }
2539                   }
2540                   RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t)); 
2541                }
2542             }
2543             RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
2544          }
2545          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2546       }
2547       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2548    }
2549 }
2550
2551 /*******************************************************************
2552  *
2553  * @brief Build RAN function rejected list
2554  *
2555  * @details
2556  *
2557  *    Function : BuildRanFunctionRejectedList
2558  *
2559  *    Functionality: Build RAN function rejected list 
2560  *
2561  * @params[in] 
2562  *    Count of ran functions to be rejected in the list 
2563  *    Received list of RAN functions
2564  *
2565  * @return ROK - success
2566  *         RFAILED - failure
2567  * ****************************************************************/
2568
2569 uint8_t BuildRanFunctionRejectedList(uint8_t count, RanFunction *ranFunRejectedList, RANfunctionsIDcause_List_t *ranFuncRejectedList)
2570 {
2571    uint8_t ranFuncIdx = 0;
2572    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
2573    
2574    ranFuncRejectedList->list.count = count;
2575    
2576    ranFuncRejectedList->list.size = ranFuncRejectedList->list.count*sizeof(RANfunctionIDcause_ItemIEs_t*);
2577    RIC_ALLOC(ranFuncRejectedList->list.array, ranFuncRejectedList->list.size);
2578    if(ranFuncRejectedList->list.array == NULLP)
2579    {
2580       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array");
2581       return RFAILED;
2582    }
2583    
2584    for(ranFuncIdx = 0; ranFuncIdx< ranFuncRejectedList->list.count; ranFuncIdx++)
2585    {
2586       RIC_ALLOC(ranFuncRejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
2587       if(ranFuncRejectedList->list.array[ranFuncIdx] == NULLP)
2588       {
2589          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array item");
2590          return RFAILED;
2591       }
2592       ranFuncRejectedItemIe = (RANfunctionIDcause_ItemIEs_t*)ranFuncRejectedList->list.array[ranFuncIdx];
2593       ranFuncRejectedItemIe->id = ProtocolIE_IDE2_id_RANfunctionIEcause_Item;
2594       ranFuncRejectedItemIe->criticality= CriticalityE2_ignore;
2595       ranFuncRejectedItemIe->value.present = RANfunctionIDcause_ItemIEs__value_PR_RANfunctionIDcause_Item;
2596       ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID = ranFunRejectedList[ranFuncIdx].id;
2597       fillE2FailureCause(&ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.cause, CauseE2_PR_ricService,\
2598             CauseE2RICservice_ran_function_not_supported);
2599    }
2600    
2601    return ROK;
2602 }
2603
2604 /*******************************************************************
2605  *
2606  * @brief build and send the ric service update Acknowledge 
2607  *
2608  * @details
2609  *
2610  *    Function : BuildAndSendRicServiceUpdateAcknowledge
2611  *
2612  * Functionality: build and send the ric service update Acknowledge 
2613  * @return ROK     - success
2614  *         RFAILED - Acknowledge
2615  *
2616  ******************************************************************/
2617
2618 uint8_t BuildAndSendRicServiceUpdateAcknowledge(DuDb *duDb, int8_t transId, RicTmpRanFunList ricRanFuncList)
2619 {
2620    E2AP_PDU_t         *e2apMsg = NULL;
2621    asn_enc_rval_t     encRetVal;
2622    uint8_t  arrIdx=0, elementCnt=0, ret=RFAILED;;
2623    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
2624
2625    DU_LOG("\nINFO   -->  E2AP : Building Ric service update Acknowledge\n");
2626    while(true)
2627    {
2628       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2629       if(e2apMsg == NULLP)
2630       {
2631          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2632          break;
2633       }
2634       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
2635       RIC_ALLOC(e2apMsg->choice.successfulOutcome , sizeof(struct SuccessfulOutcomeE2));
2636       if(e2apMsg->choice.successfulOutcome == NULLP)
2637       {
2638          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2639          break;
2640       }
2641
2642       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
2643       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
2644       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge;
2645       ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
2646
2647       elementCnt = 1;
2648       if(ricRanFuncList.numOfRanFunAccepted)
2649          elementCnt++;
2650       if(ricRanFuncList.numOfRanFuneRejected)
2651          elementCnt++;
2652       
2653
2654       ricServiceUpdateAck->protocolIEs.list.count = elementCnt;
2655       ricServiceUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateAcknowledge_IEs_t*);
2656
2657       RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
2658       if(ricServiceUpdateAck->protocolIEs.list.array == NULLP)
2659       {
2660          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2661          break;
2662       }
2663
2664       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2665       {
2666          RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t));
2667          if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
2668          {
2669             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2670             break;
2671          }
2672       }
2673       if(arrIdx<elementCnt)
2674       {
2675          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2676          break;
2677       }
2678
2679       /* Trans Id */
2680       arrIdx = 0;
2681       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2682       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2683       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_TransactionID;
2684       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
2685
2686       if(ricRanFuncList.numOfRanFunAccepted)
2687       {
2688          /* Accepted RAN function List */
2689          arrIdx++;
2690          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
2691          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2692          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsID_List;
2693          if(BuildRanFunctionAcceptedList(duDb, ricRanFuncList.numOfRanFunAccepted, ricRanFuncList.ranFunAcceptedList,\
2694          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceUpdate)!=ROK)       
2695          {
2696             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
2697             break;         
2698          }
2699       }
2700       
2701       if(ricRanFuncList.numOfRanFuneRejected)
2702       {
2703          /* RAN Functions Rejected List */
2704          arrIdx++;
2705          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsRejected;
2706          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2707          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsIDcause_List;
2708          if(BuildRanFunctionRejectedList(ricRanFuncList.numOfRanFuneRejected, ricRanFuncList.ranFunRejectedList, \
2709          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List)!=ROK)       
2710          {
2711             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function rejected list");
2712             break;         
2713          }
2714       }
2715       
2716       
2717       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2718       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2719       encBufSize = 0;
2720       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2721
2722       /* Check encode results */
2723       if(encRetVal.encoded == ENCODE_FAIL)
2724       {
2725          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update Acknowledge structure (at %s)\n",\
2726                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2727          break;
2728       }
2729       else
2730       {
2731          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Acknowledge\n");
2732          for(int i=0; i< encBufSize; i++)
2733          {
2734             DU_LOG("%x",encBuf[i]);
2735          }
2736       }
2737
2738       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
2739       {
2740          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update ack failed");
2741          break;
2742       }
2743       ret =ROK;
2744       break;
2745    }
2746    FreeRicServiceUpdateAck(e2apMsg);
2747    return ret; 
2748 }
2749
2750 /*******************************************************************
2751  *
2752  * @brief process the RIC service update 
2753  *
2754  * @details
2755  *
2756  *    Function : ProcRicserviceUpdate 
2757  *
2758  * Functionality: process the RIC service update 
2759  *
2760  * @return ROK     - success
2761  *         RFAILED - failure
2762  *
2763  ******************************************************************/
2764
2765 void ProcRicServiceUpdate(uint32_t duId, RICserviceUpdate_t *ricServiceUpdate)
2766 {
2767    RicTmpRanFunList ricRanFuncList;
2768    DuDb    *duDb = NULLP;
2769    int8_t transId =-1;
2770    uint8_t duIdx = 0, elementCnt =0, arrIdx = 0; 
2771    uint16_t ranFuncIdx = 0, failedRanFuncCount=0, recvdRanFuncCount=0;
2772    RANfunction_ItemIEs_t *ranFuncItemIe =NULL;
2773    RANfunction_Item_t  *ranFuncItem =NULL;
2774    RANfunctionID_Item_t  *ranFuncIdItem=NULL;
2775    RANfunctions_List_t *ranFuncList=NULL;
2776    RANfunctionsID_List_t *deleteList=NULL;
2777    RANfunctionID_ItemIEs_t *delRanFuncItem=NULL;
2778
2779    SEARCH_DU_DB(duIdx, duId, duDb); 
2780    if(duDb == NULLP)
2781    {
2782       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
2783       return;
2784    }
2785    memset(&ricRanFuncList, 0, sizeof(RicTmpRanFunList)); 
2786
2787    if(!ricServiceUpdate)
2788    {
2789       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate pointer is null"); 
2790       return;
2791    }
2792
2793    if(!ricServiceUpdate->protocolIEs.list.array)      
2794    {
2795       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array pointer is null");
2796       return;
2797    }
2798    elementCnt = ricServiceUpdate->protocolIEs.list.count;
2799    for(arrIdx=0; arrIdx<ricServiceUpdate->protocolIEs.list.count; arrIdx++)
2800    {
2801       if(!ricServiceUpdate->protocolIEs.list.array[arrIdx])
2802       {
2803          DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array idx %d pointer is null",arrIdx);
2804          return;
2805       }
2806
2807       switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
2808       {
2809          case ProtocolIE_IDE2_id_TransactionID:
2810             {
2811                transId = ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
2812
2813                if(transId < 0 || transId > 255)
2814                {
2815                   DU_LOG("\nERROR  -->  E2AP : Received invalid transId %d",transId);
2816                   return;
2817                }
2818                break;
2819             }
2820
2821          case ProtocolIE_IDE2_id_RANfunctionsAdded:
2822             {
2823                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
2824
2825                if(ranFuncList->list.array)
2826                {
2827                   for(ranFuncIdx=0;ranFuncIdx<ranFuncList->list.count; ranFuncIdx++)
2828                   {
2829                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx]; 
2830                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
2831
2832                      /* Adding the ran function in temporary list */
2833                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
2834                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
2835                      ricRanFuncList.numOfRanFunAccepted++;
2836
2837                      /* Adding the new ran function in DB*/
2838                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].id = ranFuncItem->ranFunctionID;
2839                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
2840                      duDb->numOfRanFunction++;
2841
2842                      /* Calculating total number of ran fuctions which are received for addition */
2843                      recvdRanFuncCount++;
2844                   }
2845                }
2846                break;
2847             }
2848
2849          case ProtocolIE_IDE2_id_RANfunctionsModified:
2850             {
2851
2852                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List; 
2853                if(ranFuncList->list.array)
2854                {
2855                   for(ranFuncIdx = 0; ranFuncIdx< ranFuncList->list.count; ranFuncIdx++)
2856                   {
2857                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx];
2858                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
2859                      if(duDb->ranFunction[ranFuncItem->ranFunctionID-1].id != ranFuncItem->ranFunctionID)
2860                      {
2861                         /* Calculating total number of ran fuctions which are not present */
2862                         failedRanFuncCount++;
2863
2864                         /* Adding the ran function in temporary list */
2865                         ricRanFuncList.ranFunRejectedList[ricRanFuncList.numOfRanFuneRejected].id =  ranFuncItem->ranFunctionID; 
2866                         ricRanFuncList.numOfRanFuneRejected++;
2867                      }
2868                      else
2869                      {
2870
2871                         /* Adding the ran function in temporary list */
2872                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
2873                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
2874                         ricRanFuncList.numOfRanFunAccepted++;
2875
2876                         /* Updating the new ran function in DB*/
2877                         duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
2878                      }
2879                      /* Calculating total number of ran fuctions which are received for modification */
2880                      recvdRanFuncCount++;
2881                   }
2882                }
2883                break;
2884             }
2885          case ProtocolIE_IDE2_id_RANfunctionsDeleted:
2886             {
2887
2888                deleteList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List; 
2889                if(deleteList->list.array)
2890                {
2891                   for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
2892                   {
2893                      delRanFuncItem  = (RANfunctionID_ItemIEs_t*) deleteList->list.array[ranFuncIdx];
2894                      ranFuncIdItem = &delRanFuncItem->value.choice.RANfunctionID_Item;
2895                      if(duDb->ranFunction[ranFuncIdItem->ranFunctionID-1].id == ranFuncIdItem->ranFunctionID)
2896                      {
2897                         memset(&duDb->ranFunction[ranFuncIdItem->ranFunctionID-1], 0, sizeof(RanFunction));
2898                         duDb->numOfRanFunction--; 
2899                      }
2900
2901                      /* Calculating total number of ran fuctions which are received for deletion */
2902                      recvdRanFuncCount++;
2903                   }
2904                }
2905                break;
2906             }
2907
2908          default:
2909             {
2910                DU_LOG("\nERROR  -->  E2AP : IE [%ld] is not supported",ricServiceUpdate->protocolIEs.list.array[arrIdx]->id);
2911                break;
2912             }
2913       }
2914    }
2915    
2916    /* Sending RIC Service Update Failed if all RAN Functions received fail or if any IE processing fails
2917     * Else sending RIC Service Update Acknowledge */  
2918    if((elementCnt > arrIdx) ||((recvdRanFuncCount > 0) && (recvdRanFuncCount == failedRanFuncCount)))
2919    {
2920       if(BuildAndSendRicServiceUpdateFailure(duDb->duId, transId, CauseE2_PR_misc, CauseE2Misc_unspecified) != ROK)
2921       {
2922          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update Failure");
2923          return;
2924       }
2925    }
2926    else
2927    {
2928       if(BuildAndSendRicServiceUpdateAcknowledge(duDb, transId, ricRanFuncList) != ROK)
2929       {
2930          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update acknowledge");
2931          return;
2932       }
2933    }
2934 }
2935
2936 /*******************************************************************
2937  *
2938  * @brief Processing RIC subscription failure from DU
2939  *
2940  * @details
2941  *
2942  *    Function : ProcRicSubscriptionFailure
2943  *
2944  * Functionality: Processing RIC subscription failure from DU
2945  *
2946  * @param  ID of DU from which message was sent
2947  *         RIC Subscription failure message
2948  * @return ROK     - success
2949  *         RFAILED - failure
2950  *
2951  ******************************************************************/
2952 uint8_t ProcRicSubscriptionFailure(uint32_t duId, RICsubscriptionFailure_t *ricSubscriptionFailure)
2953 {
2954    uint8_t ieIdx = 0, duIdx = 0, subsIdx = 0;
2955    uint8_t ranFuncId = 0;
2956    bool   ricReqIdDecoded = false;
2957    DuDb    *duDb = NULLP;
2958    RanFunction *ranFuncDb = NULLP;
2959    RicRequestId ricReqId;
2960    RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
2961
2962    DU_LOG("\nINFO  -->  E2AP : Received RIC subscription failure");
2963
2964    SEARCH_DU_DB(duIdx, duId, duDb);
2965    if(duDb == NULLP)
2966    {
2967       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
2968       return RFAILED;
2969    }
2970
2971    memset(&ricReqId, 0, sizeof(RicRequestId));
2972    if(ricSubscriptionFailure)
2973    {
2974       if(ricSubscriptionFailure->protocolIEs.list.array)
2975       {
2976          for(ieIdx=0; ieIdx<ricSubscriptionFailure->protocolIEs.list.count; ieIdx++)
2977          {
2978             if(ricSubscriptionFailure->protocolIEs.list.array[ieIdx])
2979             {
2980                ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[ieIdx];
2981                switch(ricSubscriptionFailure->protocolIEs.list.array[ieIdx]->id)
2982                {
2983                   case ProtocolIE_IDE2_id_RICrequestID:
2984                   {
2985                      ricReqId.requestorId = ricSubsFailIe->value.choice.RICrequestID.ricRequestorID;
2986                      ricReqId.instanceId = ricSubsFailIe->value.choice.RICrequestID.ricInstanceID;
2987                      ricReqIdDecoded = true;
2988                      break;
2989                   }
2990                   case ProtocolIE_IDE2_id_RANfunctionID:
2991                   {
2992                      ranFuncId = ricSubsFailIe->value.choice.RANfunctionID;
2993                      if(duDb->ranFunction[ranFuncId-1].id == ranFuncId)
2994                      {
2995                         ranFuncDb = &duDb->ranFunction[ranFuncId-1];
2996                      }
2997                      break; 
2998                   }
2999                   case ProtocolIE_IDE2_id_CauseE2:
3000                   default:
3001                      /* No handling required as of now since this is a stub */
3002                      break;
3003
3004                }
3005             }
3006          }
3007
3008          /* Remove subscription entry from RAN Function */
3009          if(ranFuncDb && ricReqIdDecoded)
3010          {
3011             for(subsIdx = 0; subsIdx < ranFuncDb->numOfSubscription; subsIdx++)
3012             {
3013                if((ranFuncDb->subscriptionList[subsIdx].requestId.requestorId == ricReqId.requestorId) &&
3014                      (ranFuncDb->subscriptionList[subsIdx].requestId.instanceId == ricReqId.instanceId))
3015                {
3016                   memset(&ranFuncDb->subscriptionList[subsIdx], 0, sizeof(RicSubscription));
3017                   break;
3018                }
3019             }
3020          }
3021       }
3022    }
3023    return ROK;
3024 }
3025
3026 /*******************************************************************
3027  *
3028  * @brief Free the ErrorIndication Message
3029  *
3030  * @details
3031  *
3032  *    Function : FreeRicIndication
3033  *
3034  * Functionality: Free the ErrorIndication Message
3035  *
3036  * @return void
3037  *
3038  *
3039  ******************************************************************/
3040 void FreeErrorIndication(E2AP_PDU_t  *e2apMsg)
3041 {
3042    uint8_t arrIdx = 0;
3043    ErrorIndicationE2_t *errorIndicationMsg= NULLP;
3044
3045    if(e2apMsg != NULLP)
3046    {
3047       if(e2apMsg->choice.initiatingMessage != NULLP)
3048       {
3049          errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
3050          if(errorIndicationMsg!= NULLP)
3051          {
3052             if(errorIndicationMsg->protocolIEs.list.array != NULLP)
3053             {
3054                for(arrIdx=0; arrIdx<errorIndicationMsg->protocolIEs.list.count; arrIdx++)
3055                {
3056                   RIC_FREE(errorIndicationMsg->protocolIEs.list.array[arrIdx],sizeof(ErrorIndicationE2_t));
3057                }
3058                RIC_FREE(errorIndicationMsg->protocolIEs.list.array,errorIndicationMsg->protocolIEs.list.size);
3059             }
3060          }
3061          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3062       }
3063       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3064    }
3065 }
3066
3067
3068 /*******************************************************************
3069  *
3070  * @brief Builds and Send the ErrorIndication Message
3071  *
3072  * @details
3073  *
3074  *    Function : BuildAndSendErrorIndication
3075  *
3076  * Functionality:Fills the ErrorIndication Message
3077  *
3078  * @params[in] 
3079  *    DU id
3080  *    Trans id
3081  *    Ric req id
3082  *    Ran function id
3083  *    Reason of failure
3084  * @return ROK     - success
3085  *         RFAILED - failure
3086  *
3087  ******************************************************************/
3088
3089 uint8_t BuildAndSendErrorIndication(uint32_t duId, int8_t transId, RicRequestId requestId, uint16_t ranFuncId, uint8_t reason)
3090 {
3091    uint8_t elementCnt =0, arrIdx=0, ret = RFAILED;
3092    E2AP_PDU_t         *e2apMsg = NULLP;
3093    ErrorIndicationE2_t *errorIndicationMsg=NULLP;
3094    asn_enc_rval_t     encRetVal;        /* Encoder return value */
3095
3096    while(true)
3097    {
3098       DU_LOG("\nINFO   -->  E2AP : Building Error Indication Message\n");
3099
3100       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3101       if(e2apMsg == NULLP)
3102       {
3103          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
3104          break;
3105       }
3106
3107       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
3108       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3109       if(e2apMsg->choice.initiatingMessage == NULLP)
3110       {
3111          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
3112          break;
3113       }
3114       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_ErrorIndicationE2;
3115       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
3116       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ErrorIndicationE2;
3117
3118       errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
3119
3120       /* Element count is 2 for TransactionID/RICrequestID and Cause.
3121        * If the RAN function id is present, the count will be increased.*/
3122       elementCnt = 2;
3123       if(ranFuncId>0)
3124          elementCnt++;
3125
3126       errorIndicationMsg->protocolIEs.list.count = elementCnt;
3127       errorIndicationMsg->protocolIEs.list.size = elementCnt * sizeof(ErrorIndicationE2_IEs_t*);
3128
3129       /* Initialize the E2Setup members */
3130       RIC_ALLOC(errorIndicationMsg->protocolIEs.list.array, errorIndicationMsg->protocolIEs.list.size);
3131       if(errorIndicationMsg->protocolIEs.list.array == NULLP)
3132       {
3133          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements in %s at line %d",__func__, __LINE__);
3134          break;
3135       }
3136       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
3137       {
3138          RIC_ALLOC(errorIndicationMsg->protocolIEs.list.array[arrIdx], sizeof(ErrorIndicationE2_IEs_t));
3139          if(errorIndicationMsg->protocolIEs.list.array[arrIdx] == NULLP)
3140          {
3141             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array Idx %d in %s at line %d",arrIdx,__func__, __LINE__);
3142             break;
3143          }
3144       }
3145       if(arrIdx < elementCnt)
3146          break;
3147
3148       arrIdx = 0;
3149
3150       if(transId >=0 && transId<=255)
3151       {
3152          /* TransactionID */
3153          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
3154          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3155          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_TransactionID;
3156          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
3157       }
3158       else
3159       {
3160          /* RICrequestID */
3161          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RICrequestID;
3162          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3163          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RICrequestID;
3164          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricRequestorID = requestId.requestorId;
3165          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricInstanceID = requestId.instanceId;
3166       }
3167       
3168       if(ranFuncId>0)
3169       {
3170          /* RAN Function ID */
3171          arrIdx++;
3172          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionID;
3173          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3174          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RANfunctionID;
3175          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionID = ranFuncId;
3176       }
3177      
3178       /* Cause */
3179       arrIdx++;
3180       errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
3181       errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
3182       errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2;
3183       fillE2FailureCause(&errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, CauseE2_PR_misc, reason);
3184
3185
3186       /* Prints the Msg formed */
3187       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3188       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3189       encBufSize = 0;
3190       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
3191             encBuf);
3192       if(encRetVal.encoded == ENCODE_FAIL)
3193       {
3194          DU_LOG("\nERROR  -->  E2AP : Could not encode Error Indication Message (at %s)\n",\
3195                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3196          break;
3197       }
3198       else
3199       {
3200          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for Error Indication Message \n");
3201 #ifdef DEBUG_ASN_PRINT
3202          for(int i=0; i< encBufSize; i++)
3203          {
3204             printf("%x",encBuf[i]);
3205          }
3206 #endif
3207       }
3208
3209       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
3210       {
3211          DU_LOG("\nINFO   -->  E2AP : Sending Error Indication Message");
3212
3213       }
3214       ret = ROK;
3215       break;
3216    }
3217    FreeErrorIndication(e2apMsg);
3218    return ret;
3219 }
3220
3221 /*******************************************************************
3222 *
3223 * @brief Handles received E2AP message and sends back response  
3224 *
3225 * @details
3226 *
3227 *    Function : E2APMsgHdlr
3228 *
3229 *    Functionality:
3230 *         - Decodes received E2AP control message
3231 *         - Prepares response message, encodes and sends to SCTP
3232 *
3233 * @params[in] 
3234 * @return ROK     - success
3235 *         RFAILED - failure
3236 *
3237 * ****************************************************************/
3238 void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
3239 {
3240    int             i;
3241    char            *recvBuf;
3242    MsgLen          copyCnt;
3243    MsgLen          recvBufLen;
3244    E2AP_PDU_t      *e2apMsg;
3245    asn_dec_rval_t  rval; /* Decoder return value */
3246    E2AP_PDU_t      e2apasnmsg ;
3247  
3248    DU_LOG("\nINFO  -->  E2AP : Received E2AP message buffer");
3249    ODU_PRINT_MSG(mBuf, 0,0);
3250  
3251    /* Copy mBuf into char array to decode it */
3252    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
3253    RIC_ALLOC(recvBuf, (Size)recvBufLen);
3254
3255    if(recvBuf == NULLP)
3256    {
3257       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
3258       return;
3259    }
3260    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
3261    {
3262       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
3263       return;
3264    }
3265
3266    DU_LOG("\nDEBUG  -->  E2AP : Received flat buffer to be decoded : ");
3267    for(i=0; i< recvBufLen; i++)
3268    {
3269         DU_LOG("%x",recvBuf[i]);
3270    }
3271
3272    /* Decoding flat buffer into E2AP messsage */
3273    e2apMsg = &e2apasnmsg;
3274    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
3275
3276    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
3277    RIC_FREE(recvBuf, (Size)recvBufLen);
3278
3279    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
3280    {
3281       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
3282       return;
3283    }
3284    DU_LOG("\n");
3285    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3286
3287    switch(e2apMsg->present)
3288    {
3289       case E2AP_PDU_PR_initiatingMessage:
3290          {
3291             switch(e2apMsg->choice.initiatingMessage->value.present)
3292             {
3293                case InitiatingMessageE2__value_PR_E2setupRequest:
3294                   {
3295                      DU_LOG("\nINFO  -->  E2AP : E2 setup request received");
3296                      ProcE2SetupReq(duId, &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest);
3297                      break;
3298                   }
3299                case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate:
3300                   {
3301                      DU_LOG("\nINFO  -->  E2AP : E2 node config update received");
3302                      ProcE2NodeConfigUpdate(*duId, &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate);
3303                      break;
3304                   }
3305                case InitiatingMessageE2__value_PR_ResetRequestE2:
3306                   {
3307                      DU_LOG("\nINFO  -->  E2AP : E2 Reset Request received");
3308                      ProcE2ResetReq(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2);
3309                      break;
3310                   }
3311                case InitiatingMessageE2__value_PR_RICindication:
3312                   {
3313                      DU_LOG("\nINFO  -->  E2AP : RIC Indication received");
3314                      break;
3315                   }
3316                case InitiatingMessageE2__value_PR_RICserviceUpdate:
3317                   {
3318                      DU_LOG("\nINFO  -->  E2AP : RIC Service update received");
3319                      ProcRicServiceUpdate(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate);
3320                      break;
3321                   }
3322                case InitiatingMessageE2__value_PR_ErrorIndicationE2:
3323                   {
3324                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
3325                      break;
3326                   }
3327                default:
3328                   {
3329                      DU_LOG("\nERROR  -->  E2AP : Invalid type of intiating message [%d]", \
3330                         e2apMsg->choice.initiatingMessage->value.present);
3331                      return;
3332                   }
3333             }/* End of switch(initiatingMessage) */
3334             break;
3335          }
3336       case E2AP_PDU_PR_successfulOutcome: 
3337          {
3338             switch(e2apMsg->choice.successfulOutcome->value.present)
3339             {
3340                case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:  
3341                   {
3342                      ProcRicSubscriptionResponse(*duId, \
3343                         &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse);
3344                      break;
3345                   }
3346                default:
3347                   {
3348                      DU_LOG("\nERROR  -->  E2AP : Invalid type of successfulOutcome message [%d]", \
3349                         e2apMsg->choice.successfulOutcome->value.present);
3350                      return;
3351                   }
3352                   break;
3353             }
3354             break; 
3355          }
3356          case E2AP_PDU_PR_unsuccessfulOutcome:
3357          {
3358             switch(e2apMsg->choice.successfulOutcome->value.present)
3359             {
3360                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure:
3361                   {
3362                      ProcRicSubscriptionFailure(*duId, \
3363                         &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure);
3364                      break;
3365                   }
3366                default:
3367                   {
3368                      DU_LOG("\nERROR  -->  E2AP : Invalid type of unsuccessfulOutcome message [%d]", \
3369                         e2apMsg->choice.unsuccessfulOutcome->value.present);
3370                      return;
3371                   }
3372             }
3373             break;
3374          }
3375       default:
3376          {
3377             DU_LOG("\nERROR  -->  E2AP : Invalid type message type ");
3378             return;
3379          }
3380
3381    }/* End of switch(e2apMsg->present) */
3382 } /* End of E2APMsgHdlr */
3383
3384
3385 /**********************************************************************
3386   End of file
3387  **********************************************************************/