[Epic-ID: ODUHIGH-516][Task-ID: 527] Implementation of E2 Node Configuration Update...
[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-1].id = \
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-1], 0, sizeof(ActionInfo));
1135    return RFAILED;
1136 }
1137
1138 /*******************************************************************
1139  *
1140  * @brief Free Event Trigger Definition
1141  *
1142  * @details
1143  *
1144  *    Function : FreeEventTriggerDef
1145  *
1146  *    Functionality: Free Event Trigger Definition
1147  *
1148  * @params[in] E2SM-KPM Event Trigger Definition
1149  * @return void
1150  *
1151  * ****************************************************************/
1152 void  FreeEventTriggerDef(E2SM_KPM_EventTriggerDefinition_t *eventTiggerDef)
1153 {
1154    if(eventTiggerDef)
1155    {
1156       switch(eventTiggerDef->eventDefinition_formats.present)
1157       {
1158          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING:
1159             break;
1160          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1: 
1161             RIC_FREE(eventTiggerDef->eventDefinition_formats.choice.eventDefinition_Format1, \
1162                   sizeof(E2SM_KPM_EventTriggerDefinition_Format1_t));
1163             break;                  
1164       }         
1165    }
1166 }
1167
1168 /*******************************************************************
1169  *
1170  * @brief Fill Event Trigger Definition
1171  *
1172  * @details
1173  *
1174  *    Function : fillEventTriggerDef
1175  *
1176  *    Functionality: Fill Event Trigger Definition
1177  *
1178  * @params[in] RIC Event Trigger Definition
1179  * @return ROK
1180  *         RFAILED
1181  *
1182  * ****************************************************************/
1183 uint8_t fillEventTriggerDef(RICeventTriggerDefinition_t *ricEventTriggerDef)
1184 {
1185    uint8_t ret = RFAILED;
1186    asn_enc_rval_t  encRetVal;
1187    E2SM_KPM_EventTriggerDefinition_t eventTiggerDef;
1188
1189    while(true)
1190    {
1191       /* Fill E2SM-KPM Event Trigger Definition Format 1 */
1192       eventTiggerDef.eventDefinition_formats.present = \
1193        E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1;
1194
1195       RIC_ALLOC(eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1, \
1196             sizeof(E2SM_KPM_EventTriggerDefinition_Format1_t));
1197       if(eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1 == NULLP)
1198       {
1199          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1200          break;
1201       }
1202
1203       eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1->reportingPeriod = 1000; /* In ms */
1204
1205       /* Prints the Msg formed */
1206       xer_fprint(stdout, &asn_DEF_E2SM_KPM_EventTriggerDefinition, &eventTiggerDef);
1207
1208       /* Encode E2SM-KPM Event Trigger Definition */
1209       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1210       encBufSize = 0;
1211       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_EventTriggerDefinition, 0, &eventTiggerDef, PrepFinalEncBuf, encBuf);
1212       if(encRetVal.encoded == ENCODE_FAIL)
1213       {
1214          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM event trigger definition structure (at %s)\n",\
1215                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1216          break;
1217       }
1218
1219       /* Copy encoded E2SM-KPM event trigger definition to E2AP octet string buffer */
1220       ricEventTriggerDef->size = encBufSize;
1221       RIC_ALLOC(ricEventTriggerDef->buf, encBufSize);
1222       if(ricEventTriggerDef->buf == NULLP)
1223       {
1224          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1225          break;
1226       }
1227       memcpy(ricEventTriggerDef->buf, encBuf, encBufSize);
1228
1229       ret = ROK;
1230       break;
1231    }
1232
1233    FreeEventTriggerDef(&eventTiggerDef);
1234    return ret;
1235 }
1236
1237 /*******************************************************************
1238  *
1239  * @brief builds RIC Subscription Details
1240  *
1241  * @details
1242  *
1243  *    Function : BuildsRicSubsDetails
1244  *
1245  *    Functionality: Builds the RIC Subscription Details
1246  *
1247  * @params[in] RIC Subscription details to be filled
1248  *             RIC subscriotion DB
1249  * @return ROK     - success
1250  *         RFAILED - failure
1251  *
1252  * ****************************************************************/
1253
1254 uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails, RicSubscription *ricSubsDb)
1255 {
1256    uint8_t elementCnt = 0;
1257    uint8_t elementIdx = 0;
1258
1259    if(subsDetails == NULLP)
1260    {
1261       DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1262       return RFAILED;
1263    }
1264
1265    while(true)
1266    {
1267       /* RIC Event Trigger Definition */
1268       if(fillEventTriggerDef(&subsDetails->ricEventTriggerDefinition) != ROK)
1269       {
1270          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1271          break;
1272       }
1273
1274       /* RIC Actions To Be Setup List */
1275       elementCnt = 1;
1276       subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt;
1277       subsDetails->ricAction_ToBeSetup_List.list.size = elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t *);
1278       RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, subsDetails->ricAction_ToBeSetup_List.list.size);
1279       if(subsDetails->ricAction_ToBeSetup_List.list.array  == NULLP)
1280       {
1281          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICactionToBeSetup Items failed");
1282          break;
1283       } 
1284
1285       for(elementIdx = 0; elementIdx < elementCnt; elementIdx++)
1286       {
1287          RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], sizeof(RICaction_ToBeSetup_ItemIEs_t));
1288          if(!subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
1289          {
1290             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1291             break;
1292          }
1293       }
1294       if(elementIdx < elementCnt)
1295          break;
1296
1297       elementIdx = 0;
1298       if(fillActionToBeSetup((RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], \
1299          ricSubsDb) != ROK)
1300       {
1301          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1302          break;
1303       }
1304
1305       return ROK;
1306    }
1307    return RFAILED;
1308 }
1309
1310 /*******************************************************************
1311  *
1312  * @brief Builds and Send the RicSubscriptionReq
1313  *
1314  * @details
1315  *
1316  *    Function : BuildAndSendRicSubscriptionReq
1317  *
1318  * Functionality:Fills the RicSubscriptionReq
1319  *
1320  * @return ROK     - success
1321  *         RFAILED - failure
1322  *
1323  ******************************************************************/
1324 uint8_t BuildAndSendRicSubscriptionReq(DuDb *duDb)
1325 {
1326    uint8_t         ret = RFAILED;
1327    E2AP_PDU_t                 *e2apRicMsg = NULL;
1328    RICsubscriptionRequest_t   *ricSubscriptionReq;
1329    uint8_t         elementCnt;
1330    uint8_t         idx;
1331    asn_enc_rval_t  encRetVal;        /* Encoder return value */
1332    RanFunction     *ranFuncDb = &duDb->ranFunction[0];
1333
1334    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Request\n");
1335
1336    while(true)
1337    {
1338       RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
1339       if(e2apRicMsg == NULLP)
1340       {
1341          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1342          break;
1343       }
1344
1345       e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
1346       RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1347       if(e2apRicMsg->choice.initiatingMessage == NULLP)
1348       {
1349          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1350          break;
1351       }
1352       e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
1353       e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
1354       e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
1355
1356       ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
1357
1358       elementCnt = 3;
1359       ricSubscriptionReq->protocolIEs.list.count = elementCnt;
1360       ricSubscriptionReq->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
1361
1362       /* Initialize the subscription members */
1363       RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, ricSubscriptionReq->protocolIEs.list.size);
1364       if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
1365       {
1366          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1367          break;
1368       }
1369
1370       for(idx=0; idx<elementCnt; idx++)
1371       {
1372          RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionRequest_IEs_t));
1373          if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
1374          {
1375             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1376             break;
1377          }
1378       }
1379       if(idx < elementCnt)
1380          break;
1381
1382       /* Filling RIC Request Id */
1383       idx = 0;
1384       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
1385       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1386       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
1387                                                                       RICsubscriptionRequest_IEs__value_PR_RICrequestID;
1388       if(BuildNewRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID, \
1389          &ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription].requestId) != ROK)
1390       {
1391          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : Line [%d]", __func__, __LINE__);
1392          break;
1393       }
1394
1395
1396       /* Filling RAN Function Id */
1397       idx++;
1398       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
1399       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1400       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
1401                                                                       RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
1402       ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ranFuncDb->id;
1403
1404       /* Filling RIC Subscription Details */
1405       idx++;
1406       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
1407       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1408       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
1409                                                                       RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
1410       if(BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails),\
1411          &ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription]) != ROK)
1412       {
1413          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : Line [%d]", __func__, __LINE__);
1414          break;
1415       }
1416
1417       /* Prints the Msg formed */
1418       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
1419
1420       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1421       encBufSize = 0;
1422       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf, encBuf);
1423       if(encRetVal.encoded == ENCODE_FAIL)
1424       {
1425          DU_LOG("\nERROR  -->  E2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
1426                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1427          break;               
1428       }
1429       else
1430       {
1431          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
1432          for(int i=0; i< encBufSize; i++)
1433          {
1434             DU_LOG("%x",encBuf[i]);
1435          } 
1436       }
1437
1438       /* Sending msg */
1439       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
1440       {
1441          DU_LOG("\nERROR  -->  E2AP : Sending RIC subscription Request failed");
1442          break;
1443       }
1444
1445       ranFuncDb->numOfSubscription++;
1446       ret = ROK;
1447       break;
1448    }
1449
1450    if(ret == RFAILED)
1451       memset(&ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription], 0, sizeof(RicSubscription));
1452    FreeRicSubscriptionReq(e2apRicMsg);
1453    return ret;
1454 }
1455
1456 /*******************************************************************
1457  *
1458  * @brief Process RicSubscriptionResponse
1459  *
1460  * @details
1461  *
1462  *    Function : ProcRicSubscriptionRsp
1463  *
1464  * Functionality: Processes RicSubscriptionRsp
1465  *
1466  * @return ROK     - void
1467  *
1468  ******************************************************************/
1469
1470 void ProcRicSubscriptionResponse(uint32_t duId, RICsubscriptionResponse_t  *ricSubscriptionRsp)
1471 {
1472    uint8_t duIdx = 0, ieIdx = 0,subsIdx = 0, notAdmitIdx = 0;
1473    uint8_t ranFuncId = 0, actionId = 0;
1474    DuDb *duDb = NULLP;
1475    bool ricReqIdDecoded = false;
1476    RicRequestId ricReqId;
1477    RanFunction  *ranFuncDb = NULLP;
1478    RICsubscriptionResponse_IEs_t *ricSubsRspIe = NULLP;
1479    RICaction_NotAdmitted_List_t *notAdmitList = NULLP;
1480
1481    DU_LOG("\nINFO  -->  E2AP : RIC Subscription Response received");
1482
1483    /* Fetch DU DB */
1484    SEARCH_DU_DB(duIdx, duId, duDb);
1485    if(duDb == NULLP)
1486    {
1487       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
1488       return;
1489    }
1490
1491    memset(&ricReqId, 0, sizeof(RicRequestId));
1492    if(ricSubscriptionRsp)
1493    {
1494       if(ricSubscriptionRsp->protocolIEs.list.array)
1495       {
1496          for(ieIdx=0; ieIdx<ricSubscriptionRsp->protocolIEs.list.count; ieIdx++)
1497          {
1498             if(ricSubscriptionRsp->protocolIEs.list.array[ieIdx])
1499             {
1500                ricSubsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
1501                switch(ricSubscriptionRsp->protocolIEs.list.array[ieIdx]->id)
1502                {
1503                   case ProtocolIE_IDE2_id_RICrequestID:
1504                      {
1505                         ricReqId.requestorId = ricSubsRspIe->value.choice.RICrequestID.ricRequestorID;
1506                         ricReqId.instanceId = ricSubsRspIe->value.choice.RICrequestID.ricInstanceID;
1507                         ricReqIdDecoded = true;
1508                         break;
1509                      }
1510                   case ProtocolIE_IDE2_id_RANfunctionID:
1511                      {
1512                         ranFuncId = ricSubsRspIe->value.choice.RANfunctionID;
1513                         if(duDb->ranFunction[ranFuncId-1].id == ranFuncId)
1514                         {
1515                            ranFuncDb = &duDb->ranFunction[ranFuncId-1];
1516                         }
1517                         else
1518                         {
1519                            DU_LOG("\nERROR  -->  E2AP : ProcRicSubscriptionResponse: RAN Function ID [%d] not found", ranFuncId);
1520                            return;
1521                         }
1522                         break; 
1523                      }
1524                   case ProtocolIE_IDE2_id_RICactions_Admitted:
1525                      {
1526                         break;
1527                      }
1528                   case ProtocolIE_IDE2_id_RICactions_NotAdmitted:
1529                      {
1530                         if(!(ranFuncDb && ricReqIdDecoded))
1531                            return;
1532
1533                         notAdmitList = &ricSubsRspIe->value.choice.RICaction_NotAdmitted_List;
1534                         for(notAdmitIdx = 0; notAdmitIdx < notAdmitList->list.count; notAdmitIdx++)
1535                         {
1536                            actionId = ((RICaction_NotAdmitted_ItemIEs_t *)(notAdmitList->list.array[notAdmitIdx]))->\
1537                               value.choice.RICaction_NotAdmitted_Item.ricActionID;
1538
1539                               /* Remove action from RAN Function's subscription list */
1540                               for(subsIdx = 0; subsIdx < ranFuncDb->numOfSubscription; subsIdx++)
1541                               {
1542                                  if((ranFuncDb->subscriptionList[subsIdx].requestId.requestorId == ricReqId.requestorId) &&
1543                                        (ranFuncDb->subscriptionList[subsIdx].requestId.instanceId == ricReqId.instanceId))
1544                                  {
1545                                     if(ranFuncDb->subscriptionList[subsIdx].actionSequence[actionId-1].id == actionId)
1546                                     {
1547                                        memset(&ranFuncDb->subscriptionList[subsIdx].actionSequence[actionId-1], 0, \
1548                                           sizeof(ActionInfo));
1549                                        ranFuncDb->subscriptionList[subsIdx].numOfActions--;
1550                                        break;
1551                                     }
1552                                  }
1553                               }
1554                         }
1555                         break;
1556                      }
1557                }
1558             }
1559          }
1560       }
1561    } 
1562 }
1563
1564 /*******************************************************************
1565  *
1566  * @brief deallocate the memory allocated in E2SetupFailure
1567  *
1568  * @details
1569  *
1570  *    Function : FreeE2SetupFailure 
1571  *
1572  *    Functionality: deallocate the memory allocated in E2SetupFailure 
1573  *
1574  * @params[in] E2AP_PDU_t *e2apMsg
1575  *
1576  * @return void
1577  * ****************************************************************/
1578 void FreeE2SetupFailure(E2AP_PDU_t *e2apMsg)
1579 {
1580    uint8_t arrIdx = 0;
1581    E2setupFailure_t  *e2SetupFail;
1582
1583    if(e2apMsg)
1584    {
1585       if(e2apMsg->choice.unsuccessfulOutcome)
1586       {
1587          e2SetupFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
1588          if(e2SetupFail->protocolIEs.list.array)
1589          {
1590             for(arrIdx=0; arrIdx<e2SetupFail->protocolIEs.list.count; arrIdx++)
1591             {
1592                RIC_FREE(e2SetupFail->protocolIEs.list.array[arrIdx], sizeof(E2setupFailureIEs_t)); 
1593             }
1594             RIC_FREE(e2SetupFail->protocolIEs.list.array, e2SetupFail->protocolIEs.list.size);
1595          }
1596          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
1597       }
1598       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1599    }
1600 }
1601
1602 /*******************************************************************
1603  *
1604  * @brief Buld and send the E2 Setup failure
1605  *
1606  * @details
1607  *
1608  *    Function : BuildAndSendE2SetupFailure
1609  *
1610  *    Functionality:
1611  *         - Buld and send the E2 Setup failure
1612  * @return ROK     - success
1613  *         RFAILED - failure
1614  *
1615  * ****************************************************************/
1616
1617 uint8_t BuildAndSendE2SetupFailure(uint32_t duId, uint8_t transId)
1618 {
1619    E2AP_PDU_t         *e2apMsg = NULL;
1620    E2setupFailure_t   *e2SetupFailure;
1621    asn_enc_rval_t     encRetVal;
1622    uint8_t            arrIdx;
1623    uint8_t            elementCnt;
1624    bool  memAllocFailed = false;
1625
1626    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup failure\n");
1627    while(true)
1628    {
1629       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1630       if(e2apMsg == NULLP)
1631       {
1632          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1633          break;
1634       }
1635       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
1636       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
1637       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
1638       {
1639          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1640          break;
1641       }
1642
1643       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
1644       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
1645       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2setupFailure;
1646       e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
1647
1648       elementCnt = 3;
1649       e2SetupFailure->protocolIEs.list.count = elementCnt;
1650       e2SetupFailure->protocolIEs.list.size  = elementCnt * sizeof(struct E2setupFailureIEs *);
1651
1652       RIC_ALLOC(e2SetupFailure->protocolIEs.list.array, e2SetupFailure->protocolIEs.list.size);
1653       if(e2SetupFailure->protocolIEs.list.array == NULLP)
1654       {
1655          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
1656          break;
1657       }
1658
1659       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
1660       {
1661          RIC_ALLOC(e2SetupFailure->protocolIEs.list.array[arrIdx], sizeof(struct E2setupFailureIEs));
1662          if(e2SetupFailure->protocolIEs.list.array[arrIdx] == NULLP)
1663          {
1664             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
1665             memAllocFailed = true;
1666             break;
1667          }
1668       }
1669
1670       if(memAllocFailed == true)
1671       {
1672           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
1673           break;
1674       }
1675
1676       /* Trans Id */
1677       arrIdx = 0;
1678       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
1679       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1680       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TransactionID;
1681       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
1682
1683       arrIdx++;
1684       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
1685       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1686       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_CauseE2;
1687       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.present = CauseE2_PR_protocol;
1688       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.protocol = CauseE2Protocol_unspecified;
1689
1690       arrIdx++;
1691       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
1692       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
1693       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TimeToWaitE2;
1694       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
1695
1696       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1697       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1698       encBufSize = 0;
1699       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
1700
1701       /* Check encode results */
1702       if(encRetVal.encoded == ENCODE_FAIL)
1703       {
1704          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Setup failure structure (at %s)\n",\
1705                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1706          break;
1707       }
1708       else
1709       {
1710          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Setup Failure\n");
1711          for(int i=0; i< encBufSize; i++)
1712          {
1713             DU_LOG("%x",encBuf[i]);
1714          }
1715       }
1716
1717       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
1718       {
1719          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Failure failed");
1720          break;
1721       }
1722       break;
1723    }
1724
1725    FreeE2SetupFailure(e2apMsg);
1726 }
1727
1728 /*******************************************************************
1729  *
1730  * @brief process the e2setup request 
1731  *
1732  * @details
1733  *
1734  *    Function : ProcE2SetupReq
1735  *
1736  * Functionality: process the e2setup request
1737  *
1738  * @return ROK     - success
1739  *         RFAILED - failure
1740  *
1741  ******************************************************************/
1742
1743 uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
1744 {
1745    uint8_t arrIdx = 0, e2NodeAddListIdx =0, duIdx = 0, transId =0, ranFuncIdx;
1746    DuDb    *duDb = NULLP;
1747    E2nodeComponentConfigAddition_List_t *e2NodeAddList;
1748    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
1749    RANfunction_ItemIEs_t *ranFuncItemIe;
1750    RANfunction_Item_t  *ranFunItem;
1751    RANfunctions_List_t *ranFunctionsList;
1752
1753    if(e2SetupReq)
1754    {
1755       if(e2SetupReq->protocolIEs.list.array)      
1756       {
1757          for(arrIdx=0; arrIdx<e2SetupReq->protocolIEs.list.count; arrIdx++)
1758          {
1759             if(e2SetupReq->protocolIEs.list.array[arrIdx])
1760             {
1761                switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
1762                {
1763                   case ProtocolIE_IDE2_id_TransactionID:
1764                      {
1765                         transId = e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; 
1766                         break;
1767                      }
1768                   case ProtocolIE_IDE2_id_GlobalE2node_ID:
1769                      {
1770                         if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID)
1771                         {
1772                             *duId =e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID->buf[0];
1773
1774                             SEARCH_DU_DB(duIdx, *duId, duDb); 
1775                             if(duDb == NULLP)
1776                             {
1777                                duDb = &ricCb.duInfo[ricCb.numDu];
1778                                ricCb.numDu++;
1779                             }
1780                             memset(duDb, 0, sizeof(DuDb));
1781                             duDb->duId = *duId;
1782                         }
1783                         break;
1784                      }
1785                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
1786                      {
1787                         ranFunctionsList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
1788
1789                         if(ranFunctionsList->list.array)
1790                         {
1791                            for(ranFuncIdx=0;ranFuncIdx<ranFunctionsList->list.count; ranFuncIdx++)
1792                            {
1793                               ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncIdx]; 
1794                               ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
1795                               duDb->ranFunction[ranFunItem->ranFunctionID-1].id = ranFunItem->ranFunctionID; 
1796                               duDb->ranFunction[ranFunItem->ranFunctionID-1].revisionCounter = ranFunItem->ranFunctionRevision; 
1797                               duDb->numOfRanFunction++;
1798                            }
1799                         }
1800                         break;
1801                      }
1802                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
1803                      {
1804                         e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;      
1805                         if(e2NodeAddList->list.array)
1806                         {
1807                            for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
1808                            {
1809                               if(e2NodeAddList->list.array[e2NodeAddListIdx])
1810                               {
1811                                  e2NodeAddItem = \
1812                                     (E2nodeComponentConfigAddition_ItemIEs_t *)e2NodeAddList->list.array[e2NodeAddListIdx];
1813                                  if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.\
1814                                     choice.e2nodeComponentInterfaceTypeF1)
1815                                  {
1816                                     duDb->e2NodeComponent.interfaceType = F1; 
1817                                     duDb->e2NodeComponent.componentId = \
1818                                        e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.\
1819                                        choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]; 
1820                                  }
1821                               }
1822                            }
1823                         }
1824                         break;
1825                      }
1826                      default:
1827                         break;
1828                   }
1829                }
1830             }
1831         }
1832    }
1833    
1834    if(BuildAndSendE2SetupRsp(duDb, transId) !=ROK)
1835    {
1836       DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 setup response");
1837       return RFAILED;
1838    }
1839    return ROK;   
1840 }
1841 /*******************************************************************
1842  *
1843  * @brief Deallocate the memory allocated for E2 Reset Response
1844  *
1845  * @details
1846  *
1847  *    Function : FreeE2ResetResponse
1848  *
1849  *    Functionality:
1850  *       - freeing the memory allocated for E2ResetResponse
1851  *
1852  * @params[in] E2AP_PDU_t *e2apMsg
1853  * @return ROK     - success
1854  *         RFAILED - failure
1855  *
1856  * ****************************************************************/
1857 void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg)
1858 {
1859    uint8_t ieIdx =0;
1860    ResetResponseE2_t *resetResponse;
1861
1862    if(e2apMsg != NULLP)
1863    {
1864       if(e2apMsg->choice.successfulOutcome != NULLP)
1865       {
1866          resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
1867          if(resetResponse->protocolIEs.list.array)
1868          {
1869             for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
1870             {
1871                if(resetResponse->protocolIEs.list.array[ieIdx])
1872                {
1873                   RIC_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
1874                }
1875             }
1876             RIC_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
1877          }
1878          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1879       }
1880       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1881    }
1882 }
1883
1884 /*******************************************************************
1885  *
1886  * @brief Buld and send the E2 Reset Response msg
1887  *
1888  * @details
1889  *
1890  *    Function : BuildAndSendE2ResetResponse
1891  *
1892  *    Functionality:
1893  *         - Buld and send the E2 Reset Response Message
1894  * @return ROK     - success
1895  *         RFAILED - failure
1896  *
1897  * ****************************************************************/
1898 uint8_t BuildAndSendResetResponse(uint32_t duId, uint8_t transId)
1899 {
1900    uint8_t           ieIdx = 0, elementCnt = 0;
1901    uint8_t           ret = RFAILED;
1902    E2AP_PDU_t        *e2apMsg = NULLP;
1903    ResetResponseE2_t *resetResponse;
1904    asn_enc_rval_t    encRetVal;       /* Encoder return value */
1905
1906    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
1907    do
1908    {
1909       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1910       if(e2apMsg == NULLP)
1911       {
1912          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
1913          break;
1914       }
1915       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
1916
1917       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1918       if(e2apMsg->choice.successfulOutcome == NULLP)
1919       {
1920          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
1921          RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1922          return RFAILED;
1923       }
1924  
1925       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
1926       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
1927       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
1928       resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
1929
1930       elementCnt = 1;
1931       resetResponse->protocolIEs.list.count = elementCnt;
1932       resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
1933       RIC_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
1934       if(!resetResponse->protocolIEs.list.array)
1935       {
1936          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
1937          break;
1938       }
1939
1940       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
1941       {
1942          RIC_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
1943          if(!resetResponse->protocolIEs.list.array[ieIdx])
1944          {
1945             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
1946             break;
1947          }
1948       }
1949       if(ieIdx < elementCnt)
1950          break;
1951
1952       ieIdx = 0; 
1953       resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
1954       resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
1955       resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
1956       resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
1957
1958       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1959
1960       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1961       encBufSize = 0;
1962       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
1963       if(encRetVal.encoded == ENCODE_FAIL)
1964       {
1965          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
1966                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1967          return RFAILED;
1968       }
1969       else
1970       {
1971          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
1972          for(int i=0; i< encBufSize; i++)
1973          {
1974             DU_LOG("%x",encBuf[i]);
1975          }
1976       }
1977
1978       /* Sending msg */
1979       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
1980       {
1981          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
1982          return RFAILED;
1983       }
1984
1985       ret = ROK;
1986       break;
1987    }while(true);
1988
1989    FreeE2ResetResponse(e2apMsg);
1990    return ROK;
1991 }
1992
1993 /*******************************************************************
1994  *
1995  * @brief process the E2 Reset Request
1996  *
1997  * @details
1998  *
1999  *    Function : ProcE2ResetReq
2000  *
2001  * Functionality: Process E2 Reset Request
2002  *
2003  * @return ROK     - success
2004  *         RFAILED - failure
2005  *
2006  ******************************************************************/
2007
2008 uint8_t ProcE2ResetReq(uint32_t duId, ResetRequestE2_t  *resetReq)
2009 {
2010    uint8_t ieIdx = 0, duIdx = 0;
2011    uint8_t transId = 0, cause = 0;
2012    DuDb    *duDb = NULLP;
2013
2014    if(resetReq)
2015    {
2016       if(resetReq->protocolIEs.list.array)
2017       {
2018          for(ieIdx=0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
2019          {
2020             if(resetReq->protocolIEs.list.array[ieIdx])
2021             {
2022                switch(resetReq->protocolIEs.list.array[ieIdx]->id)
2023                {
2024                   case ProtocolIE_IDE2_id_TransactionID:
2025                      transId = resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
2026                      break;
2027                   case ProtocolIE_IDE2_id_CauseE2:
2028                      DU_LOG("\nDEBUG  -->  E2AP : Reset reason %d", resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present);
2029                      switch(resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present)
2030                      {
2031                         case CauseE2_PR_NOTHING:
2032                            break;
2033                         case CauseE2_PR_ricRequest:
2034                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricRequest;
2035                            break;
2036                         case CauseE2_PR_ricService:
2037                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricService;
2038                            break;
2039                         case CauseE2_PR_e2Node:
2040                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.e2Node;
2041                            break;
2042                         case CauseE2_PR_transport:
2043                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.transport;
2044                            break;
2045                         case CauseE2_PR_protocol:
2046                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.protocol;
2047                            break;
2048                         case CauseE2_PR_misc:
2049                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.misc;
2050                            break;
2051                      }
2052                      DU_LOG("\nDEBUG  -->  E2AP : Reset cause %d", cause);
2053                      break;
2054                }
2055             }
2056          }
2057       }
2058    }
2059    BuildAndSendResetResponse(duId, transId);
2060    return ROK;
2061 }
2062
2063 /*******************************************************************
2064  *
2065  * @brief deallocate the memory allocated in building the
2066  *    Service Query message
2067  *
2068  * @details
2069  *
2070  *    Function : FreeRicServiceQuery 
2071  *
2072  *    Functionality: deallocate the memory allocated in building
2073  *    Ric Service Query message
2074  *
2075  * @params[in] E2AP_PDU_t *e2apMsg
2076  *
2077  * @return void
2078  * ****************************************************************/
2079
2080 void FreeRicServiceQuery(E2AP_PDU_t *e2apMsg)
2081 {
2082    uint8_t arrIdx = 0, ranFuncIdx=0;
2083    RANfunctionsID_List_t *ranFuncAcceptedList=NULL;
2084    RICserviceQuery_t *ricServiceQuery=NULL;
2085    
2086    if(e2apMsg)
2087    {
2088       if(e2apMsg->choice.initiatingMessage)
2089       {
2090          ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
2091          if(ricServiceQuery->protocolIEs.list.array)
2092          {
2093             for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
2094             {
2095                if(ricServiceQuery->protocolIEs.list.array[arrIdx])
2096                {
2097                   switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
2098                   {
2099                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
2100                         {
2101                            ranFuncAcceptedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
2102                            if(ranFuncAcceptedList->list.array)
2103                            {
2104                               for(ranFuncIdx=0;ranFuncIdx<ranFuncAcceptedList->list.count; ranFuncIdx++)
2105                               {
2106                                  RIC_FREE(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
2107                               }
2108                               RIC_FREE(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
2109                            }
2110                            break;
2111                         }
2112                      case RICserviceQuery_IEs__value_PR_TransactionID:
2113                         {
2114                            break;
2115                         }
2116                   }
2117                   RIC_FREE(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t)); 
2118                }
2119             }
2120             RIC_FREE(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
2121          }
2122          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2123       }
2124       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2125    }
2126 }
2127
2128 /*******************************************************************
2129  *
2130  * @brief build and send the ric service Query 
2131  *
2132  * @details
2133  *
2134  *    Function : BuildAndSendRicServiceQuery
2135  *
2136  * Functionality: build and send the ric service Query 
2137  * @return ROK     - success
2138  *         RFAILED - Acknowledge
2139  *
2140  ******************************************************************/
2141
2142 uint8_t BuildAndSendRicServiceQuery(DuDb *duDb)
2143 {
2144    uint8_t arrIdx;
2145    uint8_t elementCnt;
2146    uint8_t ret = RFAILED;
2147    bool  memAllocFailed = false;
2148    E2AP_PDU_t     *e2apMsg = NULL;
2149    asn_enc_rval_t encRetVal;
2150    RICserviceQuery_t *ricServiceQuery;
2151
2152    DU_LOG("\nINFO   -->  E2AP : Building Ric service Query\n");
2153    while(true)
2154    {
2155       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2156       if(e2apMsg == NULLP)
2157       {
2158          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2159          break;
2160       }
2161       e2apMsg->present =  E2AP_PDU_PR_initiatingMessage;
2162       RIC_ALLOC(e2apMsg->choice.initiatingMessage , sizeof(struct InitiatingMessageE2));
2163       if(e2apMsg->choice.initiatingMessage == NULLP)
2164       {
2165          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2166          break;
2167       }
2168
2169       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceQuery;
2170       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2171       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceQuery;
2172       ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
2173
2174       elementCnt = 1;
2175       /* Fill Accepted RAN function IE If Ran function information is stored in databse */
2176       if(duDb->numOfRanFunction)
2177          elementCnt++;
2178
2179       ricServiceQuery->protocolIEs.list.count = elementCnt;
2180       ricServiceQuery->protocolIEs.list.size  = elementCnt * sizeof(RICserviceQuery_IEs_t*);
2181
2182       RIC_ALLOC(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
2183       if(ricServiceQuery->protocolIEs.list.array == NULLP)
2184       {
2185          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2186          break;
2187       }
2188
2189       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2190       {
2191          RIC_ALLOC(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t));
2192          if(ricServiceQuery->protocolIEs.list.array[arrIdx] == NULLP)
2193          {
2194             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2195             memAllocFailed = true;
2196             break;
2197          }
2198       }
2199       if(memAllocFailed == true)
2200       {
2201          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2202          break;
2203       }
2204
2205       /* Trans Id */
2206       arrIdx = 0;
2207       ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2208       ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2209       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_TransactionID;
2210       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = assignTransactionId(duDb);
2211       
2212       if(duDb->numOfRanFunction)
2213       {
2214          /* Accepted RAN function Id */
2215          arrIdx++;
2216          ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
2217          ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2218          ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_RANfunctionsID_List;
2219          if(BuildRanFunctionAcceptedList(duDb, 0, NULL, &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceQuery)!=ROK)
2220          {
2221             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
2222             break;         
2223          }
2224       }
2225       
2226       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2227       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2228       encBufSize = 0;
2229       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2230
2231       /* Check encode results */
2232       if(encRetVal.encoded == ENCODE_FAIL)
2233       {
2234          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service Query structure (at %s)\n",\
2235                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2236          break;
2237       }
2238       else
2239       {
2240          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service Query\n");
2241          for(int i=0; i< encBufSize; i++)
2242          {
2243             DU_LOG("%x",encBuf[i]);
2244          }
2245       }
2246
2247       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
2248       {
2249          DU_LOG("\nERROR  -->  E2AP : Sending of RIC service  Query failed");
2250          break;
2251       }
2252
2253       ret =ROK;
2254       break;
2255    }
2256    FreeRicServiceQuery(e2apMsg);
2257    return ret;
2258 }
2259
2260 /*******************************************************************
2261  *
2262  * @brief deallocate the memory allocated in RicServiceUpdateFailure
2263  *
2264  * @details
2265  *
2266  *    Function : FreeRicServiceUpdateFailure 
2267  *
2268  *    Functionality: deallocate the memory allocated in RicServiceUpdatefailure
2269  *
2270  * @params[in] E2AP_PDU_t *e2apMsg
2271  *
2272  * @return void
2273  * ****************************************************************/
2274
2275 void FreeRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
2276 {
2277    uint8_t arrIdx = 0;
2278    RICserviceUpdateFailure_t *ricServiceUpdateFailure=NULL;
2279    
2280    if(e2apMsg)
2281    {
2282       if(e2apMsg->choice.unsuccessfulOutcome)
2283       {
2284          ricServiceUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
2285          if(ricServiceUpdateFailure->protocolIEs.list.array)
2286          {
2287             for(arrIdx=0; arrIdx<ricServiceUpdateFailure->protocolIEs.list.count; arrIdx++)
2288             {
2289                RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t)); 
2290             }
2291             RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array, ricServiceUpdateFailure->protocolIEs.list.size);
2292          }
2293          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
2294       }
2295       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2296    }
2297 }
2298
2299 /*******************************************************************
2300  *
2301  * @brief fill E2 failure cause 
2302  *
2303  * @details
2304  *
2305  *    Function : fillE2FailureCause
2306  *
2307  * Functionality: fill E2 failure cause
2308  * @return ROK     - success
2309  *         RFAILED - failure
2310  *
2311  ******************************************************************/
2312
2313 void fillE2FailureCause(CauseE2_t *cause, CauseE2_PR causePresent, uint8_t reason)
2314 {
2315    cause->present = causePresent;
2316
2317    switch(cause->present)
2318    {
2319       case CauseE2_PR_ricRequest:
2320          cause->choice.ricRequest = reason;
2321          break;
2322       case CauseE2_PR_ricService:
2323          cause->choice.ricService = reason;
2324          break;
2325       case CauseE2_PR_e2Node:
2326          cause->choice.e2Node = reason;
2327          break;
2328       case CauseE2_PR_transport:
2329          cause->choice.transport = reason;
2330          break;
2331       case CauseE2_PR_protocol:
2332          cause->choice.protocol = reason;
2333          break;
2334       case CauseE2_PR_misc:
2335          cause->choice.misc = reason;
2336          break;
2337       default:
2338          cause->choice.misc = CauseE2Misc_unspecified;
2339          break;
2340    }
2341 }
2342
2343 /*******************************************************************
2344  *
2345  * @brief build and send the ric service update failure 
2346  *
2347  * @details
2348  *
2349  *    Function : BuildAndSendRicServiceUpdateFailure
2350  *
2351  * Functionality: build and send the ric service update failure 
2352  * @return ROK     - success
2353  *         RFAILED - failure
2354  *
2355  ******************************************************************/
2356
2357 uint8_t BuildAndSendRicServiceUpdateFailure(uint32_t duId, int8_t transId, CauseE2_PR causePresent, uint8_t reason)
2358 {
2359
2360    E2AP_PDU_t         *e2apMsg = NULL;
2361    asn_enc_rval_t     encRetVal;
2362    uint8_t            ret = RFAILED;
2363    uint8_t            arrIdx=0;
2364    uint8_t            elementCnt=0;
2365    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
2366
2367    DU_LOG("\nINFO   -->  E2AP : Building Ric service update failure\n");
2368    while(true)
2369    {
2370       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2371       if(e2apMsg == NULLP)
2372       {
2373          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2374          break;
2375       }
2376       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
2377       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
2378       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
2379       {
2380          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2381          break;
2382       }
2383
2384       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
2385       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
2386       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure;
2387       ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
2388
2389       elementCnt = 3;
2390       ricServiceFailure->protocolIEs.list.count = elementCnt;
2391       ricServiceFailure->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateFailure_IEs_t *);
2392
2393       RIC_ALLOC(ricServiceFailure->protocolIEs.list.array, ricServiceFailure->protocolIEs.list.size);
2394       if(ricServiceFailure->protocolIEs.list.array == NULLP)
2395       {
2396          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2397          break;
2398       }
2399
2400       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2401       {
2402          RIC_ALLOC(ricServiceFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t));
2403          if(ricServiceFailure->protocolIEs.list.array[arrIdx] == NULLP)
2404          {
2405             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2406             break;
2407          }
2408       }
2409       if(arrIdx<elementCnt)
2410       {
2411          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2412          break;
2413       }
2414
2415       /* Trans Id */
2416       arrIdx = 0;
2417       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2418       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2419       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TransactionID;
2420       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
2421
2422       arrIdx++;
2423       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
2424       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2425       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_CauseE2;
2426       fillE2FailureCause(&ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, causePresent, reason);
2427
2428       arrIdx++;
2429       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
2430       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
2431       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TimeToWaitE2;
2432       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
2433
2434       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2435       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2436       encBufSize = 0;
2437       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2438
2439       /* Check encode results */
2440       if(encRetVal.encoded == ENCODE_FAIL)
2441       {
2442          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update failure structure (at %s)\n",\
2443                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2444          break;
2445       }
2446       else
2447       {
2448          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Failure\n");
2449          for(int i=0; i< encBufSize; i++)
2450          {
2451             DU_LOG("%x",encBuf[i]);
2452          }
2453       }
2454
2455       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
2456       {
2457          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update failed");
2458          break;
2459       }
2460       ret = ROK;
2461       break;
2462    }
2463
2464    FreeRicServiceUpdateFailure(e2apMsg);
2465    return ret;
2466 }
2467
2468
2469 /*******************************************************************
2470  *
2471  * @brief deallocate the memory allocated in RicServiceUpdateAck(
2472  *
2473  * @details
2474  *
2475  *    Function : FreeRicServiceUpdateAck 
2476  *
2477  *    Functionality: deallocate the memory allocated in RicServiceUpdateAck
2478  *
2479  * @params[in] E2AP_PDU_t *e2apMsg
2480  *
2481  * @return void
2482  * ****************************************************************/
2483
2484 void FreeRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
2485 {
2486    uint8_t arrIdx = 0, ranFuncIdx=0;
2487    RANfunctionsID_List_t *acceptedList=NULL;
2488    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
2489    RANfunctionsIDcause_List_t  *rejectedList=NULL;
2490
2491    if(e2apMsg)
2492    {
2493       if(e2apMsg->choice.successfulOutcome)
2494       {
2495          ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
2496          if(ricServiceUpdateAck->protocolIEs.list.array)
2497          {
2498             for(arrIdx=0; arrIdx<ricServiceUpdateAck->protocolIEs.list.count; arrIdx++)
2499             {
2500                if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx])
2501                {
2502                   switch(ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id)
2503                   {
2504                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
2505                         {
2506                            acceptedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
2507                            if(acceptedList->list.array)
2508                            {
2509                               for(ranFuncIdx=0;ranFuncIdx<acceptedList->list.count; ranFuncIdx++)
2510                               {
2511                                  RIC_FREE(acceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
2512                               }
2513                               RIC_FREE(acceptedList->list.array, acceptedList->list.size);
2514                            }
2515                            break;
2516                         }
2517
2518                      case ProtocolIE_IDE2_id_RANfunctionsRejected:
2519                         {
2520                            rejectedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
2521                            if(rejectedList->list.array)
2522                            {
2523                               for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
2524                               {
2525                                  RIC_FREE(rejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
2526                               }
2527                               RIC_FREE(rejectedList->list.array, rejectedList->list.size);
2528                            }
2529                            break;
2530                         }
2531                   }
2532                   RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t)); 
2533                }
2534             }
2535             RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
2536          }
2537          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2538       }
2539       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2540    }
2541 }
2542
2543 /*******************************************************************
2544  *
2545  * @brief Build RAN function rejected list
2546  *
2547  * @details
2548  *
2549  *    Function : BuildRanFunctionRejectedList
2550  *
2551  *    Functionality: Build RAN function rejected list 
2552  *
2553  * @params[in] 
2554  *    Count of ran functions to be rejected in the list 
2555  *    Received list of RAN functions
2556  *
2557  * @return ROK - success
2558  *         RFAILED - failure
2559  * ****************************************************************/
2560
2561 uint8_t BuildRanFunctionRejectedList(uint8_t count, RanFunction *ranFunRejectedList, RANfunctionsIDcause_List_t *ranFuncRejectedList)
2562 {
2563    uint8_t ranFuncIdx = 0;
2564    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
2565    
2566    ranFuncRejectedList->list.count = count;
2567    
2568    ranFuncRejectedList->list.size = ranFuncRejectedList->list.count*sizeof(RANfunctionIDcause_ItemIEs_t*);
2569    RIC_ALLOC(ranFuncRejectedList->list.array, ranFuncRejectedList->list.size);
2570    if(ranFuncRejectedList->list.array == NULLP)
2571    {
2572       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array");
2573       return RFAILED;
2574    }
2575    
2576    for(ranFuncIdx = 0; ranFuncIdx< ranFuncRejectedList->list.count; ranFuncIdx++)
2577    {
2578       RIC_ALLOC(ranFuncRejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
2579       if(ranFuncRejectedList->list.array[ranFuncIdx] == NULLP)
2580       {
2581          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array item");
2582          return RFAILED;
2583       }
2584       ranFuncRejectedItemIe = (RANfunctionIDcause_ItemIEs_t*)ranFuncRejectedList->list.array[ranFuncIdx];
2585       ranFuncRejectedItemIe->id = ProtocolIE_IDE2_id_RANfunctionIEcause_Item;
2586       ranFuncRejectedItemIe->criticality= CriticalityE2_ignore;
2587       ranFuncRejectedItemIe->value.present = RANfunctionIDcause_ItemIEs__value_PR_RANfunctionIDcause_Item;
2588       ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID = ranFunRejectedList[ranFuncIdx].id;
2589       fillE2FailureCause(&ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.cause, CauseE2_PR_ricService,\
2590             CauseE2RICservice_ran_function_not_supported);
2591    }
2592    
2593    return ROK;
2594 }
2595
2596 /*******************************************************************
2597  *
2598  * @brief build and send the ric service update Acknowledge 
2599  *
2600  * @details
2601  *
2602  *    Function : BuildAndSendRicServiceUpdateAcknowledge
2603  *
2604  * Functionality: build and send the ric service update Acknowledge 
2605  * @return ROK     - success
2606  *         RFAILED - Acknowledge
2607  *
2608  ******************************************************************/
2609
2610 uint8_t BuildAndSendRicServiceUpdateAcknowledge(DuDb *duDb, int8_t transId, RicTmpRanFunList ricRanFuncList)
2611 {
2612    E2AP_PDU_t         *e2apMsg = NULL;
2613    asn_enc_rval_t     encRetVal;
2614    uint8_t  arrIdx=0, elementCnt=0, ret=RFAILED;;
2615    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
2616
2617    DU_LOG("\nINFO   -->  E2AP : Building Ric service update Acknowledge\n");
2618    while(true)
2619    {
2620       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2621       if(e2apMsg == NULLP)
2622       {
2623          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2624          break;
2625       }
2626       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
2627       RIC_ALLOC(e2apMsg->choice.successfulOutcome , sizeof(struct SuccessfulOutcomeE2));
2628       if(e2apMsg->choice.successfulOutcome == NULLP)
2629       {
2630          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2631          break;
2632       }
2633
2634       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
2635       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
2636       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge;
2637       ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
2638
2639       elementCnt = 1;
2640       if(ricRanFuncList.numOfRanFunAccepted)
2641          elementCnt++;
2642       if(ricRanFuncList.numOfRanFuneRejected)
2643          elementCnt++;
2644       
2645
2646       ricServiceUpdateAck->protocolIEs.list.count = elementCnt;
2647       ricServiceUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateAcknowledge_IEs_t*);
2648
2649       RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
2650       if(ricServiceUpdateAck->protocolIEs.list.array == NULLP)
2651       {
2652          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2653          break;
2654       }
2655
2656       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2657       {
2658          RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t));
2659          if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
2660          {
2661             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2662             break;
2663          }
2664       }
2665       if(arrIdx<elementCnt)
2666       {
2667          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2668          break;
2669       }
2670
2671       /* Trans Id */
2672       arrIdx = 0;
2673       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2674       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2675       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_TransactionID;
2676       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
2677
2678       if(ricRanFuncList.numOfRanFunAccepted)
2679       {
2680          /* Accepted RAN function List */
2681          arrIdx++;
2682          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
2683          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2684          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsID_List;
2685          if(BuildRanFunctionAcceptedList(duDb, ricRanFuncList.numOfRanFunAccepted, ricRanFuncList.ranFunAcceptedList,\
2686          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceUpdate)!=ROK)       
2687          {
2688             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
2689             break;         
2690          }
2691       }
2692       
2693       if(ricRanFuncList.numOfRanFuneRejected)
2694       {
2695          /* RAN Functions Rejected List */
2696          arrIdx++;
2697          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsRejected;
2698          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2699          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsIDcause_List;
2700          if(BuildRanFunctionRejectedList(ricRanFuncList.numOfRanFuneRejected, ricRanFuncList.ranFunRejectedList, \
2701          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List)!=ROK)       
2702          {
2703             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function rejected list");
2704             break;         
2705          }
2706       }
2707       
2708       
2709       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2710       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2711       encBufSize = 0;
2712       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2713
2714       /* Check encode results */
2715       if(encRetVal.encoded == ENCODE_FAIL)
2716       {
2717          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update Acknowledge structure (at %s)\n",\
2718                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2719          break;
2720       }
2721       else
2722       {
2723          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Acknowledge\n");
2724          for(int i=0; i< encBufSize; i++)
2725          {
2726             DU_LOG("%x",encBuf[i]);
2727          }
2728       }
2729
2730       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
2731       {
2732          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update ack failed");
2733          break;
2734       }
2735       ret =ROK;
2736       break;
2737    }
2738    FreeRicServiceUpdateAck(e2apMsg);
2739    return ret; 
2740 }
2741
2742 /*******************************************************************
2743  *
2744  * @brief process the RIC service update 
2745  *
2746  * @details
2747  *
2748  *    Function : ProcRicserviceUpdate 
2749  *
2750  * Functionality: process the RIC service update 
2751  *
2752  * @return ROK     - success
2753  *         RFAILED - failure
2754  *
2755  ******************************************************************/
2756
2757 void ProcRicServiceUpdate(uint32_t duId, RICserviceUpdate_t *ricServiceUpdate)
2758 {
2759    RicTmpRanFunList ricRanFuncList;
2760    DuDb    *duDb = NULLP;
2761    int8_t transId =-1;
2762    uint8_t duIdx = 0, elementCnt =0, arrIdx = 0; 
2763    uint16_t ranFuncIdx = 0, failedRanFuncCount=0, recvdRanFuncCount=0;
2764    RANfunction_ItemIEs_t *ranFuncItemIe =NULL;
2765    RANfunction_Item_t  *ranFuncItem =NULL;
2766    RANfunctionID_Item_t  *ranFuncIdItem=NULL;
2767    RANfunctions_List_t *ranFuncList=NULL;
2768    RANfunctionsID_List_t *deleteList=NULL;
2769    RANfunctionID_ItemIEs_t *delRanFuncItem=NULL;
2770
2771    SEARCH_DU_DB(duIdx, duId, duDb); 
2772    if(duDb == NULLP)
2773    {
2774       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
2775       return;
2776    }
2777    memset(&ricRanFuncList, 0, sizeof(RicTmpRanFunList)); 
2778
2779    if(!ricServiceUpdate)
2780    {
2781       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate pointer is null"); 
2782       return;
2783    }
2784
2785    if(!ricServiceUpdate->protocolIEs.list.array)      
2786    {
2787       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array pointer is null");
2788       return;
2789    }
2790    elementCnt = ricServiceUpdate->protocolIEs.list.count;
2791    for(arrIdx=0; arrIdx<ricServiceUpdate->protocolIEs.list.count; arrIdx++)
2792    {
2793       if(!ricServiceUpdate->protocolIEs.list.array[arrIdx])
2794       {
2795          DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array idx %d pointer is null",arrIdx);
2796          return;
2797       }
2798
2799       switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
2800       {
2801          case ProtocolIE_IDE2_id_TransactionID:
2802             {
2803                transId = ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
2804
2805                if(transId < 0 || transId > 255)
2806                {
2807                   DU_LOG("\nERROR  -->  E2AP : Received invalid transId %d",transId);
2808                   return;
2809                }
2810                break;
2811             }
2812
2813          case ProtocolIE_IDE2_id_RANfunctionsAdded:
2814             {
2815                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
2816
2817                if(ranFuncList->list.array)
2818                {
2819                   for(ranFuncIdx=0;ranFuncIdx<ranFuncList->list.count; ranFuncIdx++)
2820                   {
2821                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx]; 
2822                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
2823
2824                      /* Adding the ran function in temporary list */
2825                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
2826                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
2827                      ricRanFuncList.numOfRanFunAccepted++;
2828
2829                      /* Adding the new ran function in DB*/
2830                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].id = ranFuncItem->ranFunctionID;
2831                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
2832                      duDb->numOfRanFunction++;
2833
2834                      /* Calculating total number of ran fuctions which are received for addition */
2835                      recvdRanFuncCount++;
2836                   }
2837                }
2838                break;
2839             }
2840
2841          case ProtocolIE_IDE2_id_RANfunctionsModified:
2842             {
2843
2844                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List; 
2845                if(ranFuncList->list.array)
2846                {
2847                   for(ranFuncIdx = 0; ranFuncIdx< ranFuncList->list.count; ranFuncIdx++)
2848                   {
2849                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx];
2850                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
2851                      if(duDb->ranFunction[ranFuncItem->ranFunctionID-1].id != ranFuncItem->ranFunctionID)
2852                      {
2853                         /* Calculating total number of ran fuctions which are not present */
2854                         failedRanFuncCount++;
2855
2856                         /* Adding the ran function in temporary list */
2857                         ricRanFuncList.ranFunRejectedList[ricRanFuncList.numOfRanFuneRejected].id =  ranFuncItem->ranFunctionID; 
2858                         ricRanFuncList.numOfRanFuneRejected++;
2859                      }
2860                      else
2861                      {
2862
2863                         /* Adding the ran function in temporary list */
2864                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
2865                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
2866                         ricRanFuncList.numOfRanFunAccepted++;
2867
2868                         /* Updating the new ran function in DB*/
2869                         duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
2870                      }
2871                      /* Calculating total number of ran fuctions which are received for modification */
2872                      recvdRanFuncCount++;
2873                   }
2874                }
2875                break;
2876             }
2877          case ProtocolIE_IDE2_id_RANfunctionsDeleted:
2878             {
2879
2880                deleteList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List; 
2881                if(deleteList->list.array)
2882                {
2883                   for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
2884                   {
2885                      delRanFuncItem  = (RANfunctionID_ItemIEs_t*) deleteList->list.array[ranFuncIdx];
2886                      ranFuncIdItem = &delRanFuncItem->value.choice.RANfunctionID_Item;
2887                      if(duDb->ranFunction[ranFuncIdItem->ranFunctionID-1].id == ranFuncIdItem->ranFunctionID)
2888                      {
2889                         memset(&duDb->ranFunction[ranFuncIdItem->ranFunctionID-1], 0, sizeof(RanFunction));
2890                         duDb->numOfRanFunction--; 
2891                      }
2892
2893                      /* Calculating total number of ran fuctions which are received for deletion */
2894                      recvdRanFuncCount++;
2895                   }
2896                }
2897                break;
2898             }
2899
2900          default:
2901             {
2902                DU_LOG("\nERROR  -->  E2AP : IE [%ld] is not supported",ricServiceUpdate->protocolIEs.list.array[arrIdx]->id);
2903                break;
2904             }
2905       }
2906    }
2907    
2908    /* Sending RIC Service Update Failed if all RAN Functions received fail or if any IE processing fails
2909     * Else sending RIC Service Update Acknowledge */  
2910    if((elementCnt > arrIdx) ||((recvdRanFuncCount > 0) && (recvdRanFuncCount == failedRanFuncCount)))
2911    {
2912       if(BuildAndSendRicServiceUpdateFailure(duDb->duId, transId, CauseE2_PR_misc, CauseE2Misc_unspecified) != ROK)
2913       {
2914          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update Failure");
2915          return;
2916       }
2917    }
2918    else
2919    {
2920       if(BuildAndSendRicServiceUpdateAcknowledge(duDb, transId, ricRanFuncList) != ROK)
2921       {
2922          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update acknowledge");
2923          return;
2924       }
2925    }
2926 }
2927
2928 /*******************************************************************
2929  *
2930  * @brief Processing RIC subscription failure from DU
2931  *
2932  * @details
2933  *
2934  *    Function : ProcRicSubscriptionFailure
2935  *
2936  * Functionality: Processing RIC subscription failure from DU
2937  *
2938  * @param  ID of DU from which message was sent
2939  *         RIC Subscription failure message
2940  * @return ROK     - success
2941  *         RFAILED - failure
2942  *
2943  ******************************************************************/
2944 uint8_t ProcRicSubscriptionFailure(uint32_t duId, RICsubscriptionFailure_t *ricSubscriptionFailure)
2945 {
2946    uint8_t ieIdx = 0, duIdx = 0, subsIdx = 0;
2947    uint8_t ranFuncId = 0;
2948    bool   ricReqIdDecoded = false;
2949    DuDb    *duDb = NULLP;
2950    RanFunction *ranFuncDb = NULLP;
2951    RicRequestId ricReqId;
2952    RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
2953
2954    DU_LOG("\nINFO  -->  E2AP : Received RIC subscription failure");
2955
2956    SEARCH_DU_DB(duIdx, duId, duDb);
2957    if(duDb == NULLP)
2958    {
2959       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
2960       return RFAILED;
2961    }
2962
2963    memset(&ricReqId, 0, sizeof(RicRequestId));
2964    if(ricSubscriptionFailure)
2965    {
2966       if(ricSubscriptionFailure->protocolIEs.list.array)
2967       {
2968          for(ieIdx=0; ieIdx<ricSubscriptionFailure->protocolIEs.list.count; ieIdx++)
2969          {
2970             if(ricSubscriptionFailure->protocolIEs.list.array[ieIdx])
2971             {
2972                ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[ieIdx];
2973                switch(ricSubscriptionFailure->protocolIEs.list.array[ieIdx]->id)
2974                {
2975                   case ProtocolIE_IDE2_id_RICrequestID:
2976                   {
2977                      ricReqId.requestorId = ricSubsFailIe->value.choice.RICrequestID.ricRequestorID;
2978                      ricReqId.instanceId = ricSubsFailIe->value.choice.RICrequestID.ricInstanceID;
2979                      ricReqIdDecoded = true;
2980                      break;
2981                   }
2982                   case ProtocolIE_IDE2_id_RANfunctionID:
2983                   {
2984                      ranFuncId = ricSubsFailIe->value.choice.RANfunctionID;
2985                      if(duDb->ranFunction[ranFuncId-1].id == ranFuncId)
2986                      {
2987                         ranFuncDb = &duDb->ranFunction[ranFuncId-1];
2988                      }
2989                      break; 
2990                   }
2991                   case ProtocolIE_IDE2_id_CauseE2:
2992                   default:
2993                      /* No handling required as of now since this is a stub */
2994                      break;
2995
2996                }
2997             }
2998          }
2999
3000          /* Remove subscription entry from RAN Function */
3001          if(ranFuncDb && ricReqIdDecoded)
3002          {
3003             for(subsIdx = 0; subsIdx < ranFuncDb->numOfSubscription; subsIdx++)
3004             {
3005                if((ranFuncDb->subscriptionList[subsIdx].requestId.requestorId == ricReqId.requestorId) &&
3006                      (ranFuncDb->subscriptionList[subsIdx].requestId.instanceId == ricReqId.instanceId))
3007                {
3008                   memset(&ranFuncDb->subscriptionList[subsIdx], 0, sizeof(RicSubscription));
3009                   break;
3010                }
3011             }
3012          }
3013       }
3014    }
3015    return ROK;
3016 }
3017
3018 /*******************************************************************
3019 *
3020 * @brief Handles received E2AP message and sends back response  
3021 *
3022 * @details
3023 *
3024 *    Function : E2APMsgHdlr
3025 *
3026 *    Functionality:
3027 *         - Decodes received E2AP control message
3028 *         - Prepares response message, encodes and sends to SCTP
3029 *
3030 * @params[in] 
3031 * @return ROK     - success
3032 *         RFAILED - failure
3033 *
3034 * ****************************************************************/
3035 void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
3036 {
3037    int             i;
3038    char            *recvBuf;
3039    MsgLen          copyCnt;
3040    MsgLen          recvBufLen;
3041    E2AP_PDU_t      *e2apMsg;
3042    asn_dec_rval_t  rval; /* Decoder return value */
3043    E2AP_PDU_t      e2apasnmsg ;
3044  
3045    DU_LOG("\nINFO  -->  E2AP : Received E2AP message buffer");
3046    ODU_PRINT_MSG(mBuf, 0,0);
3047  
3048    /* Copy mBuf into char array to decode it */
3049    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
3050    RIC_ALLOC(recvBuf, (Size)recvBufLen);
3051
3052    if(recvBuf == NULLP)
3053    {
3054       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
3055       return;
3056    }
3057    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
3058    {
3059       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
3060       return;
3061    }
3062
3063    DU_LOG("\nDEBUG  -->  E2AP : Received flat buffer to be decoded : ");
3064    for(i=0; i< recvBufLen; i++)
3065    {
3066         DU_LOG("%x",recvBuf[i]);
3067    }
3068
3069    /* Decoding flat buffer into E2AP messsage */
3070    e2apMsg = &e2apasnmsg;
3071    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
3072
3073    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
3074    RIC_FREE(recvBuf, (Size)recvBufLen);
3075
3076    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
3077    {
3078       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
3079       return;
3080    }
3081    DU_LOG("\n");
3082    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3083
3084    switch(e2apMsg->present)
3085    {
3086       case E2AP_PDU_PR_initiatingMessage:
3087          {
3088             switch(e2apMsg->choice.initiatingMessage->value.present)
3089             {
3090                case InitiatingMessageE2__value_PR_E2setupRequest:
3091                   {
3092                      DU_LOG("\nINFO  -->  E2AP : E2 setup request received");
3093                      ProcE2SetupReq(duId, &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest);
3094                      break;
3095                   }
3096                case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate:
3097                   {
3098                      DU_LOG("\nINFO  -->  E2AP : E2 node config update received");
3099                      ProcE2NodeConfigUpdate(*duId, &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate);
3100                      break;
3101                   }
3102                case InitiatingMessageE2__value_PR_ResetRequestE2:
3103                   {
3104                      DU_LOG("\nINFO  -->  E2AP : E2 Reset Request received");
3105                      ProcE2ResetReq(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2);
3106                      break;
3107                   }
3108                case InitiatingMessageE2__value_PR_RICindication:
3109                   {
3110                      DU_LOG("\nINFO  -->  E2AP : RIC Indication Acknowledged");
3111                      break;
3112                   }
3113                case InitiatingMessageE2__value_PR_RICserviceUpdate:
3114                   {
3115                      DU_LOG("\nINFO  -->  E2AP : RIC Service update received");
3116                      ProcRicServiceUpdate(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate);
3117                      break;
3118                   }
3119
3120                default:
3121                   {
3122                      DU_LOG("\nERROR  -->  E2AP : Invalid type of intiating message [%d]", \
3123                         e2apMsg->choice.initiatingMessage->value.present);
3124                      return;
3125                   }
3126             }/* End of switch(initiatingMessage) */
3127             break;
3128          }
3129       case E2AP_PDU_PR_successfulOutcome: 
3130          {
3131             switch(e2apMsg->choice.successfulOutcome->value.present)
3132             {
3133                case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:  
3134                   {
3135                      ProcRicSubscriptionResponse(*duId, \
3136                         &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse);
3137                      break;
3138                   }
3139                default:
3140                   {
3141                      DU_LOG("\nERROR  -->  E2AP : Invalid type of successfulOutcome message [%d]", \
3142                         e2apMsg->choice.successfulOutcome->value.present);
3143                      return;
3144                   }
3145                   break;
3146             }
3147             break; 
3148          }
3149          case E2AP_PDU_PR_unsuccessfulOutcome:
3150          {
3151             switch(e2apMsg->choice.successfulOutcome->value.present)
3152             {
3153                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure:
3154                   {
3155                      ProcRicSubscriptionFailure(*duId, \
3156                         &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure);
3157                      break;
3158                   }
3159                default:
3160                   {
3161                      DU_LOG("\nERROR  -->  E2AP : Invalid type of unsuccessfulOutcome message [%d]", \
3162                         e2apMsg->choice.unsuccessfulOutcome->value.present);
3163                      return;
3164                   }
3165             }
3166             break;
3167          }
3168       default:
3169          {
3170             DU_LOG("\nERROR  -->  E2AP : Invalid type message type ");
3171             return;
3172          }
3173
3174    }/* End of switch(e2apMsg->present) */
3175 } /* End of E2APMsgHdlr */
3176
3177
3178 /**********************************************************************
3179   End of file
3180  **********************************************************************/