[Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-532] RIC Subscription Delete Required
[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 Fetches RAN Function DB
131  *
132  * @details
133  *
134  *    Function : fetchRanFuncFromRanFuncId
135  *
136  *    Functionality: Fetches RAN function DB from E2AP DB using
137  *       RAN function ID
138  *
139  * @params[in] RAN Function ID
140  * @return RAN Function DB
141  *         NULL, in case of failure
142  *
143  * ****************************************************************/
144 RanFunction *fetchRanFuncFromRanFuncId(DuDb *duDb, uint16_t ranFuncId)
145 {
146    RanFunction *ranFuncDb = NULLP;
147
148    /* Fetch RAN Function DB */
149    if(duDb->ranFunction[ranFuncId-1].id == ranFuncId)
150    {
151       ranFuncDb = &duDb->ranFunction[ranFuncId-1];
152    }
153    else
154    {
155       DU_LOG("\nERROR  -->  DU_APP : fetchRanFuncFromRanFuncId: Invalid RAN Function ID[%d]", ranFuncId);
156    }
157
158    return ranFuncDb;
159 }
160
161 /*******************************************************************
162  *
163  * @brief Fetch subscripton DB
164  *
165  * @details
166  *
167  *    Function : fetchSubsInfoFromRicReqId
168  *
169  *    Functionality: Fetches subscription DB from RAN Function DB
170  *       using RIC Request ID
171  *
172  * @params[in] RIC Request ID
173  *             RAN Function DB
174  *             Pointer to RIC Subscription node to be searched
175  * @return RIC Subscription from RAN Function's subcription list
176  *         NULL, in case of failure
177  *
178  * ****************************************************************/
179 RicSubscription *fetchSubsInfoFromRicReqId(RicRequestId ricReqId, RanFunction *ranFuncDb, CmLList **ricSubscriptionNode)
180 {
181    RicSubscription *ricSubscriptionInfo = NULLP;
182
183    /* Fetch subscription detail in RAN Function DB */
184    CM_LLIST_FIRST_NODE(&ranFuncDb->subscriptionList, *ricSubscriptionNode);
185    while(*ricSubscriptionNode)
186    {
187       ricSubscriptionInfo = (RicSubscription *)((*ricSubscriptionNode)->node);
188       if(ricSubscriptionInfo && (ricSubscriptionInfo->requestId.requestorId == ricReqId.requestorId) &&
189             (ricSubscriptionInfo->requestId.instanceId == ricReqId.instanceId))
190       {
191          break;
192       }
193       *ricSubscriptionNode = (*ricSubscriptionNode)->next;
194       ricSubscriptionInfo = NULLP;
195    }
196
197    if(!ricSubscriptionInfo)
198    {
199       DU_LOG("\nERROR  -->  E2AP : fetchSubsInfoFromRicReqId: Subscription not found for Requestor ID [%d] \
200          Instance ID [%d] in RAN Function ID [%d]", ricReqId.requestorId, ricReqId.instanceId, ranFuncDb->id);
201    }
202
203    return ricSubscriptionInfo;
204 }
205
206 /*******************************************************************
207  *
208  * @brief Fetch Action details
209  *
210  * @details
211  *
212  *    Function : fetchActionInfoFromActionId
213  *
214  *    Functionality: Fetch action details from RIC subscription DB
215  *       using action ID
216  *
217  * @params[in] Action ID
218  *             RIC Subscription DB
219  * @return Action Info DB
220  *         NULL, in case of failure
221  *
222  * ****************************************************************/
223 ActionInfo *fetchActionInfoFromActionId(uint8_t actionId, RicSubscription *ricSubscriptionInfo)
224 {
225    ActionInfo *actionInfoDb = NULLP;
226    if(ricSubscriptionInfo->actionSequence[actionId].actionId == actionId)
227    {
228       actionInfoDb = &ricSubscriptionInfo->actionSequence[actionId];
229    }
230    else
231    {
232       DU_LOG("\nERROR  -->  E2AP : fetchActionInfoFromActionId: Action Id [%d] not found in \
233          subscription info [Requestor id : %d] [Instance Id : %d]", actionId,\
234          ricSubscriptionInfo->requestId.requestorId, ricSubscriptionInfo->requestId.instanceId);
235
236    }
237    return actionInfoDb;
238 }
239
240 /*******************************************************************
241  *
242  * @brief deallocate memory allocated in E2 Node Config Update Failure
243  *
244  * @details
245  *
246  *    Function : FreeE2ConfigUpdateFail
247  *
248  *    Functionality: deallocate memory allocated in E2 Node Config Update Failure
249  *
250  * @params[in] E2AP_PDU_t *e2apMsg
251  *
252  * @return void
253  * ****************************************************************/
254
255 void FreeE2ConfigUpdateFail(E2AP_PDU_t *e2apMsg)
256 {
257    uint8_t arrIdx = 0;
258    E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdFail=NULL;
259
260    if(e2apMsg)
261    {
262       if(e2apMsg->choice.unsuccessfulOutcome)
263       {
264          e2NodeCfgUpdFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2nodeConfigurationUpdateFailure;
265          if(e2NodeCfgUpdFail->protocolIEs.list.array)
266          {
267             for(arrIdx=0; arrIdx<e2NodeCfgUpdFail->protocolIEs.list.count; arrIdx++)
268             {
269                RIC_FREE(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateFailure_IEs_t));
270             }
271             RIC_FREE(e2NodeCfgUpdFail->protocolIEs.list.array, e2NodeCfgUpdFail->protocolIEs.list.size);
272          }
273          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
274       }
275       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
276    }
277 }
278
279 /*******************************************************************
280  *
281  * @brief Buld and send the E2 Node Config Update failure
282  *
283  * @details
284  *
285  *    Function : BuildAndSendE2NodeConfigUpdateFailure
286  *
287  *    Functionality:
288  *         - Buld and send the E2 Node Config Update failure
289  * @return ROK     - success
290  *         RFAILED - failure
291  *
292  * ****************************************************************/
293
294 uint8_t BuildAndSendE2NodeConfigUpdateFailure(uint32_t duId, uint8_t transId, uint8_t causeInfo, uint8_t causeReason)
295 {
296    E2AP_PDU_t         *e2apMsg = NULL;
297    asn_enc_rval_t     encRetVal;
298    uint8_t            arrIdx=0;
299    uint8_t            elementCnt=0;
300    bool  memAllocFailed = false;
301    E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdateFail=NULL;
302
303    DU_LOG("\nINFO   -->  E2AP : Building E2 Node Config Update failure\n");
304    while(true)
305    {
306       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
307       if(e2apMsg == NULLP)
308       {
309          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
310          break;
311       }
312       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
313       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
314       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
315       {
316          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
317          break;
318       }
319
320       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
321       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
322       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateFailure;
323       e2NodeCfgUpdateFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2nodeConfigurationUpdateFailure;
324
325       elementCnt = 3;
326       e2NodeCfgUpdateFail->protocolIEs.list.count = elementCnt;
327       e2NodeCfgUpdateFail->protocolIEs.list.size  = elementCnt * sizeof(struct E2nodeConfigurationUpdateFailure_IEs *);
328
329       RIC_ALLOC(e2NodeCfgUpdateFail->protocolIEs.list.array, e2NodeCfgUpdateFail->protocolIEs.list.size);
330       if(e2NodeCfgUpdateFail->protocolIEs.list.array == NULLP)
331       {
332          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2 node config update failure array failed");
333          break;
334       }
335
336       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
337       {
338          RIC_ALLOC(e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx], sizeof(struct E2nodeConfigurationUpdateFailure_IEs));
339          if(e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx] == NULLP)
340          {
341             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2 node config update failure IEs failed");
342             memAllocFailed = true;
343             break;
344          }
345       }
346
347       if(memAllocFailed == true)
348       {
349           break;
350       }
351
352       /* Trans Id */
353       arrIdx = 0;
354       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
355       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
356       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TransactionID;
357       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
358
359       arrIdx++;
360       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
361       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
362       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_CauseE2;
363       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.present = causeInfo;
364       if(causeInfo == CauseE2_PR_e2Node) 
365          e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.e2Node = causeReason;
366       else
367          e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.misc = causeReason;
368
369       arrIdx++;
370       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
371       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
372       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TimeToWaitE2;
373       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
374
375       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
376       memset(encBuf, 0, ENC_BUF_MAX_LEN);
377       encBufSize = 0;
378       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
379
380       /* Check encode results */
381       if(encRetVal.encoded == ENCODE_FAIL)
382       {
383          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Node Config Update failure structure (at %s)\n",\
384                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
385          break;
386       }
387       else
388       {
389          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Node Config Update Failure\n");
390          for(int i=0; i< encBufSize; i++)
391          {
392             DU_LOG("%x",encBuf[i]);
393          }
394       }
395
396       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
397       {
398          DU_LOG("\nERROR  -->  E2AP : Sending E2 Node Config Update Failure failed");
399          break;
400       }
401       break;
402    }
403
404    FreeE2ConfigUpdateFail(e2apMsg);
405    return ROK;
406 }
407
408 /*******************************************************************
409  *
410  * @brief process the E2 node configuration update
411  *
412  * @details
413  *
414  *    Function : ProcE2NodeConfigUpdate 
415  *
416  * Functionality: Process E2 node configuration update
417  *
418  * @return ROK     - success
419  *         RFAILED - failure
420  *
421  ******************************************************************/
422
423 void ProcE2NodeConfigUpdate(uint32_t duId, E2nodeConfigurationUpdate_t *e2NodeConfigUpdate)
424 {
425    uint8_t ieIdx = 0;
426    uint8_t transId = 0, e2NodeUpdateListIdx=0;
427    E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList=NULLP;
428    E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItemIe=NULLP;
429    E2nodeComponentConfigUpdate_Item_t *e2NodeUpdateItem =NULLP;
430
431    if(e2NodeConfigUpdate)
432    {
433       if(e2NodeConfigUpdate->protocolIEs.list.array)
434       {
435          for(ieIdx=0; ieIdx < e2NodeConfigUpdate->protocolIEs.list.count; ieIdx++)
436          {
437             if(e2NodeConfigUpdate->protocolIEs.list.array[ieIdx])
438             {
439                switch(e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]->id)
440                {
441                   case ProtocolIE_IDE2_id_TransactionID:
442                      transId = e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
443                      break;
444                   
445                   default:
446                   {
447                      /*TODO - Other IEs will be handling in next gerrit*/
448                      break;
449                   }
450                }
451             }
452          }
453       }
454    }
455 }
456
457 /*******************************************************************
458  *
459  * @brief Builds Global RIC Id Params
460  *
461  * @details
462  *
463  *    Function : BuildGlobalRicId
464  *
465  *    Functionality: Building the Plmn and ric id
466  *
467  * @params[in] GlobalRIC_ID_t *ricId
468  * @return ROK     - success
469  *         RFAILED - failure
470  *
471  * ****************************************************************/
472
473 uint8_t BuildGlobalRicId(GlobalRIC_ID_t *ricId)
474 {
475    uint8_t unused = 4;
476    uint8_t byteSize = 3;
477    uint8_t ricVal= 1;
478    if(ricId != NULLP)
479    {
480       ricId->pLMN_Identity.size = byteSize * sizeof(uint8_t);
481       RIC_ALLOC(ricId->pLMN_Identity.buf,  ricId->pLMN_Identity.size);
482       buildPlmnId(ricCb.ricCfgParams.plmn , ricId->pLMN_Identity.buf);
483       /* fill ric Id */
484       ricId->ric_ID.size = byteSize * sizeof(uint8_t);
485       RIC_ALLOC(ricId->ric_ID.buf, ricId->ric_ID.size);
486       fillBitString(&ricId->ric_ID, unused, byteSize, ricVal);
487    }
488    return ROK;   
489 }
490
491 /*******************************************************************
492  *
493  * @brief deallocate the memory allocated in E2SetupResponse
494  *
495  * @details
496  *
497  *    Function : FreeE2SetupRsp 
498  *
499  *    Functionality: deallocate the memory allocated in E2SetupResponse 
500  *
501  * @params[in] E2AP_PDU_t *e2apMsg
502  *
503  * @return void
504  * ****************************************************************/
505 void FreeE2SetupRsp(E2AP_PDU_t *e2apMsg)
506 {
507    uint8_t arrIdx = 0, e2NodeConfigIdx=0, ranFuncIdx=0;
508    RANfunctionsID_List_t *ranFuncAcceptedList=NULL;
509    E2setupResponse_t  *e2SetupRsp=NULL;
510    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItemIe=NULL;
511    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList=NULL;
512    E2nodeComponentInterfaceF1_t *f1InterfaceInfo=NULL;
513    
514    if(e2apMsg)
515    {
516       if(e2apMsg->choice.successfulOutcome)
517       {
518          e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
519          if(e2SetupRsp->protocolIEs.list.array)
520          {
521             for(arrIdx=0; arrIdx<e2SetupRsp->protocolIEs.list.count; arrIdx++)
522             {
523                switch(e2SetupRsp->protocolIEs.list.array[arrIdx]->id)
524                {
525                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
526                   {
527                      ranFuncAcceptedList= &e2SetupRsp->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
528                      if(ranFuncAcceptedList->list.array)
529                      {
530                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAcceptedList->list.count; ranFuncIdx++)
531                         {
532                            if(ranFuncAcceptedList->list.array[ranFuncIdx])
533                            {
534                               RIC_FREE(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
535                            }
536                         }
537                         RIC_FREE(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
538                      }
539                      break;
540                   }
541                   case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
542                   {
543                      e2NodeConfigAdditionAckList =&e2SetupRsp->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
544                      if(e2NodeConfigAdditionAckList->list.count)
545                      {
546                         for(e2NodeConfigIdx=0; e2NodeConfigIdx<e2NodeConfigAdditionAckList->list.count; e2NodeConfigIdx++)
547                         {
548                            e2NodeAddAckItemIe = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[e2NodeConfigIdx];
549                            if(e2NodeAddAckItemIe)
550                            {
551                               f1InterfaceInfo = e2NodeAddAckItemIe->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1; 
552                               if(f1InterfaceInfo)
553                               {
554                                  RIC_FREE(f1InterfaceInfo->gNB_DU_ID.buf, f1InterfaceInfo->gNB_DU_ID.size);
555                                  RIC_FREE(f1InterfaceInfo, sizeof(E2nodeComponentInterfaceF1_t));
556                               }
557                               RIC_FREE(e2NodeAddAckItemIe, sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
558                            }
559                         }
560                         RIC_FREE(e2NodeConfigAdditionAckList->list.array, e2NodeConfigAdditionAckList->list.size);
561                      }
562                      break;
563                   }
564                }
565                RIC_FREE(e2SetupRsp->protocolIEs.list.array[arrIdx], sizeof(E2setupResponseIEs_t)); 
566             }
567             RIC_FREE(e2SetupRsp->protocolIEs.list.array, e2SetupRsp->protocolIEs.list.size);
568          }
569          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
570       }
571       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
572    }
573 }
574
575 /*******************************************************************
576  *
577  * @brief Build E2node Component config addition ack list
578  *
579  * @details
580  *
581  *    Function :  BuildE2nodeComponentConfigAdditionAck
582  *
583  *    Functionality: deallocate the memory allocated in E2SetupResponse 
584  *
585  * @params[in] E2nodeComponentConfigAdditionAck_List_t
586  * *e2NodeConfigAdditionAckList
587  *
588  * @return ROK - success
589  *         RFAILED - failure
590  * ****************************************************************/
591
592 uint8_t BuildE2nodeComponentConfigAdditionAck(E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList, DuDb *duDb)
593 {
594    uint8_t arrIdx = 0;
595    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem;
596    
597    e2NodeConfigAdditionAckList->list.count = 1;
598    e2NodeConfigAdditionAckList->list.size = e2NodeConfigAdditionAckList->list.count * sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t*);
599    RIC_ALLOC(e2NodeConfigAdditionAckList->list.array, e2NodeConfigAdditionAckList->list.size);
600    if(e2NodeConfigAdditionAckList->list.array == NULLP)
601    {
602       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
603       return RFAILED;
604    }
605
606    for(arrIdx = 0; arrIdx< e2NodeConfigAdditionAckList->list.count; arrIdx++)
607    {
608       RIC_ALLOC(e2NodeConfigAdditionAckList->list.array[arrIdx], sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
609       if(e2NodeConfigAdditionAckList->list.array[arrIdx] == NULLP)
610       {
611          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
612          return RFAILED;
613       }
614    }
615    e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[0];
616    e2NodeAddAckItem->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck_Item;
617    e2NodeAddAckItem->criticality = CriticalityE2_reject;
618    e2NodeAddAckItem->value.present = E2nodeComponentConfigAdditionAck_ItemIEs__value_PR_E2nodeComponentConfigAdditionAck_Item;
619    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentInterfaceType = duDb->e2NodeComponent.interfaceType;
620
621    /* >E2 Node Component ID */
622    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1;
623    RIC_ALLOC(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\
624          sizeof(E2nodeComponentInterfaceF1_t));
625    if(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1 == NULLP)
626    {
627       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
628       return RFAILED;
629    }
630    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t);
631    RIC_ALLOC(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
632          e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
633
634    if(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP)
635    {
636       DU_LOG("\nERROR  -->list.  E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
637       return RFAILED;
638    }
639    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]  = duDb->e2NodeComponent.componentId;
640    
641    /* >E2 Node Component Configuration Acknowledge*/
642    e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentConfigurationAck.updateOutcome = \
643    E2nodeComponentConfigurationAck__updateOutcome_success;
644    
645    return ROK;  
646 }
647
648 /*******************************************************************
649  *
650  * @brief Build RAN function accepted list
651  *
652  * @details
653  *
654  *    Function : BuildRanFunctionAcceptedList
655  *
656  *    Functionality: Build RAN function accepted list 
657  *     ->For ProcedureCodeE2_id_E2setup or ProcedureCodeE2_id_RICserviceQuery  
658  *     we add all the RAN Function list which is present in RIC database.
659  *     ->For any other procedures, we just fill the RAN functions whose ID 
660  *     is present in the recvList
661  *
662  * @params[in] 
663  *    Stored DU databse 
664  *    Count of ran functions to be accepted in the list 
665  *    Received list of RAN functions
666  *    RAN Function list  
667  *    Procedure Code 
668  *
669  * @return ROK - success
670  *         RFAILED - failure
671  * ****************************************************************/
672
673 uint8_t BuildRanFunctionAcceptedList(DuDb *duDb, uint8_t count, RanFunction *ranFunAcceptedList, RANfunctionsID_List_t *ranFuncAcceptedList, uint8_t procedureCode)
674 {
675    uint8_t ranFuncIdx = 0;
676    RANfunctionID_ItemIEs_t *ranFuncAcceptedItemIe=NULL;
677    
678    /* For ProcedureCodeE2_id_E2setup and ProcedureCodeE2_id_RICserviceQuery, 
679     * the number of RAN function list items is equal to the number of 
680     * ran function entries stored in the database.
681     * For any other procedure, the RAN function list count is equal
682     * to the count of ran functions obtained from the function's caller */
683
684    if((procedureCode == ProcedureCodeE2_id_RICserviceQuery)||(procedureCode == ProcedureCodeE2_id_E2setup))
685       ranFuncAcceptedList->list.count = duDb->numOfRanFunction;
686    else
687       ranFuncAcceptedList->list.count = count;
688    
689    ranFuncAcceptedList->list.size = ranFuncAcceptedList->list.count*sizeof(RANfunctionID_ItemIEs_t*);
690    RIC_ALLOC(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
691    if(ranFuncAcceptedList->list.array)
692    {
693       for(ranFuncIdx = 0; ranFuncIdx< ranFuncAcceptedList->list.count; ranFuncIdx++)
694       {
695          RIC_ALLOC(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
696          if(ranFuncAcceptedList->list.array[ranFuncIdx] == NULLP)
697          {
698             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function added list array item");
699             return RFAILED;
700          }
701          ranFuncAcceptedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAcceptedList->list.array[ranFuncIdx];
702          ranFuncAcceptedItemIe->id = ProtocolIE_IDE2_id_RANfunctionID_Item;
703          ranFuncAcceptedItemIe->criticality= CriticalityE2_ignore;
704          ranFuncAcceptedItemIe->value.present = RANfunctionID_ItemIEs__value_PR_RANfunctionID_Item;
705          if((procedureCode == ProcedureCodeE2_id_RICserviceQuery)||(procedureCode == ProcedureCodeE2_id_E2setup))
706          {
707             /* filling the RAN function information with the help of DuDb */
708             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionID = duDb->ranFunction[ranFuncIdx].id;
709             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision= duDb->ranFunction[ranFuncIdx].revisionCounter;
710          }
711          else
712          {
713             /* filling the the RAN function information with the help received list of RAN functions */
714             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionID = ranFunAcceptedList[ranFuncIdx].id;
715             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision= ranFunAcceptedList[ranFuncIdx].revisionCounter;
716          }
717       }
718    }
719    else
720    {
721       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function added list array");
722       return RFAILED;
723    }
724    return ROK;
725 }
726
727 /*******************************************************************
728  *
729  * @brief Builds and sends the E2SetupResponse
730  *
731  * @details
732  *
733  *    Function : BuildAndSendE2SetupRsp
734  *
735  *    Functionality: Constructs the F1SetupResponse message and sends
736  *                   it back to the DU through SCTP.
737  *
738  * @params[in] void **buf,Buffer to which encoded pattern is written into
739  * @params[in] int *size,size of buffer
740  *
741  * @return ROK     - success
742  *         RFAILED - failure
743  *
744  * ****************************************************************/
745
746 uint8_t BuildAndSendE2SetupRsp(DuDb *duDb, uint8_t transId)
747 {
748    E2AP_PDU_t         *e2apMsg = NULL;
749    E2setupResponse_t  *e2SetupRsp;
750    asn_enc_rval_t     encRetVal; 
751    uint8_t            idx;
752    uint8_t            elementCnt;
753    bool  memAllocFailed = false;
754  
755    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup Response\n");
756    while(true)
757    {
758       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); 
759       if(e2apMsg == NULLP)
760       {
761          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
762          break;
763       }
764       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
765       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
766       if(e2apMsg->choice.successfulOutcome == NULLP)
767       {
768          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
769          break;  
770       }
771
772       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
773       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
774       e2apMsg->choice.successfulOutcome->value.present = \
775                                                          SuccessfulOutcomeE2__value_PR_E2setupResponse;
776       e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
777
778       elementCnt = 3;
779       /* Fill Accepted RAN function IE If Ran function information is stored in databse */
780       if(duDb->numOfRanFunction)
781          elementCnt++;
782
783       e2SetupRsp->protocolIEs.list.count = elementCnt;
784       e2SetupRsp->protocolIEs.list.size  = elementCnt * sizeof(E2setupResponseIEs_t*);
785
786       RIC_ALLOC(e2SetupRsp->protocolIEs.list.array, e2SetupRsp->protocolIEs.list.size);
787       if(e2SetupRsp->protocolIEs.list.array == NULLP)
788       {
789          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");
790          break;  
791       }
792
793       for(idx=0; idx<elementCnt; idx++)
794       {
795          RIC_ALLOC(e2SetupRsp->protocolIEs.list.array[idx], sizeof(E2setupResponseIEs_t)); 
796          if(e2SetupRsp->protocolIEs.list.array[idx] == NULLP)
797          { 
798             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");
799             memAllocFailed = true;
800             break;
801          }    
802       }
803       
804       if(memAllocFailed == true)
805       {
806           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");    
807           break;
808       }
809       /* Trans Id */
810       idx = 0;
811       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_TransactionID;
812       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
813       e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_TransactionID; 
814       e2SetupRsp->protocolIEs.list.array[idx]->value.choice.TransactionID  = transId;
815
816       /* Global RIC ID */
817       idx++;
818       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_GlobalRIC_ID;
819       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
820       e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_GlobalRIC_ID;
821
822       if(BuildGlobalRicId(&(e2SetupRsp->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID))!=ROK)
823       {
824          DU_LOG("\nERROR  -->  E2AP : Failed to build Global Ric Id");
825          break;
826       }
827       
828       if(duDb->numOfRanFunction)
829       {
830          /* Accepted RAN function Id */
831          idx++;
832          e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
833          e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
834          e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_RANfunctionsID_List;
835          if(BuildRanFunctionAcceptedList(duDb, 0, NULL, &e2SetupRsp->protocolIEs.list.array[idx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_E2setup)!=ROK)
836          {
837             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
838             break;         
839          }
840       }
841
842       /* E2 Node Component Configuration Addition Acknowledge List*/
843       idx++;
844       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck;
845       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
846       e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
847          E2setupResponseIEs__value_PR_E2nodeComponentConfigAdditionAck_List;
848       if(BuildE2nodeComponentConfigAdditionAck(&e2SetupRsp->protocolIEs.list.array[idx]->\
849          value.choice.E2nodeComponentConfigAdditionAck_List, duDb) != ROK)
850       {
851          DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config addition ack list");
852          break;
853       }
854
855       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
856       memset(encBuf, 0, ENC_BUF_MAX_LEN);
857       encBufSize = 0;
858       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
859
860       /* Check encode results */
861       if(encRetVal.encoded == ENCODE_FAIL)
862       {
863          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupResponse structure (at %s)\n",\
864                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
865          break;   
866       } 
867       else 
868       {
869          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SetupResponse\n");
870          for(int i=0; i< encBufSize; i++)
871          {
872             DU_LOG("%x",encBuf[i]);
873          } 
874       }
875
876       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
877       {
878          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Response failed");      
879          break;   
880       }
881       break;
882    }
883
884    FreeE2SetupRsp(e2apMsg);
885    BuildAndSendRicSubscriptionReq(duDb);
886    return ROK;
887 }
888
889 /*******************************************************************
890  *
891  * @brief Free RIC Subscription Details
892  *
893  * @details
894  *
895  *    Function : FreeRicSubsDetails
896  *
897  *    Functionality: Free the RIC Subscription Details
898  *
899  * @params[in] RICsubscriptionDetails_t *subsDetails
900  * @return void
901  *
902  * ****************************************************************/
903 void FreeRicSubsDetails(RICsubscriptionDetails_t *subsDetails)
904 {
905    uint8_t elementIdx = 0;
906    RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
907
908    RIC_FREE(subsDetails->ricEventTriggerDefinition.buf, subsDetails->ricEventTriggerDefinition.size);
909
910    if(subsDetails->ricAction_ToBeSetup_List.list.array)
911    {
912       for(elementIdx = 0; elementIdx < subsDetails->ricAction_ToBeSetup_List.list.count; elementIdx++)
913       {
914          if(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
915          {
916             actionItem = (RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx];
917             if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
918             {
919                RIC_FREE(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf, \
920                   actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->size);
921                RIC_FREE(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, sizeof(RICactionDefinition_t));
922             }
923             RIC_FREE(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], sizeof(RICaction_ToBeSetup_ItemIEs_t))
924          }
925       }
926       RIC_FREE(subsDetails->ricAction_ToBeSetup_List.list.array, subsDetails->ricAction_ToBeSetup_List.list.size);
927    }
928 }
929
930 /*******************************************************************
931  *
932  * @brief Free RIC Subscription Request
933  *
934  * @details
935  *
936  *    Function : FreeRicSubscriptionReq
937  *
938  * Functionality : Free RIC Subscription Request
939  *
940  * @return ROK     - success
941  *         RFAILED - failure
942  *
943  ******************************************************************/
944 void FreeRicSubscriptionReq(E2AP_PDU_t *e2apRicMsg)
945 {
946    uint8_t idx = 0;
947    RICsubscriptionRequest_t   *ricSubscriptionReq;
948
949    if(e2apRicMsg)
950    {
951       if(e2apRicMsg->choice.initiatingMessage)
952       {
953          ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
954          if(ricSubscriptionReq->protocolIEs.list.array)
955          {
956             for(idx=0; idx < ricSubscriptionReq->protocolIEs.list.count; idx++)
957             {
958                switch(ricSubscriptionReq->protocolIEs.list.array[idx]->id)
959                {
960                   case ProtocolIE_IDE2_id_RICsubscriptionDetails:
961                      {
962                         FreeRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails));
963                         break;
964                      }
965                }               
966                RIC_FREE(ricSubscriptionReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionRequest_IEs_t));
967             }
968             RIC_FREE(ricSubscriptionReq->protocolIEs.list.array, ricSubscriptionReq->protocolIEs.list.size);
969          }
970          RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
971       }
972       RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
973    }
974 }
975
976 /*******************************************************************
977  *
978  * @brief Builds Ric Request Id
979  *
980  * @details
981  *
982  *    Function : BuildNewRicRequestId
983  *
984  *    Functionality: Assign new Ric Request ID
985  *
986  * @params[in] RIC request ID to be sent
987  *             RIC request ID stored in DB
988  * @return ROK     - success
989  *         RFAILED - failure
990  *
991  * ****************************************************************/
992
993 uint8_t BuildNewRicRequestId(RICrequestID_t *ricReqId, RicRequestId *reqIdDb)
994 {
995    static uint16_t requestorId = 0;
996    static uint16_t instanceId = 0;
997
998    if(ricReqId != NULLP)
999    {
1000       ricReqId->ricRequestorID = ++requestorId;
1001       ricReqId->ricInstanceID  = ++instanceId;
1002
1003       reqIdDb->requestorId = ricReqId->ricRequestorID;
1004       reqIdDb->instanceId = ricReqId->ricInstanceID;
1005    }
1006    return ROK;
1007 }
1008
1009 /*******************************************************************
1010  *
1011  * @brief Free RIC Action Definition
1012  *
1013  * @details
1014  *
1015  *    Function : FreeRicActionDefinition
1016  *
1017  *    Functionality: Free RIC Action Definition
1018  *
1019  * @params[in] E2SM-KPM Action definition
1020  * @return void
1021  *
1022  * ****************************************************************/
1023 void  FreeRicActionDefinition(E2SM_KPM_ActionDefinition_t actionDef)
1024 {
1025    uint8_t  elementIdx = 0;
1026    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
1027    MeasurementInfoItem_t *measItem = NULLP;
1028
1029    switch(actionDef.actionDefinition_formats.present)
1030    {
1031       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
1032          {
1033             if(actionDef.actionDefinition_formats.choice.actionDefinition_Format1)
1034             {
1035                actionFormat1 = actionDef.actionDefinition_formats.choice.actionDefinition_Format1;
1036                if(actionFormat1->measInfoList.list.array)
1037                {
1038                   for(elementIdx = 0; elementIdx < actionFormat1->measInfoList.list.count; elementIdx++)
1039                   {
1040                      if(actionFormat1->measInfoList.list.array[elementIdx])
1041                      {
1042                         measItem = actionFormat1->measInfoList.list.array[elementIdx];
1043                         switch(measItem->measType.present)
1044                         {
1045                            case MeasurementType_PR_NOTHING:
1046                            case MeasurementType_PR_measID:
1047                               break;
1048                            case MeasurementType_PR_measName:
1049                            {
1050                               RIC_FREE(measItem->measType.choice.measName.buf, measItem->measType.choice.measName.size)
1051                               break;
1052                            }
1053                         }
1054                         RIC_FREE(measItem, sizeof(MeasurementInfoItem_t));
1055                      }
1056                   }
1057                   RIC_FREE(actionFormat1->measInfoList.list.array, actionFormat1->measInfoList.list.size);
1058                }
1059                RIC_FREE(actionFormat1, sizeof(E2SM_KPM_ActionDefinition_Format1_t));
1060             }
1061             break;
1062          }
1063
1064       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format2:
1065       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format3:
1066       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format4:
1067       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format5:
1068       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_NOTHING:
1069          break;
1070    }
1071 }
1072
1073 /*******************************************************************
1074  *
1075  * @brief Fill RIC Action Definition
1076  *
1077  * @details
1078  *
1079  *    Function : fillRicActionDef
1080  *
1081  *    Functionality: Fill RIC Action Definition
1082  *
1083  * @params[in] RIC Action definition
1084  * @return ROK 
1085  *         RFAILED
1086  *
1087  * ****************************************************************/
1088 uint8_t fillRicActionDef(RICactionDefinition_t *ricActionDef)
1089 {
1090    uint8_t ret = RFAILED;
1091    asn_enc_rval_t  encRetVal;
1092    uint8_t elementCnt = 0, elementIdx = 0;
1093    char    *measurementTypeName[] = {"RRU.PrbTotDl", "RRU.PrbTotUl"};
1094    E2SM_KPM_ActionDefinition_t actionDef;
1095    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
1096    MeasurementInfoItem_t *measItem = NULLP;
1097    
1098    while(true)
1099    {
1100       /* Fill E2SM-KPM Action Definition Format 1 */
1101
1102       /* RIC Stype Type */
1103       actionDef.ric_Style_Type = RIC_STYLE_TYPE;
1104
1105       /* RIC Action Definition Format 1 */
1106       actionDef.actionDefinition_formats.present = \
1107            E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1;
1108
1109       RIC_ALLOC(actionDef.actionDefinition_formats.choice.actionDefinition_Format1, \
1110             sizeof(E2SM_KPM_ActionDefinition_Format1_t));
1111       if(actionDef.actionDefinition_formats.choice.actionDefinition_Format1 == NULLP)
1112       {
1113          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1114          break;
1115       }
1116       actionFormat1 = actionDef.actionDefinition_formats.choice.actionDefinition_Format1;
1117
1118       /* Measurement Info List */
1119       elementCnt = 2;
1120       actionFormat1->measInfoList.list.count = elementCnt;
1121       actionFormat1->measInfoList.list.size = elementCnt * sizeof(MeasurementInfoItem_t *);
1122       RIC_ALLOC(actionFormat1->measInfoList.list.array, actionFormat1->measInfoList.list.size);
1123       if(actionFormat1->measInfoList.list.array == NULL)
1124       {
1125          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1126          break;
1127       }
1128
1129       for(elementIdx = 0; elementIdx < elementCnt; elementIdx++)
1130       {
1131          RIC_ALLOC(actionFormat1->measInfoList.list.array[elementIdx], sizeof(MeasurementInfoItem_t));
1132          if(actionFormat1->measInfoList.list.array[elementIdx] == NULLP)
1133          {
1134             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1135             break;
1136          }
1137
1138          measItem = actionFormat1->measInfoList.list.array[elementIdx];
1139          measItem->measType.present = MeasurementType_PR_measName;
1140
1141          measItem->measType.choice.measName.size = strlen(measurementTypeName[elementIdx]);
1142          RIC_ALLOC(measItem->measType.choice.measName.buf, measItem->measType.choice.measName.size);
1143          if(measItem->measType.choice.measName.buf == NULLP)
1144          {
1145             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1146             break;
1147          }
1148          memcpy(measItem->measType.choice.measName.buf, measurementTypeName[elementIdx], measItem->measType.choice.measName.size);
1149       }
1150       if(elementIdx < elementCnt)
1151          break;
1152
1153       /* Granularity Period */
1154       actionFormat1->granulPeriod = RIC_ACTION_GRANULARITY_PERIOD; /* In ms */
1155
1156       /* Prints the Msg formed */
1157       xer_fprint(stdout, &asn_DEF_E2SM_KPM_ActionDefinition, &actionDef);
1158
1159       /* Encode E2SM-KPM RIC Action Definition */
1160       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1161       encBufSize = 0;
1162       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_ActionDefinition, 0, &actionDef, PrepFinalEncBuf, encBuf);
1163       if(encRetVal.encoded == ENCODE_FAIL)
1164       {
1165          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM action definition structure (at %s)\n",\
1166                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1167          break;
1168       }
1169
1170       /* Copty encoded E2SM-KPM RIC action definition to E2AP octet string buffer */
1171       ricActionDef->size = encBufSize;
1172       RIC_ALLOC(ricActionDef->buf, encBufSize);
1173       if(ricActionDef->buf == NULLP)
1174       {
1175          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1176          break;
1177       }
1178       memcpy(ricActionDef->buf, encBuf, encBufSize);
1179
1180       ret = ROK;
1181       break;
1182    }
1183
1184    FreeRicActionDefinition(actionDef);
1185    return ret;
1186 }
1187
1188 /*******************************************************************
1189  *
1190  * @brief Fills RIC Action To Be Setup Item
1191  *
1192  * @details
1193  *
1194  *    Function : fillActionToBeSetup
1195  *
1196  *    Functionality: Fill the RIC Action To Be Setup Ite,
1197  *                   RIC subscription DB
1198  *
1199  * @params[in] RICaction_ToBeSetup_ItemIEs_t *items
1200  * @return ROK     - success
1201  *         RFAILED - failure
1202  *
1203  * ****************************************************************/
1204 uint8_t fillActionToBeSetup(RICaction_ToBeSetup_ItemIEs_t *actionItem, RicSubscription *ricSubsDb)
1205 {
1206    static uint8_t ricActionId = 0;
1207
1208    if(actionItem == NULLP)
1209    {
1210       DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1211       return RFAILED;
1212    }
1213
1214    while(true)
1215    {
1216       actionItem->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item;
1217       actionItem->criticality   =  CriticalityE2_ignore;
1218       actionItem->value.present =  RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
1219       
1220       /* RIC Action ID */
1221       actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID = ricActionId;
1222       ricSubsDb->actionSequence[ricActionId].actionId = \
1223          actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
1224       ricActionId++;
1225
1226       /* RIC Action Type */
1227       actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType = RICactionType_report;
1228
1229       /* RIC Action Definition */
1230       RIC_ALLOC(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, sizeof(RICactionDefinition_t));
1231       if(!actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
1232       {
1233          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1234          break;
1235       }
1236       if(fillRicActionDef(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition) != ROK)
1237       {
1238          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1239          break;
1240       }
1241       
1242       ricSubsDb->numOfActions++;
1243       return ROK;
1244    }
1245
1246    memset(&ricSubsDb->actionSequence[ricActionId], 0, sizeof(ActionInfo));
1247    ricSubsDb->actionSequence[ricActionId].actionId = -1;
1248    return RFAILED;
1249 }
1250
1251 /*******************************************************************
1252  *
1253  * @brief Free Event Trigger Definition
1254  *
1255  * @details
1256  *
1257  *    Function : FreeEventTriggerDef
1258  *
1259  *    Functionality: Free Event Trigger Definition
1260  *
1261  * @params[in] E2SM-KPM Event Trigger Definition
1262  * @return void
1263  *
1264  * ****************************************************************/
1265 void  FreeEventTriggerDef(E2SM_KPM_EventTriggerDefinition_t *eventTiggerDef)
1266 {
1267    if(eventTiggerDef)
1268    {
1269       switch(eventTiggerDef->eventDefinition_formats.present)
1270       {
1271          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING:
1272             break;
1273          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1: 
1274             RIC_FREE(eventTiggerDef->eventDefinition_formats.choice.eventDefinition_Format1, \
1275                   sizeof(E2SM_KPM_EventTriggerDefinition_Format1_t));
1276             break;                  
1277       }         
1278    }
1279 }
1280
1281 /*******************************************************************
1282  *
1283  * @brief Fill Event Trigger Definition
1284  *
1285  * @details
1286  *
1287  *    Function : fillEventTriggerDef
1288  *
1289  *    Functionality: Fill Event Trigger Definition
1290  *
1291  * @params[in] RIC Event Trigger Definition
1292  * @return ROK
1293  *         RFAILED
1294  *
1295  * ****************************************************************/
1296 uint8_t fillEventTriggerDef(RICeventTriggerDefinition_t *ricEventTriggerDef)
1297 {
1298    uint8_t ret = RFAILED;
1299    asn_enc_rval_t  encRetVal;
1300    E2SM_KPM_EventTriggerDefinition_t eventTiggerDef;
1301
1302    while(true)
1303    {
1304       /* Fill E2SM-KPM Event Trigger Definition Format 1 */
1305       eventTiggerDef.eventDefinition_formats.present = \
1306        E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1;
1307
1308       RIC_ALLOC(eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1, \
1309             sizeof(E2SM_KPM_EventTriggerDefinition_Format1_t));
1310       if(eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1 == NULLP)
1311       {
1312          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1313          break;
1314       }
1315
1316       eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1->reportingPeriod = 1000; /* In ms */
1317
1318       /* Prints the Msg formed */
1319       xer_fprint(stdout, &asn_DEF_E2SM_KPM_EventTriggerDefinition, &eventTiggerDef);
1320
1321       /* Encode E2SM-KPM Event Trigger Definition */
1322       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1323       encBufSize = 0;
1324       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_EventTriggerDefinition, 0, &eventTiggerDef, PrepFinalEncBuf, encBuf);
1325       if(encRetVal.encoded == ENCODE_FAIL)
1326       {
1327          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM event trigger definition structure (at %s)\n",\
1328                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1329          break;
1330       }
1331
1332       /* Copy encoded E2SM-KPM event trigger definition to E2AP octet string buffer */
1333       ricEventTriggerDef->size = encBufSize;
1334       RIC_ALLOC(ricEventTriggerDef->buf, encBufSize);
1335       if(ricEventTriggerDef->buf == NULLP)
1336       {
1337          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1338          break;
1339       }
1340       memcpy(ricEventTriggerDef->buf, encBuf, encBufSize);
1341
1342       ret = ROK;
1343       break;
1344    }
1345
1346    FreeEventTriggerDef(&eventTiggerDef);
1347    return ret;
1348 }
1349
1350 /*******************************************************************
1351  *
1352  * @brief builds RIC Subscription Details
1353  *
1354  * @details
1355  *
1356  *    Function : BuildsRicSubsDetails
1357  *
1358  *    Functionality: Builds the RIC Subscription Details
1359  *
1360  * @params[in] RIC Subscription details to be filled
1361  *             RIC subscriotion DB
1362  * @return ROK     - success
1363  *         RFAILED - failure
1364  *
1365  * ****************************************************************/
1366
1367 uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails, RicSubscription *ricSubsInfo)
1368 {
1369    uint8_t elementCnt = 0;
1370    uint8_t elementIdx = 0;
1371
1372    if(subsDetails == NULLP)
1373    {
1374       DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1375       return RFAILED;
1376    }
1377
1378    while(true)
1379    {
1380       /* RIC Event Trigger Definition */
1381       if(fillEventTriggerDef(&subsDetails->ricEventTriggerDefinition) != ROK)
1382       {
1383          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1384          break;
1385       }
1386
1387       /* RIC Actions To Be Setup List */
1388       elementCnt = 1;
1389       subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt;
1390       subsDetails->ricAction_ToBeSetup_List.list.size = elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t *);
1391       RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, subsDetails->ricAction_ToBeSetup_List.list.size);
1392       if(subsDetails->ricAction_ToBeSetup_List.list.array  == NULLP)
1393       {
1394          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICactionToBeSetup Items failed");
1395          break;
1396       } 
1397
1398       for(elementIdx = 0; elementIdx < elementCnt; elementIdx++)
1399       {
1400          RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], sizeof(RICaction_ToBeSetup_ItemIEs_t));
1401          if(!subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
1402          {
1403             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1404             break;
1405          }
1406       }
1407       if(elementIdx < elementCnt)
1408          break;
1409
1410
1411       elementIdx = 0;
1412       if(fillActionToBeSetup((RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], \
1413          ricSubsInfo) != ROK)
1414       {
1415          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1416          break;
1417       }
1418
1419       return ROK;
1420    }
1421    return RFAILED;
1422 }
1423
1424 /*******************************************************************
1425  *
1426  * @brief Builds and Send the RicSubscriptionReq
1427  *
1428  * @details
1429  *
1430  *    Function : BuildAndSendRicSubscriptionReq
1431  *
1432  * Functionality:Fills the RicSubscriptionReq
1433  *
1434  * @return ROK     - success
1435  *         RFAILED - failure
1436  *
1437  ******************************************************************/
1438 uint8_t BuildAndSendRicSubscriptionReq(DuDb *duDb)
1439 {
1440    uint8_t         ret = RFAILED;
1441    uint8_t         elementCnt = 0;
1442    uint8_t         idx = 0;
1443    uint8_t         actionIdx = 0;
1444    asn_enc_rval_t  encRetVal;        /* Encoder return value */
1445    E2AP_PDU_t                 *e2apRicMsg = NULL;
1446    RICsubscriptionRequest_t   *ricSubscriptionReq;
1447    RanFunction  *ranFuncDb = &duDb->ranFunction[0];
1448    CmLList *ricSubsNode = NULLP;
1449    RicSubscription *ricSubsInfo = NULLP;
1450
1451    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Request\n");
1452
1453    /* Allocate memory to store RIC subscription info in RIC DB */
1454    RIC_ALLOC(ricSubsInfo, sizeof(RicSubscription));
1455    if(!ricSubsInfo)
1456    {
1457       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1458       return RFAILED;
1459    }
1460    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
1461    {
1462       ricSubsInfo->actionSequence[actionIdx].actionId = -1;
1463    }
1464
1465    while(true)
1466    {
1467       RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
1468       if(e2apRicMsg == NULLP)
1469       {
1470          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1471          break;
1472       }
1473
1474       e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
1475       RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1476       if(e2apRicMsg->choice.initiatingMessage == NULLP)
1477       {
1478          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1479          break;
1480       }
1481       e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
1482       e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
1483       e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
1484
1485       ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
1486
1487       elementCnt = 3;
1488       ricSubscriptionReq->protocolIEs.list.count = elementCnt;
1489       ricSubscriptionReq->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
1490
1491       /* Initialize the subscription members */
1492       RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, ricSubscriptionReq->protocolIEs.list.size);
1493       if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
1494       {
1495          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1496          break;
1497       }
1498
1499       for(idx=0; idx<elementCnt; idx++)
1500       {
1501          RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionRequest_IEs_t));
1502          if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
1503          {
1504             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1505             break;
1506          }
1507       }
1508       if(idx < elementCnt)
1509          break;
1510
1511       /* Filling RIC Request Id */
1512       idx = 0;
1513       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
1514       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1515       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
1516                                                                       RICsubscriptionRequest_IEs__value_PR_RICrequestID;
1517       if(BuildNewRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID, \
1518          &ricSubsInfo->requestId) != ROK)
1519       {
1520          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : Line [%d]", __func__, __LINE__);
1521          break;
1522       }
1523
1524
1525       /* Filling RAN Function Id */
1526       idx++;
1527       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
1528       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1529       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
1530                                                                       RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
1531       ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ranFuncDb->id;
1532
1533       /* Filling RIC Subscription Details */
1534       idx++;
1535       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
1536       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1537       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
1538                                                                       RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
1539       if(BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails),\
1540          ricSubsInfo) != ROK)
1541       {
1542          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : Line [%d]", __func__, __LINE__);
1543          break;
1544       }
1545
1546       /* Prints the Msg formed */
1547       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
1548
1549       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1550       encBufSize = 0;
1551       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf, encBuf);
1552       if(encRetVal.encoded == ENCODE_FAIL)
1553       {
1554          DU_LOG("\nERROR  -->  E2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
1555                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1556          break;               
1557       }
1558       else
1559       {
1560          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
1561          for(int i=0; i< encBufSize; i++)
1562          {
1563             DU_LOG("%x",encBuf[i]);
1564          } 
1565       }
1566
1567       /* Sending msg */
1568       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
1569       {
1570          DU_LOG("\nERROR  -->  E2AP : Sending RIC subscription Request failed");
1571          break;
1572       }
1573
1574       /* Add RIC Subscription Info to RAN Function's RIC Subscription List */
1575       RIC_ALLOC(ricSubsNode , sizeof(CmLList));
1576       if(!ricSubsNode)
1577       {
1578          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1579          break;
1580       }
1581       ricSubsNode->node = (PTR)ricSubsInfo;
1582       cmLListAdd2Tail(&ranFuncDb->subscriptionList, ricSubsNode);
1583
1584       ret = ROK;
1585       break;
1586    }
1587
1588    if(ret == RFAILED)
1589    {
1590       RIC_FREE(ricSubsInfo, sizeof(RicSubscription));
1591       RIC_FREE(ricSubsNode , sizeof(CmLList));
1592    }
1593
1594    FreeRicSubscriptionReq(e2apRicMsg);
1595    return ret;
1596 }
1597
1598 /*******************************************************************
1599  *
1600  * @brief Process RicSubscriptionResponse
1601  *
1602  * @details
1603  *
1604  *    Function : ProcRicSubscriptionRsp
1605  *
1606  * Functionality: Processes RicSubscriptionRsp
1607  *
1608  * @return ROK     - void
1609  *
1610  ******************************************************************/
1611
1612 void ProcRicSubscriptionResponse(uint32_t duId, RICsubscriptionResponse_t  *ricSubscriptionRsp)
1613 {
1614    uint8_t duIdx = 0, ieIdx = 0, notAdmitIdx = 0;
1615    uint8_t ranFuncId = 0, actionId = 0;
1616    DuDb *duDb = NULLP;
1617    bool ricReqIdDecoded = false;
1618    RicRequestId ricReqId;
1619    RanFunction  *ranFuncDb = NULLP;
1620    RicSubscription *ricSubs = NULLP;
1621    CmLList *ricSubsNode = NULLP;
1622    ActionInfo *action = NULLP;
1623    RICsubscriptionResponse_IEs_t *ricSubsRspIe = NULLP;
1624    RICaction_NotAdmitted_List_t *notAdmitList = NULLP;
1625
1626    DU_LOG("\nINFO  -->  E2AP : RIC Subscription Response received");
1627
1628    /* Fetch DU DB */
1629    SEARCH_DU_DB(duIdx, duId, duDb);
1630    if(duDb == NULLP)
1631    {
1632       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
1633       return;
1634    }
1635
1636    memset(&ricReqId, 0, sizeof(RicRequestId));
1637    if(ricSubscriptionRsp)
1638    {
1639       if(ricSubscriptionRsp->protocolIEs.list.array)
1640       {
1641          for(ieIdx=0; ieIdx<ricSubscriptionRsp->protocolIEs.list.count; ieIdx++)
1642          {
1643             if(ricSubscriptionRsp->protocolIEs.list.array[ieIdx])
1644             {
1645                ricSubsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
1646                switch(ricSubscriptionRsp->protocolIEs.list.array[ieIdx]->id)
1647                {
1648                   case ProtocolIE_IDE2_id_RICrequestID:
1649                      {
1650                         ricReqId.requestorId = ricSubsRspIe->value.choice.RICrequestID.ricRequestorID;
1651                         ricReqId.instanceId = ricSubsRspIe->value.choice.RICrequestID.ricInstanceID;
1652                         ricReqIdDecoded = true;
1653                         break;
1654                      }
1655                   case ProtocolIE_IDE2_id_RANfunctionID:
1656                      {
1657                         ranFuncId = ricSubsRspIe->value.choice.RANfunctionID;
1658                         ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
1659                         if(!ranFuncDb)
1660                         {
1661                            DU_LOG("\nERROR  -->  E2AP : ProcRicSubscriptionResponse: RAN Function ID [%d] not found", ranFuncId);
1662                            return;
1663                         }
1664                         break; 
1665                      }
1666                   case ProtocolIE_IDE2_id_RICactions_Admitted:
1667                      {
1668                         break;
1669                      }
1670                   case ProtocolIE_IDE2_id_RICactions_NotAdmitted:
1671                      {
1672                         if(!(ranFuncDb && ricReqIdDecoded))
1673                            return;
1674
1675                         notAdmitList = &ricSubsRspIe->value.choice.RICaction_NotAdmitted_List;
1676                         for(notAdmitIdx = 0; notAdmitIdx < notAdmitList->list.count; notAdmitIdx++)
1677                         {
1678                            actionId = ((RICaction_NotAdmitted_ItemIEs_t *)(notAdmitList->list.array[notAdmitIdx]))->\
1679                               value.choice.RICaction_NotAdmitted_Item.ricActionID;
1680
1681                            /* Remove action from RAN Function's subscription list */
1682                            ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
1683                            if(ricSubs)
1684                            {
1685                               action = fetchActionInfoFromActionId(actionId, ricSubs);
1686                               if(action)
1687                               {
1688                                  memset(action, 0, sizeof(ActionInfo));
1689                                  ricSubs->actionSequence[actionId].actionId = -1;
1690                                  ricSubs->numOfActions--;
1691                               }
1692                            }
1693                         }
1694                         break;
1695                      }
1696                }
1697             }
1698          }
1699       }
1700    } 
1701 }
1702
1703 /*******************************************************************
1704  *
1705  * @brief deallocate the memory allocated in E2SetupFailure
1706  *
1707  * @details
1708  *
1709  *    Function : FreeE2SetupFailure 
1710  *
1711  *    Functionality: deallocate the memory allocated in E2SetupFailure 
1712  *
1713  * @params[in] E2AP_PDU_t *e2apMsg
1714  *
1715  * @return void
1716  * ****************************************************************/
1717 void FreeE2SetupFailure(E2AP_PDU_t *e2apMsg)
1718 {
1719    uint8_t arrIdx = 0;
1720    E2setupFailure_t  *e2SetupFail;
1721
1722    if(e2apMsg)
1723    {
1724       if(e2apMsg->choice.unsuccessfulOutcome)
1725       {
1726          e2SetupFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
1727          if(e2SetupFail->protocolIEs.list.array)
1728          {
1729             for(arrIdx=0; arrIdx<e2SetupFail->protocolIEs.list.count; arrIdx++)
1730             {
1731                RIC_FREE(e2SetupFail->protocolIEs.list.array[arrIdx], sizeof(E2setupFailureIEs_t)); 
1732             }
1733             RIC_FREE(e2SetupFail->protocolIEs.list.array, e2SetupFail->protocolIEs.list.size);
1734          }
1735          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
1736       }
1737       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1738    }
1739 }
1740
1741 /*******************************************************************
1742  *
1743  * @brief Buld and send the E2 Setup failure
1744  *
1745  * @details
1746  *
1747  *    Function : BuildAndSendE2SetupFailure
1748  *
1749  *    Functionality:
1750  *         - Buld and send the E2 Setup failure
1751  * @return ROK     - success
1752  *         RFAILED - failure
1753  *
1754  * ****************************************************************/
1755
1756 uint8_t BuildAndSendE2SetupFailure(uint32_t duId, uint8_t transId)
1757 {
1758    uint8_t            ret = RFAILED;
1759    E2AP_PDU_t         *e2apMsg = NULL;
1760    E2setupFailure_t   *e2SetupFailure;
1761    asn_enc_rval_t     encRetVal;
1762    uint8_t            arrIdx;
1763    uint8_t            elementCnt;
1764    bool  memAllocFailed = false;
1765
1766    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup failure\n");
1767    while(true)
1768    {
1769       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1770       if(e2apMsg == NULLP)
1771       {
1772          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1773          break;
1774       }
1775       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
1776       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
1777       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
1778       {
1779          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1780          break;
1781       }
1782
1783       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
1784       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
1785       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2setupFailure;
1786       e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
1787
1788       elementCnt = 3;
1789       e2SetupFailure->protocolIEs.list.count = elementCnt;
1790       e2SetupFailure->protocolIEs.list.size  = elementCnt * sizeof(struct E2setupFailureIEs *);
1791
1792       RIC_ALLOC(e2SetupFailure->protocolIEs.list.array, e2SetupFailure->protocolIEs.list.size);
1793       if(e2SetupFailure->protocolIEs.list.array == NULLP)
1794       {
1795          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
1796          break;
1797       }
1798
1799       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
1800       {
1801          RIC_ALLOC(e2SetupFailure->protocolIEs.list.array[arrIdx], sizeof(struct E2setupFailureIEs));
1802          if(e2SetupFailure->protocolIEs.list.array[arrIdx] == NULLP)
1803          {
1804             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
1805             memAllocFailed = true;
1806             break;
1807          }
1808       }
1809
1810       if(memAllocFailed == true)
1811       {
1812           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
1813           break;
1814       }
1815
1816       /* Trans Id */
1817       arrIdx = 0;
1818       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
1819       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1820       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TransactionID;
1821       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
1822
1823       arrIdx++;
1824       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
1825       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1826       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_CauseE2;
1827       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.present = CauseE2_PR_protocol;
1828       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.protocol = CauseE2Protocol_unspecified;
1829
1830       arrIdx++;
1831       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
1832       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
1833       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TimeToWaitE2;
1834       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
1835
1836       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1837       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1838       encBufSize = 0;
1839       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
1840
1841       /* Check encode results */
1842       if(encRetVal.encoded == ENCODE_FAIL)
1843       {
1844          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Setup failure structure (at %s)\n",\
1845                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1846          break;
1847       }
1848       else
1849       {
1850          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Setup Failure\n");
1851          for(int i=0; i< encBufSize; i++)
1852          {
1853             DU_LOG("%x",encBuf[i]);
1854          }
1855       }
1856
1857       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
1858       {
1859          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Failure failed");
1860          break;
1861       }
1862
1863       ret = ROK;
1864       break;
1865    }
1866
1867    FreeE2SetupFailure(e2apMsg);
1868    return ret;
1869 }
1870
1871 /*******************************************************************
1872  *
1873  * @brief process the e2setup request 
1874  *
1875  * @details
1876  *
1877  *    Function : ProcE2SetupReq
1878  *
1879  * Functionality: process the e2setup request
1880  *
1881  * @return ROK     - success
1882  *         RFAILED - failure
1883  *
1884  ******************************************************************/
1885
1886 uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
1887 {
1888    uint8_t arrIdx = 0, e2NodeAddListIdx =0, duIdx = 0, transId =0, ranFuncIdx;
1889    DuDb    *duDb = NULLP;
1890    E2nodeComponentConfigAddition_List_t *e2NodeAddList;
1891    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
1892    RANfunction_ItemIEs_t *ranFuncItemIe;
1893    RANfunction_Item_t  *ranFunItem;
1894    RANfunctions_List_t *ranFunctionsList;
1895
1896    if(e2SetupReq)
1897    {
1898       if(e2SetupReq->protocolIEs.list.array)      
1899       {
1900          for(arrIdx=0; arrIdx<e2SetupReq->protocolIEs.list.count; arrIdx++)
1901          {
1902             if(e2SetupReq->protocolIEs.list.array[arrIdx])
1903             {
1904                switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
1905                {
1906                   case ProtocolIE_IDE2_id_TransactionID:
1907                      {
1908                         transId = e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; 
1909                         break;
1910                      }
1911                   case ProtocolIE_IDE2_id_GlobalE2node_ID:
1912                      {
1913                         if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID)
1914                         {
1915                             *duId =e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID->buf[0];
1916
1917                             SEARCH_DU_DB(duIdx, *duId, duDb); 
1918                             if(duDb == NULLP)
1919                             {
1920                                duDb = &ricCb.duInfo[ricCb.numDu];
1921                                ricCb.numDu++;
1922                             }
1923                             memset(duDb, 0, sizeof(DuDb));
1924                             duDb->duId = *duId;
1925                         }
1926                         break;
1927                      }
1928                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
1929                      {
1930                         ranFunctionsList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
1931
1932                         if(ranFunctionsList->list.array)
1933                         {
1934                            for(ranFuncIdx=0;ranFuncIdx<ranFunctionsList->list.count; ranFuncIdx++)
1935                            {
1936                               ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncIdx]; 
1937                               ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
1938                               duDb->ranFunction[ranFunItem->ranFunctionID-1].id = ranFunItem->ranFunctionID; 
1939                               duDb->ranFunction[ranFunItem->ranFunctionID-1].revisionCounter = ranFunItem->ranFunctionRevision; 
1940                               cmLListInit(&duDb->ranFunction[ranFunItem->ranFunctionID-1].subscriptionList);
1941                               duDb->numOfRanFunction++;
1942                            }
1943                         }
1944                         break;
1945                      }
1946                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
1947                      {
1948                         e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;      
1949                         if(e2NodeAddList->list.array)
1950                         {
1951                            for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
1952                            {
1953                               if(e2NodeAddList->list.array[e2NodeAddListIdx])
1954                               {
1955                                  e2NodeAddItem = \
1956                                     (E2nodeComponentConfigAddition_ItemIEs_t *)e2NodeAddList->list.array[e2NodeAddListIdx];
1957                                  if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.\
1958                                     choice.e2nodeComponentInterfaceTypeF1)
1959                                  {
1960                                     duDb->e2NodeComponent.interfaceType = F1; 
1961                                     duDb->e2NodeComponent.componentId = \
1962                                        e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.\
1963                                        choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]; 
1964                                  }
1965                               }
1966                            }
1967                         }
1968                         break;
1969                      }
1970                      default:
1971                         break;
1972                   }
1973                }
1974             }
1975         }
1976    }
1977    
1978    if(BuildAndSendE2SetupRsp(duDb, transId) !=ROK)
1979    {
1980       DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 setup response");
1981       return RFAILED;
1982    }
1983    return ROK;   
1984 }
1985 /*******************************************************************
1986  *
1987  * @brief Deallocate the memory allocated for E2 Reset Response
1988  *
1989  * @details
1990  *
1991  *    Function : FreeE2ResetResponse
1992  *
1993  *    Functionality:
1994  *       - freeing the memory allocated for E2ResetResponse
1995  *
1996  * @params[in] E2AP_PDU_t *e2apMsg
1997  * @return ROK     - success
1998  *         RFAILED - failure
1999  *
2000  * ****************************************************************/
2001 void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg)
2002 {
2003    uint8_t ieIdx =0;
2004    ResetResponseE2_t *resetResponse =NULLP;
2005
2006    if(e2apMsg != NULLP)
2007    {
2008       if(e2apMsg->choice.successfulOutcome != NULLP)
2009       {
2010          resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
2011          if(resetResponse->protocolIEs.list.array)
2012          {
2013             for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
2014             {
2015                if(resetResponse->protocolIEs.list.array[ieIdx])
2016                {
2017                   RIC_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
2018                }
2019             }
2020             RIC_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
2021          }
2022          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2023       }
2024       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2025    }
2026 }
2027
2028 /*******************************************************************
2029  *
2030  * @brief Buld and send the Reset Response msg
2031  *
2032  * @details
2033  *
2034  *    Function : BuildAndSendResetResponse 
2035  *
2036  *    Functionality:
2037  *         - Buld and send the Reset Response Message
2038  *
2039  * @params[in] 
2040  *    DU id
2041  *    TransId Id
2042  * @return ROK     - success
2043  *         RFAILED - failure
2044  *
2045  * ****************************************************************/
2046 uint8_t BuildAndSendResetResponse(uint32_t duId, uint8_t transId)
2047 {
2048    uint8_t           ieIdx = 0, elementCnt = 0;
2049    uint8_t           ret = RFAILED;
2050    E2AP_PDU_t        *e2apMsg = NULLP;
2051    ResetResponseE2_t *resetResponse=NULL;
2052    asn_enc_rval_t    encRetVal;       /* Encoder return value */
2053
2054    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
2055    do
2056    {
2057       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2058       if(e2apMsg == NULLP)
2059       {
2060          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
2061          break;
2062       }
2063       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
2064
2065       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2066       if(e2apMsg->choice.successfulOutcome == NULLP)
2067       {
2068          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
2069          break;
2070       }
2071  
2072       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
2073       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
2074       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
2075       resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
2076
2077       elementCnt = 1;
2078       resetResponse->protocolIEs.list.count = elementCnt;
2079       resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
2080       RIC_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
2081       if(!resetResponse->protocolIEs.list.array)
2082       {
2083          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
2084          break;
2085       }
2086
2087       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
2088       {
2089          RIC_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
2090          if(!resetResponse->protocolIEs.list.array[ieIdx])
2091          {
2092             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
2093             break;
2094          }
2095       }
2096       if(ieIdx < elementCnt)
2097          break;
2098
2099       ieIdx = 0; 
2100       resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
2101       resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
2102       resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
2103       resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
2104
2105       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2106
2107       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2108       encBufSize = 0;
2109       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2110       if(encRetVal.encoded == ENCODE_FAIL)
2111       {
2112          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
2113                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2114          break;
2115       }
2116       else
2117       {
2118          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
2119          for(int i=0; i< encBufSize; i++)
2120          {
2121             DU_LOG("%x",encBuf[i]);
2122          }
2123       }
2124
2125       /* Sending msg */
2126       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
2127       {
2128          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
2129          break;
2130       }
2131
2132       ret = ROK;
2133       break;
2134    }while(true);
2135
2136    FreeE2ResetResponse(e2apMsg);
2137    return ret;
2138 }
2139
2140 /*******************************************************************
2141  *
2142  * @brief deallocate the memory allocated in building the
2143  *    Service Query message
2144  *
2145  * @details
2146  *
2147  *    Function : FreeRicServiceQuery 
2148  *
2149  *    Functionality: deallocate the memory allocated in building
2150  *    Ric Service Query message
2151  *
2152  * @params[in] E2AP_PDU_t *e2apMsg
2153  *
2154  * @return void
2155  * ****************************************************************/
2156
2157 void FreeRicServiceQuery(E2AP_PDU_t *e2apMsg)
2158 {
2159    uint8_t arrIdx = 0, ranFuncIdx=0;
2160    RANfunctionsID_List_t *ranFuncAcceptedList=NULL;
2161    RICserviceQuery_t *ricServiceQuery=NULL;
2162    
2163    if(e2apMsg)
2164    {
2165       if(e2apMsg->choice.initiatingMessage)
2166       {
2167          ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
2168          if(ricServiceQuery->protocolIEs.list.array)
2169          {
2170             for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
2171             {
2172                if(ricServiceQuery->protocolIEs.list.array[arrIdx])
2173                {
2174                   switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
2175                   {
2176                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
2177                         {
2178                            ranFuncAcceptedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
2179                            if(ranFuncAcceptedList->list.array)
2180                            {
2181                               for(ranFuncIdx=0;ranFuncIdx<ranFuncAcceptedList->list.count; ranFuncIdx++)
2182                               {
2183                                  RIC_FREE(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
2184                               }
2185                               RIC_FREE(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
2186                            }
2187                            break;
2188                         }
2189                      case RICserviceQuery_IEs__value_PR_TransactionID:
2190                         {
2191                            break;
2192                         }
2193                   }
2194                   RIC_FREE(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t)); 
2195                }
2196             }
2197             RIC_FREE(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
2198          }
2199          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2200       }
2201       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2202    }
2203 }
2204
2205 /*******************************************************************
2206  *
2207  * @brief build and send the ric service Query 
2208  *
2209  * @details
2210  *
2211  *    Function : BuildAndSendRicServiceQuery
2212  *
2213  * Functionality: build and send the ric service Query 
2214  * @return ROK     - success
2215  *         RFAILED - Acknowledge
2216  *
2217  ******************************************************************/
2218
2219 uint8_t BuildAndSendRicServiceQuery(DuDb *duDb)
2220 {
2221    uint8_t arrIdx;
2222    uint8_t elementCnt;
2223    uint8_t ret = RFAILED;
2224    bool  memAllocFailed = false;
2225    E2AP_PDU_t     *e2apMsg = NULL;
2226    asn_enc_rval_t encRetVal;
2227    RICserviceQuery_t *ricServiceQuery;
2228
2229    DU_LOG("\nINFO   -->  E2AP : Building Ric service Query\n");
2230    while(true)
2231    {
2232       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2233       if(e2apMsg == NULLP)
2234       {
2235          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2236          break;
2237       }
2238       e2apMsg->present =  E2AP_PDU_PR_initiatingMessage;
2239       RIC_ALLOC(e2apMsg->choice.initiatingMessage , sizeof(struct InitiatingMessageE2));
2240       if(e2apMsg->choice.initiatingMessage == NULLP)
2241       {
2242          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2243          break;
2244       }
2245
2246       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceQuery;
2247       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2248       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceQuery;
2249       ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
2250
2251       elementCnt = 1;
2252       /* Fill Accepted RAN function IE If Ran function information is stored in databse */
2253       if(duDb->numOfRanFunction)
2254          elementCnt++;
2255
2256       ricServiceQuery->protocolIEs.list.count = elementCnt;
2257       ricServiceQuery->protocolIEs.list.size  = elementCnt * sizeof(RICserviceQuery_IEs_t*);
2258
2259       RIC_ALLOC(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
2260       if(ricServiceQuery->protocolIEs.list.array == NULLP)
2261       {
2262          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2263          break;
2264       }
2265
2266       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2267       {
2268          RIC_ALLOC(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t));
2269          if(ricServiceQuery->protocolIEs.list.array[arrIdx] == NULLP)
2270          {
2271             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2272             memAllocFailed = true;
2273             break;
2274          }
2275       }
2276       if(memAllocFailed == true)
2277       {
2278          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2279          break;
2280       }
2281
2282       /* Trans Id */
2283       arrIdx = 0;
2284       ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2285       ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2286       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_TransactionID;
2287       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = assignTransactionId(duDb);
2288       
2289       if(duDb->numOfRanFunction)
2290       {
2291          /* Accepted RAN function Id */
2292          arrIdx++;
2293          ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
2294          ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2295          ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_RANfunctionsID_List;
2296          if(BuildRanFunctionAcceptedList(duDb, 0, NULL, &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceQuery)!=ROK)
2297          {
2298             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
2299             break;         
2300          }
2301       }
2302       
2303       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2304       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2305       encBufSize = 0;
2306       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2307
2308       /* Check encode results */
2309       if(encRetVal.encoded == ENCODE_FAIL)
2310       {
2311          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service Query structure (at %s)\n",\
2312                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2313          break;
2314       }
2315       else
2316       {
2317          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service Query\n");
2318          for(int i=0; i< encBufSize; i++)
2319          {
2320             DU_LOG("%x",encBuf[i]);
2321          }
2322       }
2323
2324       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
2325       {
2326          DU_LOG("\nERROR  -->  E2AP : Sending of RIC service  Query failed");
2327          break;
2328       }
2329
2330       ret =ROK;
2331       break;
2332    }
2333    FreeRicServiceQuery(e2apMsg);
2334    return ret;
2335 }
2336
2337 /*******************************************************************
2338  *
2339  * @brief deallocate the memory allocated in RicServiceUpdateFailure
2340  *
2341  * @details
2342  *
2343  *    Function : FreeRicServiceUpdateFailure 
2344  *
2345  *    Functionality: deallocate the memory allocated in RicServiceUpdatefailure
2346  *
2347  * @params[in] E2AP_PDU_t *e2apMsg
2348  *
2349  * @return void
2350  * ****************************************************************/
2351
2352 void FreeRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
2353 {
2354    uint8_t arrIdx = 0;
2355    RICserviceUpdateFailure_t *ricServiceUpdateFailure=NULL;
2356    
2357    if(e2apMsg)
2358    {
2359       if(e2apMsg->choice.unsuccessfulOutcome)
2360       {
2361          ricServiceUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
2362          if(ricServiceUpdateFailure->protocolIEs.list.array)
2363          {
2364             for(arrIdx=0; arrIdx<ricServiceUpdateFailure->protocolIEs.list.count; arrIdx++)
2365             {
2366                RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t)); 
2367             }
2368             RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array, ricServiceUpdateFailure->protocolIEs.list.size);
2369          }
2370          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
2371       }
2372       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2373    }
2374 }
2375
2376 /*******************************************************************
2377  *
2378  * @brief fill E2 failure cause 
2379  *
2380  * @details
2381  *
2382  *    Function : fillE2FailureCause
2383  *
2384  * Functionality: fill E2 failure cause
2385  * @return ROK     - success
2386  *         RFAILED - failure
2387  *
2388  ******************************************************************/
2389
2390 void fillE2FailureCause(CauseE2_t *cause, CauseE2_PR causePresent, uint8_t reason)
2391 {
2392    cause->present = causePresent;
2393
2394    switch(cause->present)
2395    {
2396       case CauseE2_PR_ricRequest:
2397          cause->choice.ricRequest = reason;
2398          break;
2399       case CauseE2_PR_ricService:
2400          cause->choice.ricService = reason;
2401          break;
2402       case CauseE2_PR_e2Node:
2403          cause->choice.e2Node = reason;
2404          break;
2405       case CauseE2_PR_transport:
2406          cause->choice.transport = reason;
2407          break;
2408       case CauseE2_PR_protocol:
2409          cause->choice.protocol = reason;
2410          break;
2411       case CauseE2_PR_misc:
2412          cause->choice.misc = reason;
2413          break;
2414       default:
2415          cause->choice.misc = CauseE2Misc_unspecified;
2416          break;
2417    }
2418 }
2419
2420 /*******************************************************************
2421  *
2422  * @brief build and send the ric service update failure 
2423  *
2424  * @details
2425  *
2426  *    Function : BuildAndSendRicServiceUpdateFailure
2427  *
2428  * Functionality: build and send the ric service update failure 
2429  * @return ROK     - success
2430  *         RFAILED - failure
2431  *
2432  ******************************************************************/
2433
2434 uint8_t BuildAndSendRicServiceUpdateFailure(uint32_t duId, int8_t transId, CauseE2_PR causePresent, uint8_t reason)
2435 {
2436
2437    E2AP_PDU_t         *e2apMsg = NULL;
2438    asn_enc_rval_t     encRetVal;
2439    uint8_t            ret = RFAILED;
2440    uint8_t            arrIdx=0;
2441    uint8_t            elementCnt=0;
2442    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
2443
2444    DU_LOG("\nINFO   -->  E2AP : Building Ric service update failure\n");
2445    while(true)
2446    {
2447       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2448       if(e2apMsg == NULLP)
2449       {
2450          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2451          break;
2452       }
2453       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
2454       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
2455       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
2456       {
2457          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2458          break;
2459       }
2460
2461       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
2462       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
2463       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure;
2464       ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
2465
2466       elementCnt = 3;
2467       ricServiceFailure->protocolIEs.list.count = elementCnt;
2468       ricServiceFailure->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateFailure_IEs_t *);
2469
2470       RIC_ALLOC(ricServiceFailure->protocolIEs.list.array, ricServiceFailure->protocolIEs.list.size);
2471       if(ricServiceFailure->protocolIEs.list.array == NULLP)
2472       {
2473          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2474          break;
2475       }
2476
2477       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2478       {
2479          RIC_ALLOC(ricServiceFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t));
2480          if(ricServiceFailure->protocolIEs.list.array[arrIdx] == NULLP)
2481          {
2482             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2483             break;
2484          }
2485       }
2486       if(arrIdx<elementCnt)
2487       {
2488          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2489          break;
2490       }
2491
2492       /* Trans Id */
2493       arrIdx = 0;
2494       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2495       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2496       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TransactionID;
2497       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
2498
2499       arrIdx++;
2500       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
2501       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2502       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_CauseE2;
2503       fillE2FailureCause(&ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, causePresent, reason);
2504
2505       arrIdx++;
2506       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
2507       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
2508       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TimeToWaitE2;
2509       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
2510
2511       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2512       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2513       encBufSize = 0;
2514       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2515
2516       /* Check encode results */
2517       if(encRetVal.encoded == ENCODE_FAIL)
2518       {
2519          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update failure structure (at %s)\n",\
2520                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2521          break;
2522       }
2523       else
2524       {
2525          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Failure\n");
2526          for(int i=0; i< encBufSize; i++)
2527          {
2528             DU_LOG("%x",encBuf[i]);
2529          }
2530       }
2531
2532       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
2533       {
2534          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update failed");
2535          break;
2536       }
2537       ret = ROK;
2538       break;
2539    }
2540
2541    FreeRicServiceUpdateFailure(e2apMsg);
2542    return ret;
2543 }
2544
2545
2546 /*******************************************************************
2547  *
2548  * @brief deallocate the memory allocated in RicServiceUpdateAck(
2549  *
2550  * @details
2551  *
2552  *    Function : FreeRicServiceUpdateAck 
2553  *
2554  *    Functionality: deallocate the memory allocated in RicServiceUpdateAck
2555  *
2556  * @params[in] E2AP_PDU_t *e2apMsg
2557  *
2558  * @return void
2559  * ****************************************************************/
2560
2561 void FreeRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
2562 {
2563    uint8_t arrIdx = 0, ranFuncIdx=0;
2564    RANfunctionsID_List_t *acceptedList=NULL;
2565    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
2566    RANfunctionsIDcause_List_t  *rejectedList=NULL;
2567
2568    if(e2apMsg)
2569    {
2570       if(e2apMsg->choice.successfulOutcome)
2571       {
2572          ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
2573          if(ricServiceUpdateAck->protocolIEs.list.array)
2574          {
2575             for(arrIdx=0; arrIdx<ricServiceUpdateAck->protocolIEs.list.count; arrIdx++)
2576             {
2577                if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx])
2578                {
2579                   switch(ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id)
2580                   {
2581                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
2582                         {
2583                            acceptedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
2584                            if(acceptedList->list.array)
2585                            {
2586                               for(ranFuncIdx=0;ranFuncIdx<acceptedList->list.count; ranFuncIdx++)
2587                               {
2588                                  RIC_FREE(acceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
2589                               }
2590                               RIC_FREE(acceptedList->list.array, acceptedList->list.size);
2591                            }
2592                            break;
2593                         }
2594
2595                      case ProtocolIE_IDE2_id_RANfunctionsRejected:
2596                         {
2597                            rejectedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
2598                            if(rejectedList->list.array)
2599                            {
2600                               for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
2601                               {
2602                                  RIC_FREE(rejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
2603                               }
2604                               RIC_FREE(rejectedList->list.array, rejectedList->list.size);
2605                            }
2606                            break;
2607                         }
2608                   }
2609                   RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t)); 
2610                }
2611             }
2612             RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
2613          }
2614          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2615       }
2616       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2617    }
2618 }
2619
2620 /*******************************************************************
2621  *
2622  * @brief Build RAN function rejected list
2623  *
2624  * @details
2625  *
2626  *    Function : BuildRanFunctionRejectedList
2627  *
2628  *    Functionality: Build RAN function rejected list 
2629  *
2630  * @params[in] 
2631  *    Count of ran functions to be rejected in the list 
2632  *    Received list of RAN functions
2633  *
2634  * @return ROK - success
2635  *         RFAILED - failure
2636  * ****************************************************************/
2637
2638 uint8_t BuildRanFunctionRejectedList(uint8_t count, RanFunction *ranFunRejectedList, RANfunctionsIDcause_List_t *ranFuncRejectedList)
2639 {
2640    uint8_t ranFuncIdx = 0;
2641    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
2642    
2643    ranFuncRejectedList->list.count = count;
2644    
2645    ranFuncRejectedList->list.size = ranFuncRejectedList->list.count*sizeof(RANfunctionIDcause_ItemIEs_t*);
2646    RIC_ALLOC(ranFuncRejectedList->list.array, ranFuncRejectedList->list.size);
2647    if(ranFuncRejectedList->list.array == NULLP)
2648    {
2649       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array");
2650       return RFAILED;
2651    }
2652    
2653    for(ranFuncIdx = 0; ranFuncIdx< ranFuncRejectedList->list.count; ranFuncIdx++)
2654    {
2655       RIC_ALLOC(ranFuncRejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
2656       if(ranFuncRejectedList->list.array[ranFuncIdx] == NULLP)
2657       {
2658          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array item");
2659          return RFAILED;
2660       }
2661       ranFuncRejectedItemIe = (RANfunctionIDcause_ItemIEs_t*)ranFuncRejectedList->list.array[ranFuncIdx];
2662       ranFuncRejectedItemIe->id = ProtocolIE_IDE2_id_RANfunctionIEcause_Item;
2663       ranFuncRejectedItemIe->criticality= CriticalityE2_ignore;
2664       ranFuncRejectedItemIe->value.present = RANfunctionIDcause_ItemIEs__value_PR_RANfunctionIDcause_Item;
2665       ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID = ranFunRejectedList[ranFuncIdx].id;
2666       fillE2FailureCause(&ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.cause, CauseE2_PR_ricService,\
2667             CauseE2RICservice_ran_function_not_supported);
2668    }
2669    
2670    return ROK;
2671 }
2672
2673 /*******************************************************************
2674  *
2675  * @brief build and send the ric service update Acknowledge 
2676  *
2677  * @details
2678  *
2679  *    Function : BuildAndSendRicServiceUpdateAcknowledge
2680  *
2681  * Functionality: build and send the ric service update Acknowledge 
2682  * @return ROK     - success
2683  *         RFAILED - Acknowledge
2684  *
2685  ******************************************************************/
2686
2687 uint8_t BuildAndSendRicServiceUpdateAcknowledge(DuDb *duDb, int8_t transId, RicTmpRanFunList ricRanFuncList)
2688 {
2689    E2AP_PDU_t         *e2apMsg = NULL;
2690    asn_enc_rval_t     encRetVal;
2691    uint8_t  arrIdx=0, elementCnt=0, ret=RFAILED;;
2692    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
2693
2694    DU_LOG("\nINFO   -->  E2AP : Building Ric service update Acknowledge\n");
2695    while(true)
2696    {
2697       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2698       if(e2apMsg == NULLP)
2699       {
2700          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2701          break;
2702       }
2703       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
2704       RIC_ALLOC(e2apMsg->choice.successfulOutcome , sizeof(struct SuccessfulOutcomeE2));
2705       if(e2apMsg->choice.successfulOutcome == NULLP)
2706       {
2707          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2708          break;
2709       }
2710
2711       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
2712       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
2713       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge;
2714       ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
2715
2716       elementCnt = 1;
2717       if(ricRanFuncList.numOfRanFunAccepted)
2718          elementCnt++;
2719       if(ricRanFuncList.numOfRanFuneRejected)
2720          elementCnt++;
2721       
2722
2723       ricServiceUpdateAck->protocolIEs.list.count = elementCnt;
2724       ricServiceUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateAcknowledge_IEs_t*);
2725
2726       RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
2727       if(ricServiceUpdateAck->protocolIEs.list.array == NULLP)
2728       {
2729          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2730          break;
2731       }
2732
2733       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2734       {
2735          RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t));
2736          if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
2737          {
2738             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2739             break;
2740          }
2741       }
2742       if(arrIdx<elementCnt)
2743       {
2744          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2745          break;
2746       }
2747
2748       /* Trans Id */
2749       arrIdx = 0;
2750       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2751       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2752       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_TransactionID;
2753       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
2754
2755       if(ricRanFuncList.numOfRanFunAccepted)
2756       {
2757          /* Accepted RAN function List */
2758          arrIdx++;
2759          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
2760          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2761          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsID_List;
2762          if(BuildRanFunctionAcceptedList(duDb, ricRanFuncList.numOfRanFunAccepted, ricRanFuncList.ranFunAcceptedList,\
2763          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceUpdate)!=ROK)       
2764          {
2765             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
2766             break;         
2767          }
2768       }
2769       
2770       if(ricRanFuncList.numOfRanFuneRejected)
2771       {
2772          /* RAN Functions Rejected List */
2773          arrIdx++;
2774          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsRejected;
2775          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2776          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsIDcause_List;
2777          if(BuildRanFunctionRejectedList(ricRanFuncList.numOfRanFuneRejected, ricRanFuncList.ranFunRejectedList, \
2778          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List)!=ROK)       
2779          {
2780             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function rejected list");
2781             break;         
2782          }
2783       }
2784       
2785       
2786       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2787       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2788       encBufSize = 0;
2789       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2790
2791       /* Check encode results */
2792       if(encRetVal.encoded == ENCODE_FAIL)
2793       {
2794          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update Acknowledge structure (at %s)\n",\
2795                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2796          break;
2797       }
2798       else
2799       {
2800          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Acknowledge\n");
2801          for(int i=0; i< encBufSize; i++)
2802          {
2803             DU_LOG("%x",encBuf[i]);
2804          }
2805       }
2806
2807       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
2808       {
2809          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update ack failed");
2810          break;
2811       }
2812       ret =ROK;
2813       break;
2814    }
2815    FreeRicServiceUpdateAck(e2apMsg);
2816    return ret; 
2817 }
2818
2819 /*******************************************************************
2820  *
2821  * @brief process the RIC service update 
2822  *
2823  * @details
2824  *
2825  *    Function : ProcRicserviceUpdate 
2826  *
2827  * Functionality: process the RIC service update 
2828  *
2829  * @return ROK     - success
2830  *         RFAILED - failure
2831  *
2832  ******************************************************************/
2833
2834 void ProcRicServiceUpdate(uint32_t duId, RICserviceUpdate_t *ricServiceUpdate)
2835 {
2836    RicTmpRanFunList ricRanFuncList;
2837    DuDb    *duDb = NULLP;
2838    int8_t transId =-1;
2839    uint8_t duIdx = 0, elementCnt =0, arrIdx = 0; 
2840    uint16_t ranFuncIdx = 0, failedRanFuncCount=0, recvdRanFuncCount=0;
2841    RanFunction *ranFuncDb = NULLP;
2842    RANfunction_ItemIEs_t *ranFuncItemIe =NULL;
2843    RANfunction_Item_t  *ranFuncItem =NULL;
2844    RANfunctionID_Item_t  *ranFuncIdItem=NULL;
2845    RANfunctions_List_t *ranFuncList=NULL;
2846    RANfunctionsID_List_t *deleteList=NULL;
2847    RANfunctionID_ItemIEs_t *delRanFuncItem=NULL;
2848
2849    SEARCH_DU_DB(duIdx, duId, duDb); 
2850    if(duDb == NULLP)
2851    {
2852       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
2853       return;
2854    }
2855    memset(&ricRanFuncList, 0, sizeof(RicTmpRanFunList)); 
2856
2857    if(!ricServiceUpdate)
2858    {
2859       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate pointer is null"); 
2860       return;
2861    }
2862
2863    if(!ricServiceUpdate->protocolIEs.list.array)      
2864    {
2865       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array pointer is null");
2866       return;
2867    }
2868    elementCnt = ricServiceUpdate->protocolIEs.list.count;
2869    for(arrIdx=0; arrIdx<ricServiceUpdate->protocolIEs.list.count; arrIdx++)
2870    {
2871       if(!ricServiceUpdate->protocolIEs.list.array[arrIdx])
2872       {
2873          DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array idx %d pointer is null",arrIdx);
2874          return;
2875       }
2876
2877       switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
2878       {
2879          case ProtocolIE_IDE2_id_TransactionID:
2880             {
2881                transId = ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
2882
2883                if(transId < 0 || transId > 255)
2884                {
2885                   DU_LOG("\nERROR  -->  E2AP : Received invalid transId %d",transId);
2886                   return;
2887                }
2888                break;
2889             }
2890
2891          case ProtocolIE_IDE2_id_RANfunctionsAdded:
2892             {
2893                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
2894
2895                if(ranFuncList->list.array)
2896                {
2897                   for(ranFuncIdx=0;ranFuncIdx<ranFuncList->list.count; ranFuncIdx++)
2898                   {
2899                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx]; 
2900                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
2901
2902                      /* Adding the ran function in temporary list */
2903                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
2904                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
2905                      ricRanFuncList.numOfRanFunAccepted++;
2906
2907                      /* Adding the new ran function in DB*/
2908                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].id = ranFuncItem->ranFunctionID;
2909                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
2910                      duDb->numOfRanFunction++;
2911
2912                      /* Calculating total number of ran fuctions which are received for addition */
2913                      recvdRanFuncCount++;
2914                   }
2915                }
2916                break;
2917             }
2918
2919          case ProtocolIE_IDE2_id_RANfunctionsModified:
2920             {
2921
2922                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List; 
2923                if(ranFuncList->list.array)
2924                {
2925                   for(ranFuncIdx = 0; ranFuncIdx< ranFuncList->list.count; ranFuncIdx++)
2926                   {
2927                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx];
2928                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
2929                      if(fetchRanFuncFromRanFuncId(duDb, ranFuncItem->ranFunctionID) == NULLP)
2930                      {
2931                         /* Calculating total number of ran fuctions which are not present */
2932                         failedRanFuncCount++;
2933
2934                         /* Adding the ran function in temporary list */
2935                         ricRanFuncList.ranFunRejectedList[ricRanFuncList.numOfRanFuneRejected].id =  ranFuncItem->ranFunctionID; 
2936                         ricRanFuncList.numOfRanFuneRejected++;
2937                      }
2938                      else
2939                      {
2940
2941                         /* Adding the ran function in temporary list */
2942                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
2943                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
2944                         ricRanFuncList.numOfRanFunAccepted++;
2945
2946                         /* Updating the new ran function in DB*/
2947                         duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
2948                      }
2949                      /* Calculating total number of ran fuctions which are received for modification */
2950                      recvdRanFuncCount++;
2951                   }
2952                }
2953                break;
2954             }
2955          case ProtocolIE_IDE2_id_RANfunctionsDeleted:
2956             {
2957
2958                deleteList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List; 
2959                if(deleteList->list.array)
2960                {
2961                   for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
2962                   {
2963                      delRanFuncItem  = (RANfunctionID_ItemIEs_t*) deleteList->list.array[ranFuncIdx];
2964                      ranFuncIdItem = &delRanFuncItem->value.choice.RANfunctionID_Item;
2965                      ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncIdItem->ranFunctionID);
2966                      if(ranFuncDb)
2967                      {
2968                         memset(ranFuncDb, 0, sizeof(RanFunction));
2969                         duDb->numOfRanFunction--; 
2970                      }
2971
2972                      /* Calculating total number of ran fuctions which are received for deletion */
2973                      recvdRanFuncCount++;
2974                   }
2975                }
2976                break;
2977             }
2978
2979          default:
2980             {
2981                DU_LOG("\nERROR  -->  E2AP : IE [%ld] is not supported",ricServiceUpdate->protocolIEs.list.array[arrIdx]->id);
2982                break;
2983             }
2984       }
2985    }
2986    
2987    /* Sending RIC Service Update Failed if all RAN Functions received fail or if any IE processing fails
2988     * Else sending RIC Service Update Acknowledge */  
2989    if((elementCnt > arrIdx) ||((recvdRanFuncCount > 0) && (recvdRanFuncCount == failedRanFuncCount)))
2990    {
2991       if(BuildAndSendRicServiceUpdateFailure(duDb->duId, transId, CauseE2_PR_misc, CauseE2Misc_unspecified) != ROK)
2992       {
2993          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update Failure");
2994          return;
2995       }
2996    }
2997    else
2998    {
2999       if(BuildAndSendRicServiceUpdateAcknowledge(duDb, transId, ricRanFuncList) != ROK)
3000       {
3001          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update acknowledge");
3002          return;
3003       }
3004    }
3005 }
3006
3007 /*******************************************************************
3008  *
3009  * @brief Processing RIC subscription failure from DU
3010  *
3011  * @details
3012  *
3013  *    Function : ProcRicSubscriptionFailure
3014  *
3015  * Functionality: Processing RIC subscription failure from DU
3016  *
3017  * @param  ID of DU from which message was sent
3018  *         RIC Subscription failure message
3019  * @return ROK     - success
3020  *         RFAILED - failure
3021  *
3022  ******************************************************************/
3023 uint8_t ProcRicSubscriptionFailure(uint32_t duId, RICsubscriptionFailure_t *ricSubscriptionFailure)
3024 {
3025    uint8_t ieIdx = 0, duIdx = 0;
3026    uint8_t ranFuncId = 0;
3027    DuDb    *duDb = NULLP;
3028    RanFunction *ranFuncDb = NULLP;
3029    RicSubscription *ricSubs = NULLP;
3030    CmLList *ricSubsNode = NULLP;
3031    RicRequestId ricReqId;
3032    RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
3033
3034    DU_LOG("\nINFO  -->  E2AP : Received RIC subscription failure");
3035
3036    SEARCH_DU_DB(duIdx, duId, duDb);
3037    if(duDb == NULLP)
3038    {
3039       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
3040       return RFAILED;
3041    }
3042
3043    memset(&ricReqId, 0, sizeof(RicRequestId));
3044    if(ricSubscriptionFailure)
3045    {
3046       if(ricSubscriptionFailure->protocolIEs.list.array)
3047       {
3048          for(ieIdx=0; ieIdx<ricSubscriptionFailure->protocolIEs.list.count; ieIdx++)
3049          {
3050             if(ricSubscriptionFailure->protocolIEs.list.array[ieIdx])
3051             {
3052                ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[ieIdx];
3053                switch(ricSubscriptionFailure->protocolIEs.list.array[ieIdx]->id)
3054                {
3055                   case ProtocolIE_IDE2_id_RICrequestID:
3056                   {
3057                      ricReqId.requestorId = ricSubsFailIe->value.choice.RICrequestID.ricRequestorID;
3058                      ricReqId.instanceId = ricSubsFailIe->value.choice.RICrequestID.ricInstanceID;
3059                      break;
3060                   }
3061                   case ProtocolIE_IDE2_id_RANfunctionID:
3062                   {
3063                      ranFuncId = ricSubsFailIe->value.choice.RANfunctionID;
3064                      ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
3065                      if(!ranFuncDb)
3066                      {
3067                         DU_LOG("\nERROR  -->  E2AP : ProcRicSubscriptionFailure : RAN Function Id [%d] not found", ranFuncId);
3068                         return RFAILED;
3069                      }
3070                      else
3071                      {
3072                         /* Remove subscription entry from RAN Function */
3073                         ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
3074                         if(ricSubs)
3075                         {
3076                            cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubsNode);
3077                            deleteRicSubscriptionNode(ricSubsNode);
3078                         }
3079                      }
3080                      break; 
3081                   }
3082                   case ProtocolIE_IDE2_id_CauseE2:
3083                   default:
3084                      /* No handling required as of now since this is a stub */
3085                      break;
3086                }
3087             }
3088          }
3089       }
3090    }
3091    return ROK;
3092 }
3093
3094 /*******************************************************************
3095  *
3096  * @brief Free RIC Subscription Modification Refuse
3097  *
3098  * @details
3099  *
3100  *    Function : FreeRicSubsModRefuse
3101  *
3102  * Functionality: Free RIC Subscription Modification Refuse
3103  *
3104  * @param  E2AP Message PDU to be freed
3105  * @return void
3106  *
3107  ******************************************************************/
3108 void FreeRicSubsModRefuse(E2AP_PDU_t *e2apMsg)
3109 {
3110    uint8_t ieIdx =0;
3111    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
3112
3113    if(e2apMsg)
3114    {
3115       if(e2apMsg->choice.unsuccessfulOutcome)
3116       {
3117          ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
3118          if(ricSubsModRefuse->protocolIEs.list.array)
3119          {
3120             for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++)
3121             {
3122                RIC_FREE(ricSubsModRefuse->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRefuse_IEs_t));
3123             }
3124             RIC_FREE(ricSubsModRefuse->protocolIEs.list.array, ricSubsModRefuse->protocolIEs.list.size);
3125          }
3126          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome , sizeof(UnsuccessfulOutcomeE2_t));
3127       }
3128       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3129    }
3130 }
3131
3132 /*******************************************************************
3133  *
3134  * @brief Build And Send RIC Subscription Modification Refuse
3135  *
3136  * @details
3137  *
3138  *    Function : BuildAndSendRicSubsModRefuse
3139  *
3140  * Functionality: Build And Send RIC Subscription Modification Refuse
3141  *
3142  * @param DU ID
3143  *        RIC Request ID of subscription
3144  *        RAN Function ID
3145  *        Type of failure
3146  *        Cause of failure
3147  * @return ROK - success
3148  *         RFAILED - failure
3149  *
3150  ******************************************************************/
3151 uint8_t BuildAndSendRicSubsModRefuse(uint32_t duId, RicRequestId ricReqId, uint16_t ranFuncId, CauseE2_PR causeType, \
3152    uint8_t cause)
3153 {
3154    uint8_t ieIdx = 0, elementCnt = 0;
3155    uint8_t ret = RFAILED;
3156    E2AP_PDU_t *e2apMsg = NULL;
3157    asn_enc_rval_t encRetVal;
3158    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
3159    RICsubscriptionModificationRefuse_IEs_t *ricSubsModRefuseIe = NULLP;
3160
3161    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Refuse\n");
3162    while(true)
3163    {
3164       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3165       if(e2apMsg == NULLP)
3166       {
3167          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3168          break;
3169       }
3170       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
3171       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(UnsuccessfulOutcomeE2_t));
3172       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
3173       {
3174          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3175          break;
3176       }
3177
3178       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired;
3179       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
3180       e2apMsg->choice.unsuccessfulOutcome->value.present = \
3181          UnsuccessfulOutcomeE2__value_PR_RICsubscriptionModificationRefuse;
3182       ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
3183
3184       elementCnt = 3;
3185       ricSubsModRefuse->protocolIEs.list.count = elementCnt;
3186       ricSubsModRefuse->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationRefuse_IEs_t *);
3187       RIC_ALLOC(ricSubsModRefuse->protocolIEs.list.array, ricSubsModRefuse->protocolIEs.list.size);
3188       if(!ricSubsModRefuse->protocolIEs.list.array)
3189       {
3190          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3191          break;
3192       }
3193
3194       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
3195       {
3196          RIC_ALLOC(ricSubsModRefuse->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRefuse_IEs_t));
3197          if(!ricSubsModRefuse->protocolIEs.list.array[ieIdx])
3198          {
3199             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3200             break;
3201          }
3202       }
3203       
3204       /* RIC Request ID */
3205       ieIdx = 0;
3206       ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
3207       ricSubsModRefuseIe->id = ProtocolIE_IDE2_id_RICrequestID;
3208       ricSubsModRefuseIe->criticality = CriticalityE2_reject;
3209       ricSubsModRefuseIe->value.present = RICsubscriptionModificationRefuse_IEs__value_PR_RICrequestID;
3210       ricSubsModRefuseIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
3211       ricSubsModRefuseIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
3212
3213       /* RAN Function ID */
3214       ieIdx++;
3215       ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
3216       ricSubsModRefuseIe->id = ProtocolIE_IDE2_id_RANfunctionID;
3217       ricSubsModRefuseIe->criticality = CriticalityE2_reject;
3218       ricSubsModRefuseIe->value.present = RICsubscriptionModificationRefuse_IEs__value_PR_RANfunctionID;
3219       ricSubsModRefuseIe->value.choice.RANfunctionID = ranFuncId;
3220
3221       /* Cause */
3222       ieIdx++;
3223       ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
3224       ricSubsModRefuseIe->id = ProtocolIE_IDE2_id_CauseE2;
3225       ricSubsModRefuseIe->criticality = CriticalityE2_reject;
3226       ricSubsModRefuseIe->value.present = RICsubscriptionModificationRefuse_IEs__value_PR_CauseE2;
3227       fillE2FailureCause(&ricSubsModRefuseIe->value.choice.CauseE2, causeType, cause); 
3228
3229       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3230       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3231       encBufSize = 0;
3232       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3233
3234       /* Check encode results */
3235       if(encRetVal.encoded == ENCODE_FAIL)
3236       {
3237          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC subscription modification refuse (at %s)\n",\
3238                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3239          break;
3240       }
3241       else
3242       {
3243          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC subscription modification refuse\n");
3244          for(int i=0; i< encBufSize; i++)
3245          {
3246             DU_LOG("%x",encBuf[i]);
3247          }
3248       }
3249
3250       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
3251       {
3252          DU_LOG("\nERROR  -->  E2AP : Failed to send RIC Subscription Modification Refused");
3253          break;
3254       }
3255
3256       ret =ROK;
3257       break;
3258    }
3259    FreeRicSubsModRefuse(e2apMsg);
3260    return ret;
3261 }
3262
3263 /*******************************************************************
3264  *
3265  * @brief Free memory for RIC Subscription Modification Confirm
3266  *
3267  * @details
3268  *
3269  *    Function : FreeRicSubsModConfirm
3270  *
3271  * Functionality: Free memory for RIC subscription modification
3272  *    confirm
3273  *
3274  * @param E2AP Message PDU to be freed
3275  * @return Void
3276  *
3277  ******************************************************************/
3278 void FreeRicSubsModConfirm(E2AP_PDU_t *e2apMsg)
3279 {
3280    uint8_t ieIdx = 0, arrIdx=0;
3281    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
3282    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
3283    RICactions_ConfirmedForModification_List_t *modCfmList = NULLP;
3284    RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP;
3285    RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP;
3286    RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP;
3287
3288    if(e2apMsg)
3289    {
3290       if(e2apMsg->choice.successfulOutcome)
3291       {
3292          ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
3293          if(ricSubsModCfm->protocolIEs.list.array)
3294          {
3295             for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++)
3296             {
3297                if(ricSubsModCfm->protocolIEs.list.array[ieIdx])
3298                {
3299                   ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
3300                   switch(ricSubsModCfmIe->id)
3301                   {
3302                      case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List:
3303                         {
3304                            modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List;
3305                            if(modCfmList->list.array)
3306                            {
3307                               for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
3308                               {
3309                                  RIC_FREE(modCfmList->list.array[arrIdx], \
3310                                     sizeof(RICaction_ConfirmedForModification_ItemIEs_t));
3311                               }
3312                               RIC_FREE(modCfmList->list.array,  modCfmList->list.size);
3313                            }
3314                            break;
3315                         }
3316
3317                      case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List:
3318                         {
3319                            modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List;
3320                            if(modRefusedList->list.array)
3321                            {
3322                               for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
3323                               {
3324                                  RIC_FREE(modRefusedList->list.array[arrIdx], \
3325                                        sizeof(RICaction_RefusedToBeModified_ItemIEs_t));
3326                               }
3327                               RIC_FREE(modRefusedList->list.array,  modRefusedList->list.size);
3328                            }
3329                            break;
3330                         }
3331
3332                      case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List:
3333                         {
3334                            rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List;
3335                            if(rmvCfmList->list.array)
3336                            {
3337                               for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
3338                               {
3339                                  RIC_FREE(rmvCfmList->list.array[arrIdx], \
3340                                        sizeof(RICaction_ConfirmedForRemoval_ItemIEs_t));
3341                               }
3342                               RIC_FREE(rmvCfmList->list.array,  rmvCfmList->list.size);
3343                            }
3344                            break;
3345                         }
3346
3347                      case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List:
3348                         {
3349                            rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List;
3350                            if(rmvFailList->list.array)
3351                            {
3352                               for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
3353                               {
3354                                  RIC_ALLOC(rmvFailList->list.array[arrIdx], \
3355                                     sizeof(RICaction_RefusedToBeRemoved_ItemIEs_t));
3356                               }
3357                               RIC_FREE(rmvFailList->list.array,  rmvFailList->list.size);
3358                            }
3359                            break;
3360                         }
3361
3362                      default:
3363                         break;
3364
3365                   }
3366                   RIC_FREE(ricSubsModCfmIe, sizeof(RICsubscriptionModificationConfirm_IEs_t));
3367                }
3368             }
3369             RIC_FREE(ricSubsModCfm->protocolIEs.list.array, ricSubsModCfm->protocolIEs.list.size);
3370          }
3371          RIC_FREE(e2apMsg->choice.successfulOutcome , sizeof(SuccessfulOutcomeE2_t));
3372       }
3373       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3374    }
3375 }
3376
3377 /*******************************************************************
3378  *
3379  * @brief Fill the list of actions confirmed for modification
3380  *
3381  * @details
3382  *
3383  *    Function : fillActionModConfirmedList
3384  *
3385  * Functionality: Fill the list of actions confirmed for modification
3386  *
3387  * @param List to be filled
3388  *        Number of actions
3389  *        Source list of actions
3390  * @return ROK - success
3391  *         RFAILED - failure
3392  *
3393  ******************************************************************/
3394 uint8_t fillActionModConfirmedList(RICactions_ConfirmedForModification_List_t *modCfmList, uint8_t numActions, \
3395    uint8_t *actionModifiedList)
3396 {
3397    uint8_t arrIdx = 0;
3398    RICaction_ConfirmedForModification_ItemIEs_t *modCfmListItem = NULLP;
3399
3400    modCfmList->list.count = numActions;
3401    modCfmList->list.size = numActions * sizeof(RICaction_ConfirmedForModification_ItemIEs_t *);
3402    RIC_ALLOC(modCfmList->list.array,  modCfmList->list.size);
3403    if(!modCfmList->list.array)
3404    {
3405       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3406       return RFAILED;
3407    }
3408
3409    for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
3410    {
3411       RIC_ALLOC(modCfmList->list.array[arrIdx], sizeof(RICaction_ConfirmedForModification_ItemIEs_t));
3412       if(!modCfmList->list.array[arrIdx])
3413       {
3414          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3415          return RFAILED;
3416       }
3417
3418       modCfmListItem = (RICaction_ConfirmedForModification_ItemIEs_t *)modCfmList->list.array[arrIdx];
3419       modCfmListItem->id = ProtocolIE_IDE2_id_RICaction_ConfirmedForModification_Item;
3420       modCfmListItem->criticality = CriticalityE2_ignore;
3421       modCfmListItem->value.present = \
3422          RICaction_ConfirmedForModification_ItemIEs__value_PR_RICaction_ConfirmedForModification_Item;
3423       modCfmListItem->value.choice.RICaction_ConfirmedForModification_Item.ricActionID = actionModifiedList[arrIdx];
3424    }
3425
3426    return ROK;
3427 }
3428
3429 /*******************************************************************
3430  *
3431  * @brief Fill the list of actions refused to be modified
3432  *
3433  * @details
3434  *
3435  *    Function : fillActionModRefusedList
3436  *
3437  * Functionality: Fill the list of actions refused to be modified
3438  *
3439  * @param List to be filled
3440  *        Number of list
3441  *        Source list of actions refused tobe modified
3442  * @return ROK - success
3443  *         RFAILED - failure
3444  *
3445  ******************************************************************/
3446 uint8_t fillActionModRefusedList(RICactions_RefusedToBeModified_List_t *modRefusedList, uint8_t numActions, \
3447    ActionFailed *actionModFailedList)
3448 {
3449    uint8_t arrIdx = 0;
3450    RICaction_RefusedToBeModified_ItemIEs_t *modRefusedListItem = NULLP;
3451
3452    modRefusedList->list.count = numActions;
3453    modRefusedList->list.size = numActions * sizeof(RICaction_RefusedToBeModified_ItemIEs_t *);
3454    RIC_ALLOC(modRefusedList->list.array,  modRefusedList->list.size);
3455    if(!modRefusedList->list.array)
3456    {
3457       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3458       return RFAILED;
3459    }
3460
3461    for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
3462    {
3463       RIC_ALLOC(modRefusedList->list.array[arrIdx], sizeof(RICaction_RefusedToBeModified_ItemIEs_t));
3464       if(!modRefusedList->list.array[arrIdx])
3465       {
3466          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3467          return RFAILED;
3468       }
3469
3470       modRefusedListItem = (RICaction_RefusedToBeModified_ItemIEs_t *)modRefusedList->list.array[arrIdx];
3471       modRefusedListItem->id = ProtocolIE_IDE2_id_RICaction_RefusedToBeModified_Item;
3472       modRefusedListItem->criticality = CriticalityE2_ignore;
3473       modRefusedListItem->value.present = \
3474          RICaction_RefusedToBeModified_ItemIEs__value_PR_RICaction_RefusedToBeModified_Item;
3475       modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.ricActionID = \
3476          actionModFailedList[arrIdx].actionId;
3477       fillE2FailureCause(&modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.cause, \
3478          actionModFailedList[arrIdx].failureType, actionModFailedList[arrIdx].cause);
3479    }
3480
3481    return ROK;
3482 }
3483
3484 /*******************************************************************
3485  *
3486  * @brief Fill the list of action confirmed for removal
3487  *
3488  * @details
3489  *
3490  *    Function : fillActionRemovalConfirmedList
3491  *
3492  * Functionality: Fill the list of action confirmed for removal
3493  *
3494  * @param List to be filled
3495  *        Number of actions
3496  *        Source list of actions removed
3497  * @return ROK - success
3498  *         RFAILED - failure
3499  *
3500  ******************************************************************/
3501 uint8_t fillActionRemovalConfirmedList(RICactions_ConfirmedForRemoval_List_t *rmvCfmList, uint8_t numActions, \
3502    uint8_t *actionRemovedList)
3503 {
3504    uint8_t arrIdx = 0;
3505    RICaction_ConfirmedForRemoval_ItemIEs_t *rmvCfmListItem = NULLP;
3506
3507    rmvCfmList->list.count = numActions;
3508    rmvCfmList->list.size = numActions * sizeof(RICaction_ConfirmedForRemoval_ItemIEs_t *);
3509    RIC_ALLOC(rmvCfmList->list.array,  rmvCfmList->list.size);
3510    if(!rmvCfmList->list.array)
3511    {
3512       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3513       return RFAILED;
3514    }
3515
3516    for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
3517    {
3518       RIC_ALLOC(rmvCfmList->list.array[arrIdx], sizeof(RICaction_ConfirmedForRemoval_ItemIEs_t));
3519       if(!rmvCfmList->list.array[arrIdx])
3520       {
3521          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3522          return RFAILED;
3523       }
3524
3525       rmvCfmListItem = (RICaction_ConfirmedForRemoval_ItemIEs_t *)rmvCfmList->list.array[arrIdx];
3526       rmvCfmListItem->id = ProtocolIE_IDE2_id_RICaction_ConfirmedForRemoval_Item;
3527       rmvCfmListItem->criticality = CriticalityE2_ignore;
3528       rmvCfmListItem->value.present = \
3529          RICaction_ConfirmedForRemoval_ItemIEs__value_PR_RICaction_ConfirmedForRemoval_Item;
3530       rmvCfmListItem->value.choice.RICaction_ConfirmedForRemoval_Item.ricActionID = actionRemovedList[arrIdx];
3531    }
3532
3533    return ROK;
3534 }
3535
3536 /*******************************************************************
3537  *
3538  * @brief Fill the list of actions refused to be removed
3539  *
3540  * @details
3541  *
3542  *    Function : fillActionRemovalRefusedList
3543  *
3544  * Functionality: Fill the list of actions refused to be removed
3545  *
3546  * @param List to be filled
3547  *        Number of list
3548  *        Source list of actions refused to be removed
3549  * @return ROK - success
3550  *         RFAILED - failure
3551  *
3552  ******************************************************************/
3553 uint8_t fillActionRemovalRefusedList(RICactions_RefusedToBeRemoved_List_t *rmvFailList, \
3554    uint8_t numActions, ActionFailed *actionRmvlFailList)
3555 {
3556    uint8_t arrIdx = 0;
3557    RICaction_RefusedToBeRemoved_ItemIEs_t *rmvFailListItem = NULLP;
3558
3559    rmvFailList->list.count = numActions;
3560    rmvFailList->list.size = numActions * sizeof(RICaction_RefusedToBeRemoved_ItemIEs_t *);
3561    RIC_ALLOC(rmvFailList->list.array,  rmvFailList->list.size);
3562    if(!rmvFailList->list.array)
3563    {
3564       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3565       return RFAILED;
3566    }
3567
3568    for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
3569    {
3570       RIC_ALLOC(rmvFailList->list.array[arrIdx], sizeof(RICaction_RefusedToBeRemoved_ItemIEs_t));
3571       if(!rmvFailList->list.array[arrIdx])
3572       {
3573          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3574          return RFAILED;
3575       }
3576
3577       rmvFailListItem = (RICaction_RefusedToBeRemoved_ItemIEs_t *)rmvFailList->list.array[arrIdx];
3578       rmvFailListItem->id = ProtocolIE_IDE2_id_RICaction_RefusedToBeRemoved_Item;
3579       rmvFailListItem->criticality = CriticalityE2_ignore;
3580       rmvFailListItem->value.present = \
3581          RICaction_RefusedToBeRemoved_ItemIEs__value_PR_RICaction_RefusedToBeRemoved_Item;
3582       rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.ricActionID = actionRmvlFailList[arrIdx].actionId;
3583       fillE2FailureCause(&rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.cause, \
3584          actionRmvlFailList[arrIdx].failureType, actionRmvlFailList[arrIdx].cause);
3585    }
3586
3587    return ROK;
3588
3589 }
3590
3591 /*******************************************************************
3592  *
3593  * @brief Build And Send RIC Subscription Modification Confirm
3594  *
3595  * @details
3596  *
3597  *    Function : BuildAndSendRicSubsModConfirm
3598  *
3599  * Functionality: Build And Send RIC Subscription Modification Confirm
3600  *
3601  * @param DU ID
3602  *        RIC Request ID of subscription
3603  *        RAN Function ID
3604  *        Temporary source action list
3605  * @return ROK - success
3606  *         RFAILED - failure
3607  *
3608  ******************************************************************/
3609 uint8_t BuildAndSendRicSubsModConfirm(uint32_t duId, RicRequestId ricReqId, uint16_t ranFuncId, RicTmpActionList tmpActionList)
3610 {
3611    uint8_t ieIdx = 0, elementCnt = 0;
3612    uint8_t ret = RFAILED;
3613    E2AP_PDU_t *e2apMsg = NULLP;
3614    asn_enc_rval_t encRetVal;
3615    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
3616    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
3617
3618    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Confirm\n");
3619    while(true)
3620    {
3621       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3622       if(e2apMsg == NULLP)
3623       {
3624          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3625          break;
3626       }
3627
3628       /* Successful Outcome */
3629       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
3630       RIC_ALLOC(e2apMsg->choice.successfulOutcome , sizeof(SuccessfulOutcomeE2_t));
3631       if(e2apMsg->choice.successfulOutcome == NULLP)
3632       {
3633          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3634          break;
3635       }
3636
3637       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired;
3638       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
3639       e2apMsg->choice.successfulOutcome->value.present = \
3640          SuccessfulOutcomeE2__value_PR_RICsubscriptionModificationConfirm;
3641       ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
3642
3643       elementCnt = 2;
3644       if(tmpActionList.numActionModified)
3645          elementCnt++;
3646       if(tmpActionList.numActionModFailed)
3647          elementCnt++;
3648       if(tmpActionList.numActionRemoved)
3649          elementCnt++;
3650       if(tmpActionList.numActionRemovalFailed)
3651          elementCnt++;
3652
3653       ricSubsModCfm->protocolIEs.list.count = elementCnt;
3654       ricSubsModCfm->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationConfirm_IEs_t *);
3655       RIC_ALLOC(ricSubsModCfm->protocolIEs.list.array, ricSubsModCfm->protocolIEs.list.size);
3656       if(!ricSubsModCfm->protocolIEs.list.array)
3657       {
3658          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3659          break;
3660       }
3661
3662       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
3663       {
3664          RIC_ALLOC(ricSubsModCfm->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationConfirm_IEs_t));
3665          if(!ricSubsModCfm->protocolIEs.list.array[ieIdx])
3666          {
3667             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3668             break;
3669          }
3670       }
3671       
3672       /* RIC Request ID */
3673       ieIdx = 0;
3674       ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
3675       ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICrequestID;
3676       ricSubsModCfmIe->criticality = CriticalityE2_reject;
3677       ricSubsModCfmIe->value.present = RICsubscriptionModificationConfirm_IEs__value_PR_RICrequestID;
3678       ricSubsModCfmIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
3679       ricSubsModCfmIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
3680
3681       /* RAN Function ID */
3682       ieIdx++;
3683       ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
3684       ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RANfunctionID;
3685       ricSubsModCfmIe->criticality = CriticalityE2_reject;
3686       ricSubsModCfmIe->value.present = RICsubscriptionModificationConfirm_IEs__value_PR_RANfunctionID;
3687       ricSubsModCfmIe->value.choice.RANfunctionID = ranFuncId;
3688
3689       /* RIC Actions List confirmed for modification */
3690       if(tmpActionList.numActionModified)
3691       {
3692          ieIdx++;
3693          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
3694          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List;
3695          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
3696          ricSubsModCfmIe->value.present = \
3697             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_ConfirmedForModification_List;
3698          if(fillActionModConfirmedList(&ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List, \
3699             tmpActionList.numActionModified, tmpActionList.actionModifiedList) != ROK)
3700          {
3701             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Confirmed for Modification List", __func__);
3702             break;
3703          }
3704       }
3705
3706       /* RIC Actions List refured to be modified */
3707       if(tmpActionList.numActionModFailed)
3708       {
3709          ieIdx++;
3710          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
3711          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List;
3712          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
3713          ricSubsModCfmIe->value.present = \
3714             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_RefusedToBeModified_List;
3715          if(fillActionModRefusedList(&ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List, \
3716             tmpActionList.numActionModFailed, tmpActionList.actionModFailedList) != ROK)
3717          {
3718             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Refused to be Modified List", __func__);
3719             break;
3720          }
3721       }
3722
3723       /* RIC Actions List confirmed for removal */
3724       if(tmpActionList.numActionRemoved)
3725       {
3726          ieIdx++;
3727          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
3728          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List;
3729          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
3730          ricSubsModCfmIe->value.present = \
3731             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_ConfirmedForRemoval_List;
3732          if(fillActionRemovalConfirmedList(&ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List, \
3733             tmpActionList.numActionRemoved, tmpActionList.actionRemovedList) != ROK)
3734          {
3735             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Confirmed for Removal List", __func__);
3736             break;
3737          }
3738       }
3739
3740       /* RIC Actions List Refused to be removed */
3741       if(tmpActionList.numActionRemovalFailed)
3742       {
3743          ieIdx++;
3744          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
3745          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List;
3746          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
3747          ricSubsModCfmIe->value.present = \
3748             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_RefusedToBeRemoved_List;
3749          if(fillActionRemovalRefusedList(&ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List, \
3750             tmpActionList.numActionRemovalFailed, tmpActionList.actionRemovalFailedList) != ROK)
3751          {
3752             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Failed to be Removed List", __func__);
3753             break;
3754          }
3755       }
3756
3757       /* Print and encode E2AP Message PDU */
3758       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3759       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3760       encBufSize = 0;
3761       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3762
3763       /* Check encode results */
3764       if(encRetVal.encoded == ENCODE_FAIL)
3765       {
3766          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC subscription modification confirm (at %s)\n",\
3767                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3768          break;
3769       }
3770       else
3771       {
3772          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC subscription modification confirm\n");
3773          for(int i=0; i< encBufSize; i++)
3774          {
3775             DU_LOG("%x",encBuf[i]);
3776          }
3777       }
3778
3779       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
3780       {
3781          DU_LOG("\nERROR  -->  E2AP : Failed to send RIC Subscription Modification Confirm");
3782          break;
3783       }
3784
3785       ret =ROK;
3786       break;
3787    }
3788
3789    FreeRicSubsModConfirm(e2apMsg);
3790    return ret;
3791 }
3792
3793 /*******************************************************************
3794  *
3795  * @brief Processing of RIC Subscription Modification Required
3796  *
3797  * @details
3798  *
3799  *    Function : ProcRicSubsModReqd
3800  *
3801  * Functionality: Processing of RIC Subscription Modification Required
3802  *    As of now, we do not identify any scenario where this message
3803  *    shall be sent by DU. Hence, bare minimum handling has been
3804  *    done here.
3805  *
3806  * @param  DU ID
3807  *         RIC Subscription Modification Required IEs
3808  * @return ROK-success
3809  *         RFAILED-failure
3810  *
3811  ******************************************************************/
3812 uint8_t ProcRicSubsModReqd(uint32_t duId, RICsubscriptionModificationRequired_t *ricSubsModReqd)
3813 {
3814    uint8_t ieIdx = 0, actionIdx = 0, duIdx = 0;
3815    DuDb    *duDb = NULLP;
3816    uint16_t ranFuncId;
3817    uint16_t actionId;
3818    RicRequestId ricReqId;
3819    RanFunction *ranFuncDb = NULLP;
3820    RicSubscription *ricSubs = NULLP;
3821    CmLList *ricSubsNode = NULLP;
3822    ActionInfo *action = NULLP;
3823    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
3824    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
3825    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
3826    RICaction_RequiredToBeModified_ItemIEs_t *actionToBeMod = NULLP;
3827    RICaction_RequiredToBeRemoved_ItemIEs_t *actionToBeRmv = NULLP;
3828    RicTmpActionList tmpActionList;
3829
3830    memset(&ricReqId, 0, sizeof(RicRequestId));
3831    memset(&tmpActionList, 0, sizeof(RicTmpActionList));
3832
3833    SEARCH_DU_DB(duIdx, duId, duDb);
3834    if(duDb == NULLP)
3835    {
3836       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
3837       return RFAILED;
3838    }
3839
3840    for(ieIdx = 0; ieIdx < ricSubsModReqd->protocolIEs.list.count; ieIdx++)
3841    {
3842       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
3843       switch(ricSubsModReqdIe->id)
3844       {
3845          case ProtocolIE_IDE2_id_RICrequestID:
3846             {
3847                ricReqId.requestorId = ricSubsModReqdIe->value.choice.RICrequestID.ricRequestorID;
3848                ricReqId.instanceId = ricSubsModReqdIe->value.choice.RICrequestID.ricInstanceID;
3849                break;
3850             }
3851          case ProtocolIE_IDE2_id_RANfunctionID:
3852             {
3853                ranFuncId = ricSubsModReqdIe->value.choice.RANfunctionID;
3854                ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
3855                if(!ranFuncDb)
3856                {
3857                   /* If RIC Subscription not found, send RIC Subscription modification refuse to DU */
3858                   DU_LOG("\nERROR  -->  E2AP : ProcRicSubsModReqd: RIC Subscription not found");
3859                   BuildAndSendRicSubsModRefuse(duId, ricReqId, ranFuncId, CauseE2_PR_ricRequest, \
3860                      CauseE2RICrequest_ran_function_id_invalid);
3861                   return RFAILED;
3862                }
3863
3864                ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
3865                if(!ricSubs)
3866                {
3867                   /* If RAN Function not found, send RIC Subscription modification refuse to DU */
3868                   DU_LOG("\nERROR  -->  E2AP : ProcRicSubsModReqd: RAN Function ID [%d] not found",ranFuncId);
3869                   BuildAndSendRicSubsModRefuse(duId, ricReqId, ranFuncId, \
3870                      CauseE2_PR_ricRequest, CauseE2RICrequest_request_id_unknown);
3871                   return RFAILED; 
3872                }
3873                break;
3874             }
3875          case ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List:
3876             {
3877                actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
3878                for(actionIdx = 0; actionIdx < actionToBeModList->list.count; actionIdx++)
3879                {
3880                   actionToBeMod = (RICaction_RequiredToBeModified_ItemIEs_t *)actionToBeModList->list.array[actionIdx];
3881                   actionId = actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricActionID;
3882                   action = fetchActionInfoFromActionId(actionId, ricSubs);
3883                   if(action)
3884                   {
3885                      /* No modification required as of now, hence directly adding to the list */
3886                      tmpActionList.actionModifiedList[tmpActionList.numActionModified++] = actionId;
3887                   }
3888                   else
3889                   {
3890                      tmpActionList.actionModFailedList[tmpActionList.numActionModFailed].actionId = actionId;
3891                      tmpActionList.actionModFailedList[tmpActionList.numActionModFailed].failureType = \
3892                         CauseE2_PR_ricRequest;
3893                      tmpActionList.actionModFailedList[tmpActionList.numActionModFailed].cause = \
3894                         CauseE2RICrequest_action_not_supported;
3895                      tmpActionList.numActionModFailed++;
3896                   }
3897                }
3898                break;
3899             }
3900          case ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List:
3901             {
3902                actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
3903                for(actionIdx = 0; actionIdx < actionToBeRmvList->list.count; actionIdx++)
3904                {
3905                   actionToBeRmv = (RICaction_RequiredToBeRemoved_ItemIEs_t *)actionToBeRmvList->list.array[actionIdx];
3906                   actionId = actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.ricActionID;
3907                   action = fetchActionInfoFromActionId(actionId, ricSubs);
3908                   if(action)
3909                   {
3910                      tmpActionList.actionRemovedList[tmpActionList.numActionRemoved++] = actionId;
3911                      memset(action, 0, sizeof(ActionInfo));
3912                      action->actionId = -1;
3913                      ricSubs->numOfActions--;
3914                   }
3915                }
3916                break;
3917             }
3918          default:
3919             break;
3920       }
3921    }
3922
3923    /* If none of the action modification/removal is supported, 
3924     *   send RIC Subscription Modification Refuse
3925     * Else
3926     *   send RIC Subscription Modification Confirm
3927     */
3928    if(tmpActionList.numActionModified || tmpActionList.numActionRemoved)
3929    {
3930       BuildAndSendRicSubsModConfirm(duId, ricReqId, ranFuncId, tmpActionList);
3931    }
3932    else
3933    {
3934       BuildAndSendRicSubsModRefuse(duId, ricReqId, ranFuncId, CauseE2_PR_ricRequest, \
3935             CauseE2RICrequest_action_not_supported);
3936    }
3937    
3938    return ROK;
3939 }
3940
3941 /*******************************************************************
3942  *
3943  * @brief Free the ErrorIndication Message
3944  *
3945  * @details
3946  *
3947  *    Function : FreeRicIndication
3948  *
3949  * Functionality: Free the ErrorIndication Message
3950  *
3951  * @return void
3952  *
3953  *
3954  ******************************************************************/
3955 void FreeErrorIndication(E2AP_PDU_t  *e2apMsg)
3956 {
3957    uint8_t arrIdx = 0;
3958    ErrorIndicationE2_t *errorIndicationMsg= NULLP;
3959
3960    if(e2apMsg != NULLP)
3961    {
3962       if(e2apMsg->choice.initiatingMessage != NULLP)
3963       {
3964          errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
3965          if(errorIndicationMsg!= NULLP)
3966          {
3967             if(errorIndicationMsg->protocolIEs.list.array != NULLP)
3968             {
3969                for(arrIdx=0; arrIdx<errorIndicationMsg->protocolIEs.list.count; arrIdx++)
3970                {
3971                   RIC_FREE(errorIndicationMsg->protocolIEs.list.array[arrIdx],sizeof(ErrorIndicationE2_t));
3972                }
3973                RIC_FREE(errorIndicationMsg->protocolIEs.list.array,errorIndicationMsg->protocolIEs.list.size);
3974             }
3975          }
3976          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3977       }
3978       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3979    }
3980 }
3981
3982
3983 /*******************************************************************
3984  *
3985  * @brief Builds and Send the ErrorIndication Message
3986  *
3987  * @details
3988  *
3989  *    Function : BuildAndSendErrorIndication
3990  *
3991  * Functionality:Fills the ErrorIndication Message
3992  *
3993  * @params[in] 
3994  *    DU id
3995  *    Trans id
3996  *    Ric req id
3997  *    Ran function id
3998  *    Reason of failure
3999  * @return ROK     - success
4000  *         RFAILED - failure
4001  *
4002  ******************************************************************/
4003
4004 uint8_t BuildAndSendErrorIndication(uint32_t duId, int8_t transId, RicRequestId requestId, uint16_t ranFuncId, uint8_t reason)
4005 {
4006    uint8_t elementCnt =0, arrIdx=0, ret = RFAILED;
4007    E2AP_PDU_t         *e2apMsg = NULLP;
4008    ErrorIndicationE2_t *errorIndicationMsg=NULLP;
4009    asn_enc_rval_t     encRetVal;        /* Encoder return value */
4010
4011    while(true)
4012    {
4013       DU_LOG("\nINFO   -->  E2AP : Building Error Indication Message\n");
4014
4015       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4016       if(e2apMsg == NULLP)
4017       {
4018          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
4019          break;
4020       }
4021
4022       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4023       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4024       if(e2apMsg->choice.initiatingMessage == NULLP)
4025       {
4026          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
4027          break;
4028       }
4029       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_ErrorIndicationE2;
4030       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4031       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ErrorIndicationE2;
4032
4033       errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
4034
4035       /* Element count is 2 for TransactionID/RICrequestID and Cause.
4036        * If the RAN function id is present, the count will be increased.*/
4037       elementCnt = 2;
4038       if(ranFuncId>0)
4039          elementCnt++;
4040
4041       errorIndicationMsg->protocolIEs.list.count = elementCnt;
4042       errorIndicationMsg->protocolIEs.list.size = elementCnt * sizeof(ErrorIndicationE2_IEs_t*);
4043
4044       /* Initialize the E2Setup members */
4045       RIC_ALLOC(errorIndicationMsg->protocolIEs.list.array, errorIndicationMsg->protocolIEs.list.size);
4046       if(errorIndicationMsg->protocolIEs.list.array == NULLP)
4047       {
4048          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements in %s at line %d",__func__, __LINE__);
4049          break;
4050       }
4051       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
4052       {
4053          RIC_ALLOC(errorIndicationMsg->protocolIEs.list.array[arrIdx], sizeof(ErrorIndicationE2_IEs_t));
4054          if(errorIndicationMsg->protocolIEs.list.array[arrIdx] == NULLP)
4055          {
4056             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array Idx %d in %s at line %d",arrIdx,__func__, __LINE__);
4057             break;
4058          }
4059       }
4060       if(arrIdx < elementCnt)
4061          break;
4062
4063       arrIdx = 0;
4064
4065       if(transId >=0 && transId<=255)
4066       {
4067          /* TransactionID */
4068          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4069          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4070          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_TransactionID;
4071          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
4072       }
4073       else
4074       {
4075          /* RICrequestID */
4076          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RICrequestID;
4077          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4078          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RICrequestID;
4079          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricRequestorID = requestId.requestorId;
4080          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricInstanceID = requestId.instanceId;
4081       }
4082       
4083       if(ranFuncId>0)
4084       {
4085          /* RAN Function ID */
4086          arrIdx++;
4087          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionID;
4088          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4089          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RANfunctionID;
4090          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionID = ranFuncId;
4091       }
4092      
4093       /* Cause */
4094       arrIdx++;
4095       errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
4096       errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
4097       errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2;
4098       fillE2FailureCause(&errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, CauseE2_PR_misc, reason);
4099
4100
4101       /* Prints the Msg formed */
4102       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4103       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4104       encBufSize = 0;
4105       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4106             encBuf);
4107       if(encRetVal.encoded == ENCODE_FAIL)
4108       {
4109          DU_LOG("\nERROR  -->  E2AP : Could not encode Error Indication Message (at %s)\n",\
4110                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4111          break;
4112       }
4113       else
4114       {
4115          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for Error Indication Message \n");
4116 #ifdef DEBUG_ASN_PRINT
4117          for(int i=0; i< encBufSize; i++)
4118          {
4119             printf("%x",encBuf[i]);
4120          }
4121 #endif
4122       }
4123
4124       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
4125       {
4126          DU_LOG("\nINFO   -->  E2AP : Sending Error Indication Message");
4127
4128       }
4129       ret = ROK;
4130       break;
4131    }
4132    FreeErrorIndication(e2apMsg);
4133    return ret;
4134 }
4135
4136 /*******************************************************************
4137  *
4138  * @brief Deallocate the memory allocated for ResetRequest msg
4139  *
4140  * @details
4141  *
4142  *    Function : FreeResetRequest
4143  *
4144  *    Functionality:
4145  *       - freeing the memory allocated for ResetRequest
4146  *
4147  * @params[in] E2AP_PDU_t *e2apMsg
4148  * @return ROK     - success
4149  *         RFAILED - failure
4150  *
4151  * ****************************************************************/
4152 void FreeResetRequest(E2AP_PDU_t *e2apMsg)
4153 {
4154    uint8_t ieIdx =0;
4155    ResetRequestE2_t  *resetReq = NULLP;
4156
4157    if(e2apMsg != NULLP)
4158    {
4159       if(e2apMsg->choice.initiatingMessage != NULLP)
4160       {
4161          resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4162          if(resetReq->protocolIEs.list.array)
4163          {
4164             for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
4165             {
4166                RIC_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4167             }
4168             RIC_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4169          }
4170          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4171       }
4172       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4173    }
4174 }
4175
4176 /*******************************************************************
4177  *
4178  * @brief Build and send the reset request msg
4179  *
4180  * @details
4181  *
4182  *    Function : BuildAndSendResetRequest
4183  *
4184  *    Functionality:
4185  *         - Buld and send the reset request msg to E2 node
4186  *
4187  * @params[in]
4188  *    DU database
4189  *    Type of failure 
4190  *    Cause of failure
4191  * @return ROK     - success
4192  *         RFAILED - failure
4193  *
4194  * ****************************************************************/
4195 uint8_t BuildAndSendResetRequest(DuDb *duDb, CauseE2_PR causePresent, uint8_t reason)
4196 {
4197    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
4198    uint8_t ret = RFAILED;
4199    E2AP_PDU_t        *e2apMsg = NULLP;
4200    ResetRequestE2_t  *resetReq = NULLP;
4201    asn_enc_rval_t     encRetVal;       /* Encoder return value */
4202
4203    DU_LOG("\nINFO   -->  E2AP : Building Reset Request\n");
4204
4205    do
4206    {
4207       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4208       if(e2apMsg == NULLP)
4209       {
4210          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation for E2AP-PDU failed");
4211          break;
4212       }
4213
4214       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4215       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4216       if(e2apMsg->choice.initiatingMessage == NULLP)
4217       {
4218          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation for initiatingMessage");
4219          break;
4220       }
4221
4222       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
4223       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4224       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
4225       resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4226
4227       elementCnt = 2;
4228       resetReq->protocolIEs.list.count = elementCnt;
4229       resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
4230
4231       RIC_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4232       if(!resetReq->protocolIEs.list.array)
4233       {
4234          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation failed for \
4235                Reset Request IE array");
4236          break;
4237       }
4238
4239       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
4240       {
4241          RIC_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4242          if(!resetReq->protocolIEs.list.array[ieIdx])
4243          {
4244             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation failed for \
4245                   Reset Request IE array element");
4246             break;
4247          }
4248       }
4249
4250       /* In case of failure */
4251       if(ieIdx < elementCnt)
4252          break;
4253
4254       ieIdx = 0;
4255       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4256       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
4257       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
4258       transId = assignTransactionId(duDb);
4259       resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
4260
4261       ieIdx++;
4262       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
4263       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
4264       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
4265       fillE2FailureCause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, causePresent, reason);
4266
4267       /* Prints the Msg formed */
4268       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4269
4270       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4271       encBufSize = 0;
4272       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4273             encBuf);
4274       if(encRetVal.encoded == ENCODE_FAIL)
4275       {
4276          DU_LOG("\nERROR  -->  E2AP : Could not encode reset request structure (at %s)\n",\
4277                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4278          break;
4279       }
4280       else
4281       {
4282          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for reset request\n");
4283 #ifdef DEBUG_ASN_PRINT
4284          for(int i=0; i< encBufSize; i++)
4285          {
4286             printf("%x",encBuf[i]);
4287          }
4288 #endif
4289       }
4290       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
4291       {
4292          DU_LOG("\nERROR  -->  E2AP : Sending reset request failed");
4293          break;
4294       }
4295
4296
4297       ret = ROK;
4298       break;
4299    }while(true);
4300
4301    /* Free all memory */
4302    FreeResetRequest(e2apMsg);
4303    return ret;
4304 }
4305
4306 /******************************************************************
4307  *
4308  * @brief Delete Ric subscription node
4309  *
4310  * @details
4311  *
4312  *    Function : deleteRicSubscriptionNode
4313  *
4314  *    Functionality: Delete Ric subscription node
4315  *
4316  * @params[in] Ric subscription info
4317  *
4318  * @return void
4319  *
4320  * ****************************************************************/
4321 void deleteRicSubscriptionNode(CmLList *subscriptionNode)
4322 {
4323    uint8_t actionIdx=0;
4324    RicSubscription *ricSubscriptionInfo = NULLP;
4325
4326    ricSubscriptionInfo = (RicSubscription*)subscriptionNode->node;
4327
4328    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
4329    {
4330       if(ricSubscriptionInfo->actionSequence[actionIdx].actionId > -1)
4331       {
4332          memset(&ricSubscriptionInfo->actionSequence[actionIdx], 0, sizeof(ActionInfo));
4333       }
4334    }
4335    memset(ricSubscriptionInfo, 0, sizeof(RicSubscription));
4336    RIC_FREE(subscriptionNode->node, sizeof(RicSubscription));
4337    RIC_FREE(subscriptionNode, sizeof(CmLList));
4338 }
4339
4340 /*******************************************************************
4341  *
4342  * @brief Delete RIC subscription List
4343  *
4344  * @details
4345  *
4346  *    Function : deleteRicSubscriptionList 
4347  *
4348  * Functionality: Delete RIC subscription list
4349  *
4350  * @params[in] RIC Subscription list
4351  * @return void
4352
4353  *
4354  ******************************************************************/
4355 void deleteRicSubscriptionList(CmLListCp *subscriptionList)
4356 {
4357    CmLList *subscriptionNode = NULLP;
4358
4359    CM_LLIST_FIRST_NODE(subscriptionList, subscriptionNode);
4360    while(subscriptionNode)
4361    {
4362       cmLListDelFrm(subscriptionList, subscriptionNode);
4363       deleteRicSubscriptionNode(subscriptionNode);
4364       CM_LLIST_FIRST_NODE(subscriptionList, subscriptionNode);
4365    }
4366 }
4367
4368 /*******************************************************************
4369  *
4370  * @brief process the E2 Reset Response
4371  *
4372  * @details
4373  *
4374  *    Function : ProcResetResponse 
4375  *
4376  * Functionality: Process E2 Reset Response 
4377  *
4378  * @params[in] 
4379  *       du Id
4380  *       Pointer to reset response 
4381  * @return void
4382  *
4383  ******************************************************************/
4384
4385 void ProcResetResponse(uint32_t duId, ResetResponseE2_t *resetRsp)
4386 {
4387    uint8_t ieIdx = 0, duIdx =0;
4388    DuDb *duDb = NULLP;
4389    RanFunction *ranFuncDb = NULLP;
4390    uint16_t ranFuncIdx = 0;
4391
4392    SEARCH_DU_DB(duIdx, duId, duDb); 
4393    if(duDb == NULLP)
4394    {
4395       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
4396       return;
4397    }
4398    
4399    if(!resetRsp)
4400    {
4401       DU_LOG("\nERROR  -->  E2AP : resetRsp pointer is null"); 
4402       return;
4403    }
4404
4405    if(!resetRsp->protocolIEs.list.array)      
4406    {
4407       DU_LOG("\nERROR  -->  E2AP : resetRsp array pointer is null");
4408       return;
4409    }
4410    
4411    for(ieIdx=0; ieIdx < resetRsp->protocolIEs.list.count; ieIdx++)
4412    {
4413       if(resetRsp->protocolIEs.list.array[ieIdx])
4414       {
4415          switch(resetRsp->protocolIEs.list.array[ieIdx]->id)
4416          {
4417             case ProtocolIE_IDE2_id_TransactionID:
4418                {
4419                   for(ranFuncIdx = 0; ranFuncIdx < MAX_RAN_FUNCTION; ranFuncIdx++)
4420                   {
4421                      ranFuncDb = &duDb->ranFunction[ranFuncIdx];
4422                      if(ranFuncDb->id > 0)
4423                      {
4424                         deleteRicSubscriptionList(&ranFuncDb->subscriptionList);
4425                      }
4426                   }
4427                   break;
4428                }
4429             case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
4430                {
4431                   break;
4432                }
4433          }
4434       }
4435    }
4436 }
4437
4438
4439 /*******************************************************************
4440  *
4441  * @brief process the E2 Reset Request
4442  *
4443  * @details
4444  *
4445  *    Function : ProcResetRequest 
4446  *
4447  * Functionality: Process E2 Reset Request 
4448  *
4449  * @params[in] 
4450  *       du Id
4451  *       Pointer to reset response 
4452  * @return void
4453  *
4454  ******************************************************************/
4455
4456 void ProcResetRequest(uint32_t duId, ResetRequestE2_t *resetReq)
4457 {
4458    uint8_t ieIdx = 0, duIdx =0, transId=0;
4459    DuDb *duDb = NULLP;
4460    RanFunction *ranFuncDb = NULLP;
4461    uint16_t ranFuncIdx = 0;
4462
4463    SEARCH_DU_DB(duIdx, duId, duDb); 
4464    if(duDb == NULLP)
4465    {
4466       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
4467       return;
4468    }
4469    
4470    if(!resetReq)
4471    {
4472       DU_LOG("\nERROR  -->  E2AP : resetReq pointer is null"); 
4473       return;
4474    }
4475
4476    if(!resetReq->protocolIEs.list.array)      
4477    {
4478       DU_LOG("\nERROR  -->  E2AP : resetReq array pointer is null");
4479       return;
4480    }
4481    
4482    for(ieIdx=0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
4483    {
4484       if(resetReq->protocolIEs.list.array[ieIdx])
4485       {
4486          switch(resetReq->protocolIEs.list.array[ieIdx]->id)
4487          {
4488             case ProtocolIE_IDE2_id_TransactionID:
4489                {
4490                   transId = resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
4491                   break;
4492                }
4493             case ProtocolIE_IDE2_id_CauseE2:
4494                {
4495                   for(ranFuncIdx = 0; ranFuncIdx < MAX_RAN_FUNCTION; ranFuncIdx++)
4496                   {
4497                      ranFuncDb = &duDb->ranFunction[ranFuncIdx];
4498                      if(ranFuncDb->id > 0)
4499                      {
4500                         deleteRicSubscriptionList(&ranFuncDb->subscriptionList);
4501                      }
4502                   }
4503                   break;
4504                }
4505          }
4506       }
4507    }
4508
4509    if(BuildAndSendResetResponse(duId, transId) !=ROK)
4510    {
4511       DU_LOG("\nERROR  -->  E2AP : Failed to build and send reset response");
4512    }
4513 }
4514 /*******************************************************************
4515  *
4516  * @brief Processing of RIC Subscription Delete Required
4517  *
4518  * @details
4519  *
4520  *    Function : ProcRicSubsDeleteReqd
4521  *
4522  * Functionality: Processing of RIC Subscription Delete Required
4523  *    When received, RIC stub will initiate the RIC subscription
4524  *    deletion procedure towards DU
4525  *
4526  * @param  DU ID
4527  *         RIC Subscription Delete Required IEs
4528  * @return ROK-success
4529  *         RFAILED-failure
4530  *
4531  ******************************************************************/
4532 uint8_t ProcRicSubsDeleteReqd(uint32_t duId, RICsubscriptionDeleteRequired_t *ricSubsDelRqd)
4533 {
4534    uint8_t ieIdx = 0, arrIdx = 0, duIdx = 0;
4535    DuDb *duDb = NULLP;
4536    RicRequestId ricReqId;
4537    RanFunction *ranFuncDb = NULLP;
4538    RicSubscription *subsDb = NULLP;
4539    CmLList *ricSubsNode = NULLP;
4540    RICsubscriptionDeleteRequired_IEs_t *ricSubsDelRqdIe = NULLP;
4541    RICsubscription_List_withCause_t *ricSubsList = NULLP;
4542    RICsubscription_withCause_Item_t *subsItem = NULLP;
4543
4544    memset(&ricReqId, 0, sizeof(RicRequestId));
4545
4546    if(!ricSubsDelRqd)
4547    {
4548       DU_LOG("\nERROR  -->  E2AP : %s: Received NULL message", __func__);
4549       return RFAILED;
4550    }
4551
4552    SEARCH_DU_DB(duIdx, duId, duDb);
4553    if(duDb == NULLP)
4554    {
4555       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
4556       return RFAILED;
4557    }
4558
4559    for(ieIdx = 0; ieIdx < ricSubsDelRqd->protocolIEs.list.count; ieIdx++)
4560    {
4561       ricSubsDelRqdIe = ricSubsDelRqd->protocolIEs.list.array[ieIdx];
4562       switch(ricSubsDelRqdIe->id)
4563       {
4564          case ProtocolIE_IDE2_id_RICsubscriptionToBeRemoved:
4565          {
4566             ricSubsList = &ricSubsDelRqdIe->value.choice.RICsubscription_List_withCause;
4567             for(arrIdx = 0; arrIdx < ricSubsList->list.count; arrIdx++)
4568             {
4569                subsItem = &(((RICsubscription_withCause_ItemIEs_t *)ricSubsList->list.array[arrIdx])->\
4570                   value.choice.RICsubscription_withCause_Item);
4571                ranFuncDb = fetchRanFuncFromRanFuncId(duDb, subsItem->ranFunctionID);
4572                if(!ranFuncDb)
4573                {
4574                   DU_LOG("\nERROR  -->  E2AP : %s: RAN Function ID [%ld] not found", __func__, subsItem->ranFunctionID);
4575                   return RFAILED;
4576                }
4577                
4578                ricReqId.requestorId = subsItem->ricRequestID.ricRequestorID;
4579                ricReqId.instanceId = subsItem->ricRequestID.ricInstanceID;
4580                subsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
4581                if(!subsDb)
4582                {
4583                   DU_LOG("\nERROR  -->  E2AP : %s: RIC Subscription not found for Requestor_ID [%ld] Instance_ID [%ld]", \
4584                      __func__, subsItem->ricRequestID.ricRequestorID, subsItem->ricRequestID.ricInstanceID);
4585                   return RFAILED;
4586                }
4587                
4588                /* Delete RIC Subcription from RAN Function */
4589                cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubsNode);
4590                deleteRicSubscriptionNode(ricSubsNode);
4591             }
4592             
4593             break;
4594          }
4595          default:
4596             break;
4597       }
4598    }  
4599    
4600    //BuildAndSendRicSubsDeleteRequest();
4601    return ROK;
4602 }
4603
4604 /*******************************************************************
4605 *
4606 * @brief Handles received E2AP message and sends back response  
4607 *
4608 * @details
4609 *
4610 *    Function : E2APMsgHdlr
4611 *
4612 *    Functionality:
4613 *         - Decodes received E2AP control message
4614 *         - Prepares response message, encodes and sends to SCTP
4615 *
4616 * @params[in] 
4617 * @return ROK     - success
4618 *         RFAILED - failure
4619 *
4620 * ****************************************************************/
4621 void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
4622 {
4623    int             i;
4624    char            *recvBuf;
4625    MsgLen          copyCnt;
4626    MsgLen          recvBufLen;
4627    E2AP_PDU_t      *e2apMsg;
4628    asn_dec_rval_t  rval; /* Decoder return value */
4629    E2AP_PDU_t      e2apasnmsg ;
4630  
4631    DU_LOG("\nINFO  -->  E2AP : Received E2AP message buffer");
4632    ODU_PRINT_MSG(mBuf, 0,0);
4633  
4634    /* Copy mBuf into char array to decode it */
4635    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
4636    RIC_ALLOC(recvBuf, (Size)recvBufLen);
4637
4638    if(recvBuf == NULLP)
4639    {
4640       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
4641       return;
4642    }
4643    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
4644    {
4645       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
4646       return;
4647    }
4648
4649    DU_LOG("\nDEBUG  -->  E2AP : Received flat buffer to be decoded : ");
4650    for(i=0; i< recvBufLen; i++)
4651    {
4652         DU_LOG("%x",recvBuf[i]);
4653    }
4654
4655    /* Decoding flat buffer into E2AP messsage */
4656    e2apMsg = &e2apasnmsg;
4657    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
4658
4659    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
4660    RIC_FREE(recvBuf, (Size)recvBufLen);
4661
4662    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
4663    {
4664       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
4665       return;
4666    }
4667    DU_LOG("\n");
4668    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4669
4670    switch(e2apMsg->present)
4671    {
4672       case E2AP_PDU_PR_initiatingMessage:
4673          {
4674             switch(e2apMsg->choice.initiatingMessage->value.present)
4675             {
4676                case InitiatingMessageE2__value_PR_E2setupRequest:
4677                   {
4678                      DU_LOG("\nINFO  -->  E2AP : E2 setup request received");
4679                      ProcE2SetupReq(duId, &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest);
4680                      break;
4681                   }
4682                case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate:
4683                   {
4684                      DU_LOG("\nINFO  -->  E2AP : E2 node config update received");
4685                      ProcE2NodeConfigUpdate(*duId, &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate);
4686                      break;
4687                   }
4688                case InitiatingMessageE2__value_PR_ResetRequestE2:
4689                   {
4690                      DU_LOG("\nINFO  -->  E2AP : E2 Reset Request received");
4691                      ProcResetRequest(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2);
4692                      break;
4693                   }
4694                case InitiatingMessageE2__value_PR_RICindication:
4695                   {
4696                      DU_LOG("\nINFO  -->  E2AP : RIC Indication received");
4697                      break;
4698                   }
4699                case InitiatingMessageE2__value_PR_RICserviceUpdate:
4700                   {
4701                      DU_LOG("\nINFO  -->  E2AP : RIC Service update received");
4702                      ProcRicServiceUpdate(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate);
4703                      break;
4704                   }
4705                case InitiatingMessageE2__value_PR_RICsubscriptionModificationRequired:
4706                   {
4707                      DU_LOG("\nINFO  -->  E2AP : RIC Subscription Modification Required");
4708                      ProcRicSubsModReqd(*duId, \
4709                            &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired);
4710                      break;
4711                   }
4712                case InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequired:
4713                   {
4714                       DU_LOG("\nINFO  -->  E2AP : RIC Subscription Delete Required");
4715                       ProcRicSubsDeleteReqd(*duId, \
4716                          &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired);
4717                       break;
4718                   }
4719
4720                case InitiatingMessageE2__value_PR_ErrorIndicationE2:
4721                   {
4722                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
4723                      break;
4724                   }
4725                default:
4726                   {
4727                      DU_LOG("\nERROR  -->  E2AP : Invalid type of intiating message [%d]", \
4728                         e2apMsg->choice.initiatingMessage->value.present);
4729                      return;
4730                   }
4731             }/* End of switch(initiatingMessage) */
4732             break;
4733          }
4734       case E2AP_PDU_PR_successfulOutcome: 
4735          {
4736             switch(e2apMsg->choice.successfulOutcome->value.present)
4737             {
4738                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
4739                   {
4740                      DU_LOG("\nINFO  -->  E2AP : Reset response received");
4741                      ProcResetResponse(*duId,  &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2);
4742                      break;
4743                   }
4744                case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:  
4745                   {
4746                      ProcRicSubscriptionResponse(*duId, \
4747                         &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse);
4748                      break;
4749                   }
4750                default:
4751                   {
4752                      DU_LOG("\nERROR  -->  E2AP : Invalid type of successfulOutcome message [%d]", \
4753                         e2apMsg->choice.successfulOutcome->value.present);
4754                      return;
4755                   }
4756                   break;
4757             }
4758             break; 
4759          }
4760          case E2AP_PDU_PR_unsuccessfulOutcome:
4761          {
4762             switch(e2apMsg->choice.successfulOutcome->value.present)
4763             {
4764                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure:
4765                   {
4766                      ProcRicSubscriptionFailure(*duId, \
4767                         &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure);
4768                      break;
4769                   }
4770                default:
4771                   {
4772                      DU_LOG("\nERROR  -->  E2AP : Invalid type of unsuccessfulOutcome message [%d]", \
4773                         e2apMsg->choice.unsuccessfulOutcome->value.present);
4774                      return;
4775                   }
4776             }
4777             break;
4778          }
4779       default:
4780          {
4781             DU_LOG("\nERROR  -->  E2AP : Invalid type message type ");
4782             return;
4783          }
4784
4785    }/* End of switch(e2apMsg->present) */
4786 } /* End of E2APMsgHdlr */
4787
4788
4789 /**********************************************************************
4790   End of file
4791  **********************************************************************/