[Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-532] RIC Subscription Delete Request
[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       ricSubsInfo->ranFuncId = ranFuncDb->id;
1533
1534       /* Filling RIC Subscription Details */
1535       idx++;
1536       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
1537       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1538       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
1539                                                                       RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
1540       if(BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails),\
1541          ricSubsInfo) != ROK)
1542       {
1543          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : Line [%d]", __func__, __LINE__);
1544          break;
1545       }
1546
1547       /* Prints the Msg formed */
1548       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
1549
1550       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1551       encBufSize = 0;
1552       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf, encBuf);
1553       if(encRetVal.encoded == ENCODE_FAIL)
1554       {
1555          DU_LOG("\nERROR  -->  E2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
1556                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1557          break;               
1558       }
1559       else
1560       {
1561          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
1562          for(int i=0; i< encBufSize; i++)
1563          {
1564             DU_LOG("%x",encBuf[i]);
1565          } 
1566       }
1567
1568       /* Sending msg */
1569       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
1570       {
1571          DU_LOG("\nERROR  -->  E2AP : Sending RIC subscription Request failed");
1572          break;
1573       }
1574
1575       /* Add RIC Subscription Info to RAN Function's RIC Subscription List */
1576       RIC_ALLOC(ricSubsNode , sizeof(CmLList));
1577       if(!ricSubsNode)
1578       {
1579          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1580          break;
1581       }
1582       ricSubsNode->node = (PTR)ricSubsInfo;
1583       cmLListAdd2Tail(&ranFuncDb->subscriptionList, ricSubsNode);
1584
1585       ret = ROK;
1586       break;
1587    }
1588
1589    if(ret == RFAILED)
1590    {
1591       RIC_FREE(ricSubsInfo, sizeof(RicSubscription));
1592       RIC_FREE(ricSubsNode , sizeof(CmLList));
1593    }
1594
1595    FreeRicSubscriptionReq(e2apRicMsg);
1596    return ret;
1597 }
1598
1599 /*******************************************************************
1600  *
1601  * @brief Process RicSubscriptionResponse
1602  *
1603  * @details
1604  *
1605  *    Function : ProcRicSubscriptionRsp
1606  *
1607  * Functionality: Processes RicSubscriptionRsp
1608  *
1609  * @return ROK     - void
1610  *
1611  ******************************************************************/
1612
1613 void ProcRicSubscriptionResponse(uint32_t duId, RICsubscriptionResponse_t  *ricSubscriptionRsp)
1614 {
1615    uint8_t duIdx = 0, ieIdx = 0, notAdmitIdx = 0;
1616    uint8_t ranFuncId = 0, actionId = 0;
1617    DuDb *duDb = NULLP;
1618    bool ricReqIdDecoded = false;
1619    RicRequestId ricReqId;
1620    RanFunction  *ranFuncDb = NULLP;
1621    RicSubscription *ricSubs = NULLP;
1622    CmLList *ricSubsNode = NULLP;
1623    ActionInfo *action = NULLP;
1624    RICsubscriptionResponse_IEs_t *ricSubsRspIe = NULLP;
1625    RICaction_NotAdmitted_List_t *notAdmitList = NULLP;
1626
1627    DU_LOG("\nINFO  -->  E2AP : RIC Subscription Response received");
1628
1629    /* Fetch DU DB */
1630    SEARCH_DU_DB(duIdx, duId, duDb);
1631    if(duDb == NULLP)
1632    {
1633       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
1634       return;
1635    }
1636
1637    memset(&ricReqId, 0, sizeof(RicRequestId));
1638    if(ricSubscriptionRsp)
1639    {
1640       if(ricSubscriptionRsp->protocolIEs.list.array)
1641       {
1642          for(ieIdx=0; ieIdx<ricSubscriptionRsp->protocolIEs.list.count; ieIdx++)
1643          {
1644             if(ricSubscriptionRsp->protocolIEs.list.array[ieIdx])
1645             {
1646                ricSubsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
1647                switch(ricSubscriptionRsp->protocolIEs.list.array[ieIdx]->id)
1648                {
1649                   case ProtocolIE_IDE2_id_RICrequestID:
1650                      {
1651                         ricReqId.requestorId = ricSubsRspIe->value.choice.RICrequestID.ricRequestorID;
1652                         ricReqId.instanceId = ricSubsRspIe->value.choice.RICrequestID.ricInstanceID;
1653                         ricReqIdDecoded = true;
1654                         break;
1655                      }
1656                   case ProtocolIE_IDE2_id_RANfunctionID:
1657                      {
1658                         ranFuncId = ricSubsRspIe->value.choice.RANfunctionID;
1659                         ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
1660                         if(!ranFuncDb)
1661                         {
1662                            DU_LOG("\nERROR  -->  E2AP : ProcRicSubscriptionResponse: RAN Function ID [%d] not found", ranFuncId);
1663                            return;
1664                         }
1665                         break; 
1666                      }
1667                   case ProtocolIE_IDE2_id_RICactions_Admitted:
1668                      {
1669                         break;
1670                      }
1671                   case ProtocolIE_IDE2_id_RICactions_NotAdmitted:
1672                      {
1673                         if(!(ranFuncDb && ricReqIdDecoded))
1674                            return;
1675
1676                         notAdmitList = &ricSubsRspIe->value.choice.RICaction_NotAdmitted_List;
1677                         for(notAdmitIdx = 0; notAdmitIdx < notAdmitList->list.count; notAdmitIdx++)
1678                         {
1679                            actionId = ((RICaction_NotAdmitted_ItemIEs_t *)(notAdmitList->list.array[notAdmitIdx]))->\
1680                               value.choice.RICaction_NotAdmitted_Item.ricActionID;
1681
1682                            /* Remove action from RAN Function's subscription list */
1683                            ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
1684                            if(ricSubs)
1685                            {
1686                               action = fetchActionInfoFromActionId(actionId, ricSubs);
1687                               if(action)
1688                               {
1689                                  memset(action, 0, sizeof(ActionInfo));
1690                                  ricSubs->actionSequence[actionId].actionId = -1;
1691                                  ricSubs->numOfActions--;
1692                               }
1693                            }
1694                         }
1695                         break;
1696                      }
1697                }
1698             }
1699          }
1700       }
1701    } 
1702 }
1703
1704 /*******************************************************************
1705  *
1706  * @brief deallocate the memory allocated in E2SetupFailure
1707  *
1708  * @details
1709  *
1710  *    Function : FreeE2SetupFailure 
1711  *
1712  *    Functionality: deallocate the memory allocated in E2SetupFailure 
1713  *
1714  * @params[in] E2AP_PDU_t *e2apMsg
1715  *
1716  * @return void
1717  * ****************************************************************/
1718 void FreeE2SetupFailure(E2AP_PDU_t *e2apMsg)
1719 {
1720    uint8_t arrIdx = 0;
1721    E2setupFailure_t  *e2SetupFail;
1722
1723    if(e2apMsg)
1724    {
1725       if(e2apMsg->choice.unsuccessfulOutcome)
1726       {
1727          e2SetupFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
1728          if(e2SetupFail->protocolIEs.list.array)
1729          {
1730             for(arrIdx=0; arrIdx<e2SetupFail->protocolIEs.list.count; arrIdx++)
1731             {
1732                RIC_FREE(e2SetupFail->protocolIEs.list.array[arrIdx], sizeof(E2setupFailureIEs_t)); 
1733             }
1734             RIC_FREE(e2SetupFail->protocolIEs.list.array, e2SetupFail->protocolIEs.list.size);
1735          }
1736          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
1737       }
1738       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1739    }
1740 }
1741
1742 /*******************************************************************
1743  *
1744  * @brief Buld and send the E2 Setup failure
1745  *
1746  * @details
1747  *
1748  *    Function : BuildAndSendE2SetupFailure
1749  *
1750  *    Functionality:
1751  *         - Buld and send the E2 Setup failure
1752  * @return ROK     - success
1753  *         RFAILED - failure
1754  *
1755  * ****************************************************************/
1756
1757 uint8_t BuildAndSendE2SetupFailure(uint32_t duId, uint8_t transId)
1758 {
1759    uint8_t            ret = RFAILED;
1760    E2AP_PDU_t         *e2apMsg = NULL;
1761    E2setupFailure_t   *e2SetupFailure;
1762    asn_enc_rval_t     encRetVal;
1763    uint8_t            arrIdx;
1764    uint8_t            elementCnt;
1765    bool  memAllocFailed = false;
1766
1767    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup failure\n");
1768    while(true)
1769    {
1770       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
1771       if(e2apMsg == NULLP)
1772       {
1773          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1774          break;
1775       }
1776       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
1777       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
1778       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
1779       {
1780          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1781          break;
1782       }
1783
1784       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
1785       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
1786       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2setupFailure;
1787       e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
1788
1789       elementCnt = 3;
1790       e2SetupFailure->protocolIEs.list.count = elementCnt;
1791       e2SetupFailure->protocolIEs.list.size  = elementCnt * sizeof(struct E2setupFailureIEs *);
1792
1793       RIC_ALLOC(e2SetupFailure->protocolIEs.list.array, e2SetupFailure->protocolIEs.list.size);
1794       if(e2SetupFailure->protocolIEs.list.array == NULLP)
1795       {
1796          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
1797          break;
1798       }
1799
1800       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
1801       {
1802          RIC_ALLOC(e2SetupFailure->protocolIEs.list.array[arrIdx], sizeof(struct E2setupFailureIEs));
1803          if(e2SetupFailure->protocolIEs.list.array[arrIdx] == NULLP)
1804          {
1805             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
1806             memAllocFailed = true;
1807             break;
1808          }
1809       }
1810
1811       if(memAllocFailed == true)
1812       {
1813           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
1814           break;
1815       }
1816
1817       /* Trans Id */
1818       arrIdx = 0;
1819       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
1820       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1821       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TransactionID;
1822       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
1823
1824       arrIdx++;
1825       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
1826       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
1827       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_CauseE2;
1828       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.present = CauseE2_PR_protocol;
1829       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.protocol = CauseE2Protocol_unspecified;
1830
1831       arrIdx++;
1832       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
1833       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
1834       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TimeToWaitE2;
1835       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
1836
1837       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1838       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1839       encBufSize = 0;
1840       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
1841
1842       /* Check encode results */
1843       if(encRetVal.encoded == ENCODE_FAIL)
1844       {
1845          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Setup failure structure (at %s)\n",\
1846                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1847          break;
1848       }
1849       else
1850       {
1851          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Setup Failure\n");
1852          for(int i=0; i< encBufSize; i++)
1853          {
1854             DU_LOG("%x",encBuf[i]);
1855          }
1856       }
1857
1858       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
1859       {
1860          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Failure failed");
1861          break;
1862       }
1863
1864       ret = ROK;
1865       break;
1866    }
1867
1868    FreeE2SetupFailure(e2apMsg);
1869    return ret;
1870 }
1871
1872 /*******************************************************************
1873  *
1874  * @brief process the e2setup request 
1875  *
1876  * @details
1877  *
1878  *    Function : ProcE2SetupReq
1879  *
1880  * Functionality: process the e2setup request
1881  *
1882  * @return ROK     - success
1883  *         RFAILED - failure
1884  *
1885  ******************************************************************/
1886
1887 uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
1888 {
1889    uint8_t arrIdx = 0, e2NodeAddListIdx =0, duIdx = 0, transId =0, ranFuncIdx;
1890    DuDb    *duDb = NULLP;
1891    E2nodeComponentConfigAddition_List_t *e2NodeAddList;
1892    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
1893    RANfunction_ItemIEs_t *ranFuncItemIe;
1894    RANfunction_Item_t  *ranFunItem;
1895    RANfunctions_List_t *ranFunctionsList;
1896
1897    if(e2SetupReq)
1898    {
1899       if(e2SetupReq->protocolIEs.list.array)      
1900       {
1901          for(arrIdx=0; arrIdx<e2SetupReq->protocolIEs.list.count; arrIdx++)
1902          {
1903             if(e2SetupReq->protocolIEs.list.array[arrIdx])
1904             {
1905                switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
1906                {
1907                   case ProtocolIE_IDE2_id_TransactionID:
1908                      {
1909                         transId = e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; 
1910                         break;
1911                      }
1912                   case ProtocolIE_IDE2_id_GlobalE2node_ID:
1913                      {
1914                         if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID)
1915                         {
1916                             *duId =e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID->buf[0];
1917
1918                             SEARCH_DU_DB(duIdx, *duId, duDb); 
1919                             if(duDb == NULLP)
1920                             {
1921                                duDb = &ricCb.duInfo[ricCb.numDu];
1922                                ricCb.numDu++;
1923                             }
1924                             memset(duDb, 0, sizeof(DuDb));
1925                             duDb->duId = *duId;
1926                         }
1927                         break;
1928                      }
1929                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
1930                      {
1931                         ranFunctionsList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
1932
1933                         if(ranFunctionsList->list.array)
1934                         {
1935                            for(ranFuncIdx=0;ranFuncIdx<ranFunctionsList->list.count; ranFuncIdx++)
1936                            {
1937                               ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncIdx]; 
1938                               ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
1939                               duDb->ranFunction[ranFunItem->ranFunctionID-1].id = ranFunItem->ranFunctionID; 
1940                               duDb->ranFunction[ranFunItem->ranFunctionID-1].revisionCounter = ranFunItem->ranFunctionRevision; 
1941                               cmLListInit(&duDb->ranFunction[ranFunItem->ranFunctionID-1].subscriptionList);
1942                               duDb->numOfRanFunction++;
1943                            }
1944                         }
1945                         break;
1946                      }
1947                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
1948                      {
1949                         e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;      
1950                         if(e2NodeAddList->list.array)
1951                         {
1952                            for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
1953                            {
1954                               if(e2NodeAddList->list.array[e2NodeAddListIdx])
1955                               {
1956                                  e2NodeAddItem = \
1957                                     (E2nodeComponentConfigAddition_ItemIEs_t *)e2NodeAddList->list.array[e2NodeAddListIdx];
1958                                  if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.\
1959                                     choice.e2nodeComponentInterfaceTypeF1)
1960                                  {
1961                                     duDb->e2NodeComponent.interfaceType = F1; 
1962                                     duDb->e2NodeComponent.componentId = \
1963                                        e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.\
1964                                        choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]; 
1965                                  }
1966                               }
1967                            }
1968                         }
1969                         break;
1970                      }
1971                      default:
1972                         break;
1973                   }
1974                }
1975             }
1976         }
1977    }
1978    
1979    if(BuildAndSendE2SetupRsp(duDb, transId) !=ROK)
1980    {
1981       DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 setup response");
1982       return RFAILED;
1983    }
1984    return ROK;   
1985 }
1986 /*******************************************************************
1987  *
1988  * @brief Deallocate the memory allocated for E2 Reset Response
1989  *
1990  * @details
1991  *
1992  *    Function : FreeE2ResetResponse
1993  *
1994  *    Functionality:
1995  *       - freeing the memory allocated for E2ResetResponse
1996  *
1997  * @params[in] E2AP_PDU_t *e2apMsg
1998  * @return ROK     - success
1999  *         RFAILED - failure
2000  *
2001  * ****************************************************************/
2002 void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg)
2003 {
2004    uint8_t ieIdx =0;
2005    ResetResponseE2_t *resetResponse =NULLP;
2006
2007    if(e2apMsg != NULLP)
2008    {
2009       if(e2apMsg->choice.successfulOutcome != NULLP)
2010       {
2011          resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
2012          if(resetResponse->protocolIEs.list.array)
2013          {
2014             for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
2015             {
2016                if(resetResponse->protocolIEs.list.array[ieIdx])
2017                {
2018                   RIC_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
2019                }
2020             }
2021             RIC_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
2022          }
2023          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2024       }
2025       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2026    }
2027 }
2028
2029 /*******************************************************************
2030  *
2031  * @brief Buld and send the Reset Response msg
2032  *
2033  * @details
2034  *
2035  *    Function : BuildAndSendResetResponse 
2036  *
2037  *    Functionality:
2038  *         - Buld and send the Reset Response Message
2039  *
2040  * @params[in] 
2041  *    DU id
2042  *    TransId Id
2043  * @return ROK     - success
2044  *         RFAILED - failure
2045  *
2046  * ****************************************************************/
2047 uint8_t BuildAndSendResetResponse(uint32_t duId, uint8_t transId)
2048 {
2049    uint8_t           ieIdx = 0, elementCnt = 0;
2050    uint8_t           ret = RFAILED;
2051    E2AP_PDU_t        *e2apMsg = NULLP;
2052    ResetResponseE2_t *resetResponse=NULL;
2053    asn_enc_rval_t    encRetVal;       /* Encoder return value */
2054
2055    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
2056    do
2057    {
2058       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2059       if(e2apMsg == NULLP)
2060       {
2061          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
2062          break;
2063       }
2064       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
2065
2066       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2067       if(e2apMsg->choice.successfulOutcome == NULLP)
2068       {
2069          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
2070          break;
2071       }
2072  
2073       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
2074       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
2075       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
2076       resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
2077
2078       elementCnt = 1;
2079       resetResponse->protocolIEs.list.count = elementCnt;
2080       resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
2081       RIC_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
2082       if(!resetResponse->protocolIEs.list.array)
2083       {
2084          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
2085          break;
2086       }
2087
2088       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
2089       {
2090          RIC_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
2091          if(!resetResponse->protocolIEs.list.array[ieIdx])
2092          {
2093             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
2094             break;
2095          }
2096       }
2097       if(ieIdx < elementCnt)
2098          break;
2099
2100       ieIdx = 0; 
2101       resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
2102       resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
2103       resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
2104       resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
2105
2106       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2107
2108       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2109       encBufSize = 0;
2110       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2111       if(encRetVal.encoded == ENCODE_FAIL)
2112       {
2113          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
2114                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2115          break;
2116       }
2117       else
2118       {
2119          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
2120          for(int i=0; i< encBufSize; i++)
2121          {
2122             DU_LOG("%x",encBuf[i]);
2123          }
2124       }
2125
2126       /* Sending msg */
2127       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
2128       {
2129          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
2130          break;
2131       }
2132
2133       ret = ROK;
2134       break;
2135    }while(true);
2136
2137    FreeE2ResetResponse(e2apMsg);
2138    return ret;
2139 }
2140
2141 /*******************************************************************
2142  *
2143  * @brief deallocate the memory allocated in building the
2144  *    Service Query message
2145  *
2146  * @details
2147  *
2148  *    Function : FreeRicServiceQuery 
2149  *
2150  *    Functionality: deallocate the memory allocated in building
2151  *    Ric Service Query message
2152  *
2153  * @params[in] E2AP_PDU_t *e2apMsg
2154  *
2155  * @return void
2156  * ****************************************************************/
2157
2158 void FreeRicServiceQuery(E2AP_PDU_t *e2apMsg)
2159 {
2160    uint8_t arrIdx = 0, ranFuncIdx=0;
2161    RANfunctionsID_List_t *ranFuncAcceptedList=NULL;
2162    RICserviceQuery_t *ricServiceQuery=NULL;
2163    
2164    if(e2apMsg)
2165    {
2166       if(e2apMsg->choice.initiatingMessage)
2167       {
2168          ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
2169          if(ricServiceQuery->protocolIEs.list.array)
2170          {
2171             for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
2172             {
2173                if(ricServiceQuery->protocolIEs.list.array[arrIdx])
2174                {
2175                   switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
2176                   {
2177                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
2178                         {
2179                            ranFuncAcceptedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
2180                            if(ranFuncAcceptedList->list.array)
2181                            {
2182                               for(ranFuncIdx=0;ranFuncIdx<ranFuncAcceptedList->list.count; ranFuncIdx++)
2183                               {
2184                                  RIC_FREE(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
2185                               }
2186                               RIC_FREE(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
2187                            }
2188                            break;
2189                         }
2190                      case RICserviceQuery_IEs__value_PR_TransactionID:
2191                         {
2192                            break;
2193                         }
2194                   }
2195                   RIC_FREE(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t)); 
2196                }
2197             }
2198             RIC_FREE(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
2199          }
2200          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2201       }
2202       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2203    }
2204 }
2205
2206 /*******************************************************************
2207  *
2208  * @brief build and send the ric service Query 
2209  *
2210  * @details
2211  *
2212  *    Function : BuildAndSendRicServiceQuery
2213  *
2214  * Functionality: build and send the ric service Query 
2215  * @return ROK     - success
2216  *         RFAILED - Acknowledge
2217  *
2218  ******************************************************************/
2219
2220 uint8_t BuildAndSendRicServiceQuery(DuDb *duDb)
2221 {
2222    uint8_t arrIdx;
2223    uint8_t elementCnt;
2224    uint8_t ret = RFAILED;
2225    bool  memAllocFailed = false;
2226    E2AP_PDU_t     *e2apMsg = NULL;
2227    asn_enc_rval_t encRetVal;
2228    RICserviceQuery_t *ricServiceQuery;
2229
2230    DU_LOG("\nINFO   -->  E2AP : Building Ric service Query\n");
2231    while(true)
2232    {
2233       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2234       if(e2apMsg == NULLP)
2235       {
2236          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2237          break;
2238       }
2239       e2apMsg->present =  E2AP_PDU_PR_initiatingMessage;
2240       RIC_ALLOC(e2apMsg->choice.initiatingMessage , sizeof(struct InitiatingMessageE2));
2241       if(e2apMsg->choice.initiatingMessage == NULLP)
2242       {
2243          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2244          break;
2245       }
2246
2247       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceQuery;
2248       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2249       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceQuery;
2250       ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
2251
2252       elementCnt = 1;
2253       /* Fill Accepted RAN function IE If Ran function information is stored in databse */
2254       if(duDb->numOfRanFunction)
2255          elementCnt++;
2256
2257       ricServiceQuery->protocolIEs.list.count = elementCnt;
2258       ricServiceQuery->protocolIEs.list.size  = elementCnt * sizeof(RICserviceQuery_IEs_t*);
2259
2260       RIC_ALLOC(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
2261       if(ricServiceQuery->protocolIEs.list.array == NULLP)
2262       {
2263          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2264          break;
2265       }
2266
2267       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2268       {
2269          RIC_ALLOC(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t));
2270          if(ricServiceQuery->protocolIEs.list.array[arrIdx] == NULLP)
2271          {
2272             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2273             memAllocFailed = true;
2274             break;
2275          }
2276       }
2277       if(memAllocFailed == true)
2278       {
2279          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2280          break;
2281       }
2282
2283       /* Trans Id */
2284       arrIdx = 0;
2285       ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2286       ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2287       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_TransactionID;
2288       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = assignTransactionId(duDb);
2289       
2290       if(duDb->numOfRanFunction)
2291       {
2292          /* Accepted RAN function Id */
2293          arrIdx++;
2294          ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
2295          ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2296          ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_RANfunctionsID_List;
2297          if(BuildRanFunctionAcceptedList(duDb, 0, NULL, &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceQuery)!=ROK)
2298          {
2299             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
2300             break;         
2301          }
2302       }
2303       
2304       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2305       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2306       encBufSize = 0;
2307       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2308
2309       /* Check encode results */
2310       if(encRetVal.encoded == ENCODE_FAIL)
2311       {
2312          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service Query structure (at %s)\n",\
2313                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2314          break;
2315       }
2316       else
2317       {
2318          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service Query\n");
2319          for(int i=0; i< encBufSize; i++)
2320          {
2321             DU_LOG("%x",encBuf[i]);
2322          }
2323       }
2324
2325       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
2326       {
2327          DU_LOG("\nERROR  -->  E2AP : Sending of RIC service  Query failed");
2328          break;
2329       }
2330
2331       ret =ROK;
2332       break;
2333    }
2334    FreeRicServiceQuery(e2apMsg);
2335    return ret;
2336 }
2337
2338 /*******************************************************************
2339  *
2340  * @brief deallocate the memory allocated in RicServiceUpdateFailure
2341  *
2342  * @details
2343  *
2344  *    Function : FreeRicServiceUpdateFailure 
2345  *
2346  *    Functionality: deallocate the memory allocated in RicServiceUpdatefailure
2347  *
2348  * @params[in] E2AP_PDU_t *e2apMsg
2349  *
2350  * @return void
2351  * ****************************************************************/
2352
2353 void FreeRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
2354 {
2355    uint8_t arrIdx = 0;
2356    RICserviceUpdateFailure_t *ricServiceUpdateFailure=NULL;
2357    
2358    if(e2apMsg)
2359    {
2360       if(e2apMsg->choice.unsuccessfulOutcome)
2361       {
2362          ricServiceUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
2363          if(ricServiceUpdateFailure->protocolIEs.list.array)
2364          {
2365             for(arrIdx=0; arrIdx<ricServiceUpdateFailure->protocolIEs.list.count; arrIdx++)
2366             {
2367                RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t)); 
2368             }
2369             RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array, ricServiceUpdateFailure->protocolIEs.list.size);
2370          }
2371          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
2372       }
2373       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2374    }
2375 }
2376
2377 /*******************************************************************
2378  *
2379  * @brief fill E2 failure cause 
2380  *
2381  * @details
2382  *
2383  *    Function : fillE2FailureCause
2384  *
2385  * Functionality: fill E2 failure cause
2386  * @return ROK     - success
2387  *         RFAILED - failure
2388  *
2389  ******************************************************************/
2390
2391 void fillE2FailureCause(CauseE2_t *cause, CauseE2_PR causePresent, uint8_t reason)
2392 {
2393    cause->present = causePresent;
2394
2395    switch(cause->present)
2396    {
2397       case CauseE2_PR_ricRequest:
2398          cause->choice.ricRequest = reason;
2399          break;
2400       case CauseE2_PR_ricService:
2401          cause->choice.ricService = reason;
2402          break;
2403       case CauseE2_PR_e2Node:
2404          cause->choice.e2Node = reason;
2405          break;
2406       case CauseE2_PR_transport:
2407          cause->choice.transport = reason;
2408          break;
2409       case CauseE2_PR_protocol:
2410          cause->choice.protocol = reason;
2411          break;
2412       case CauseE2_PR_misc:
2413          cause->choice.misc = reason;
2414          break;
2415       default:
2416          cause->choice.misc = CauseE2Misc_unspecified;
2417          break;
2418    }
2419 }
2420
2421 /*******************************************************************
2422  *
2423  * @brief build and send the ric service update failure 
2424  *
2425  * @details
2426  *
2427  *    Function : BuildAndSendRicServiceUpdateFailure
2428  *
2429  * Functionality: build and send the ric service update failure 
2430  * @return ROK     - success
2431  *         RFAILED - failure
2432  *
2433  ******************************************************************/
2434
2435 uint8_t BuildAndSendRicServiceUpdateFailure(uint32_t duId, int8_t transId, CauseE2_PR causePresent, uint8_t reason)
2436 {
2437
2438    E2AP_PDU_t         *e2apMsg = NULL;
2439    asn_enc_rval_t     encRetVal;
2440    uint8_t            ret = RFAILED;
2441    uint8_t            arrIdx=0;
2442    uint8_t            elementCnt=0;
2443    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
2444
2445    DU_LOG("\nINFO   -->  E2AP : Building Ric service update failure\n");
2446    while(true)
2447    {
2448       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2449       if(e2apMsg == NULLP)
2450       {
2451          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2452          break;
2453       }
2454       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
2455       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
2456       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
2457       {
2458          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2459          break;
2460       }
2461
2462       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
2463       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
2464       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure;
2465       ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
2466
2467       elementCnt = 3;
2468       ricServiceFailure->protocolIEs.list.count = elementCnt;
2469       ricServiceFailure->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateFailure_IEs_t *);
2470
2471       RIC_ALLOC(ricServiceFailure->protocolIEs.list.array, ricServiceFailure->protocolIEs.list.size);
2472       if(ricServiceFailure->protocolIEs.list.array == NULLP)
2473       {
2474          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2475          break;
2476       }
2477
2478       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2479       {
2480          RIC_ALLOC(ricServiceFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t));
2481          if(ricServiceFailure->protocolIEs.list.array[arrIdx] == NULLP)
2482          {
2483             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2484             break;
2485          }
2486       }
2487       if(arrIdx<elementCnt)
2488       {
2489          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2490          break;
2491       }
2492
2493       /* Trans Id */
2494       arrIdx = 0;
2495       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2496       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2497       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TransactionID;
2498       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
2499
2500       arrIdx++;
2501       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
2502       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2503       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_CauseE2;
2504       fillE2FailureCause(&ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, causePresent, reason);
2505
2506       arrIdx++;
2507       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
2508       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
2509       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TimeToWaitE2;
2510       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
2511
2512       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2513       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2514       encBufSize = 0;
2515       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2516
2517       /* Check encode results */
2518       if(encRetVal.encoded == ENCODE_FAIL)
2519       {
2520          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update failure structure (at %s)\n",\
2521                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2522          break;
2523       }
2524       else
2525       {
2526          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Failure\n");
2527          for(int i=0; i< encBufSize; i++)
2528          {
2529             DU_LOG("%x",encBuf[i]);
2530          }
2531       }
2532
2533       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
2534       {
2535          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update failed");
2536          break;
2537       }
2538       ret = ROK;
2539       break;
2540    }
2541
2542    FreeRicServiceUpdateFailure(e2apMsg);
2543    return ret;
2544 }
2545
2546
2547 /*******************************************************************
2548  *
2549  * @brief deallocate the memory allocated in RicServiceUpdateAck(
2550  *
2551  * @details
2552  *
2553  *    Function : FreeRicServiceUpdateAck 
2554  *
2555  *    Functionality: deallocate the memory allocated in RicServiceUpdateAck
2556  *
2557  * @params[in] E2AP_PDU_t *e2apMsg
2558  *
2559  * @return void
2560  * ****************************************************************/
2561
2562 void FreeRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
2563 {
2564    uint8_t arrIdx = 0, ranFuncIdx=0;
2565    RANfunctionsID_List_t *acceptedList=NULL;
2566    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
2567    RANfunctionsIDcause_List_t  *rejectedList=NULL;
2568
2569    if(e2apMsg)
2570    {
2571       if(e2apMsg->choice.successfulOutcome)
2572       {
2573          ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
2574          if(ricServiceUpdateAck->protocolIEs.list.array)
2575          {
2576             for(arrIdx=0; arrIdx<ricServiceUpdateAck->protocolIEs.list.count; arrIdx++)
2577             {
2578                if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx])
2579                {
2580                   switch(ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id)
2581                   {
2582                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
2583                         {
2584                            acceptedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
2585                            if(acceptedList->list.array)
2586                            {
2587                               for(ranFuncIdx=0;ranFuncIdx<acceptedList->list.count; ranFuncIdx++)
2588                               {
2589                                  RIC_FREE(acceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
2590                               }
2591                               RIC_FREE(acceptedList->list.array, acceptedList->list.size);
2592                            }
2593                            break;
2594                         }
2595
2596                      case ProtocolIE_IDE2_id_RANfunctionsRejected:
2597                         {
2598                            rejectedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
2599                            if(rejectedList->list.array)
2600                            {
2601                               for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
2602                               {
2603                                  RIC_FREE(rejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
2604                               }
2605                               RIC_FREE(rejectedList->list.array, rejectedList->list.size);
2606                            }
2607                            break;
2608                         }
2609                   }
2610                   RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t)); 
2611                }
2612             }
2613             RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
2614          }
2615          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2616       }
2617       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2618    }
2619 }
2620
2621 /*******************************************************************
2622  *
2623  * @brief Build RAN function rejected list
2624  *
2625  * @details
2626  *
2627  *    Function : BuildRanFunctionRejectedList
2628  *
2629  *    Functionality: Build RAN function rejected list 
2630  *
2631  * @params[in] 
2632  *    Count of ran functions to be rejected in the list 
2633  *    Received list of RAN functions
2634  *
2635  * @return ROK - success
2636  *         RFAILED - failure
2637  * ****************************************************************/
2638
2639 uint8_t BuildRanFunctionRejectedList(uint8_t count, RanFunction *ranFunRejectedList, RANfunctionsIDcause_List_t *ranFuncRejectedList)
2640 {
2641    uint8_t ranFuncIdx = 0;
2642    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
2643    
2644    ranFuncRejectedList->list.count = count;
2645    
2646    ranFuncRejectedList->list.size = ranFuncRejectedList->list.count*sizeof(RANfunctionIDcause_ItemIEs_t*);
2647    RIC_ALLOC(ranFuncRejectedList->list.array, ranFuncRejectedList->list.size);
2648    if(ranFuncRejectedList->list.array == NULLP)
2649    {
2650       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array");
2651       return RFAILED;
2652    }
2653    
2654    for(ranFuncIdx = 0; ranFuncIdx< ranFuncRejectedList->list.count; ranFuncIdx++)
2655    {
2656       RIC_ALLOC(ranFuncRejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
2657       if(ranFuncRejectedList->list.array[ranFuncIdx] == NULLP)
2658       {
2659          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array item");
2660          return RFAILED;
2661       }
2662       ranFuncRejectedItemIe = (RANfunctionIDcause_ItemIEs_t*)ranFuncRejectedList->list.array[ranFuncIdx];
2663       ranFuncRejectedItemIe->id = ProtocolIE_IDE2_id_RANfunctionIEcause_Item;
2664       ranFuncRejectedItemIe->criticality= CriticalityE2_ignore;
2665       ranFuncRejectedItemIe->value.present = RANfunctionIDcause_ItemIEs__value_PR_RANfunctionIDcause_Item;
2666       ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID = ranFunRejectedList[ranFuncIdx].id;
2667       fillE2FailureCause(&ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.cause, CauseE2_PR_ricService,\
2668             CauseE2RICservice_ran_function_not_supported);
2669    }
2670    
2671    return ROK;
2672 }
2673
2674 /*******************************************************************
2675  *
2676  * @brief build and send the ric service update Acknowledge 
2677  *
2678  * @details
2679  *
2680  *    Function : BuildAndSendRicServiceUpdateAcknowledge
2681  *
2682  * Functionality: build and send the ric service update Acknowledge 
2683  * @return ROK     - success
2684  *         RFAILED - Acknowledge
2685  *
2686  ******************************************************************/
2687
2688 uint8_t BuildAndSendRicServiceUpdateAcknowledge(DuDb *duDb, int8_t transId, RicTmpRanFunList ricRanFuncList)
2689 {
2690    E2AP_PDU_t         *e2apMsg = NULL;
2691    asn_enc_rval_t     encRetVal;
2692    uint8_t  arrIdx=0, elementCnt=0, ret=RFAILED;;
2693    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
2694
2695    DU_LOG("\nINFO   -->  E2AP : Building Ric service update Acknowledge\n");
2696    while(true)
2697    {
2698       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2699       if(e2apMsg == NULLP)
2700       {
2701          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2702          break;
2703       }
2704       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
2705       RIC_ALLOC(e2apMsg->choice.successfulOutcome , sizeof(struct SuccessfulOutcomeE2));
2706       if(e2apMsg->choice.successfulOutcome == NULLP)
2707       {
2708          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2709          break;
2710       }
2711
2712       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
2713       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
2714       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge;
2715       ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
2716
2717       elementCnt = 1;
2718       if(ricRanFuncList.numOfRanFunAccepted)
2719          elementCnt++;
2720       if(ricRanFuncList.numOfRanFuneRejected)
2721          elementCnt++;
2722       
2723
2724       ricServiceUpdateAck->protocolIEs.list.count = elementCnt;
2725       ricServiceUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateAcknowledge_IEs_t*);
2726
2727       RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
2728       if(ricServiceUpdateAck->protocolIEs.list.array == NULLP)
2729       {
2730          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2731          break;
2732       }
2733
2734       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2735       {
2736          RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t));
2737          if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
2738          {
2739             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2740             break;
2741          }
2742       }
2743       if(arrIdx<elementCnt)
2744       {
2745          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2746          break;
2747       }
2748
2749       /* Trans Id */
2750       arrIdx = 0;
2751       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2752       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2753       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_TransactionID;
2754       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
2755
2756       if(ricRanFuncList.numOfRanFunAccepted)
2757       {
2758          /* Accepted RAN function List */
2759          arrIdx++;
2760          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
2761          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2762          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsID_List;
2763          if(BuildRanFunctionAcceptedList(duDb, ricRanFuncList.numOfRanFunAccepted, ricRanFuncList.ranFunAcceptedList,\
2764          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceUpdate)!=ROK)       
2765          {
2766             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
2767             break;         
2768          }
2769       }
2770       
2771       if(ricRanFuncList.numOfRanFuneRejected)
2772       {
2773          /* RAN Functions Rejected List */
2774          arrIdx++;
2775          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsRejected;
2776          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2777          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsIDcause_List;
2778          if(BuildRanFunctionRejectedList(ricRanFuncList.numOfRanFuneRejected, ricRanFuncList.ranFunRejectedList, \
2779          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List)!=ROK)       
2780          {
2781             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function rejected list");
2782             break;         
2783          }
2784       }
2785       
2786       
2787       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2788       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2789       encBufSize = 0;
2790       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2791
2792       /* Check encode results */
2793       if(encRetVal.encoded == ENCODE_FAIL)
2794       {
2795          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update Acknowledge structure (at %s)\n",\
2796                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2797          break;
2798       }
2799       else
2800       {
2801          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Acknowledge\n");
2802          for(int i=0; i< encBufSize; i++)
2803          {
2804             DU_LOG("%x",encBuf[i]);
2805          }
2806       }
2807
2808       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
2809       {
2810          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update ack failed");
2811          break;
2812       }
2813       ret =ROK;
2814       break;
2815    }
2816    FreeRicServiceUpdateAck(e2apMsg);
2817    return ret; 
2818 }
2819
2820 /*******************************************************************
2821  *
2822  * @brief process the RIC service update 
2823  *
2824  * @details
2825  *
2826  *    Function : ProcRicserviceUpdate 
2827  *
2828  * Functionality: process the RIC service update 
2829  *
2830  * @return ROK     - success
2831  *         RFAILED - failure
2832  *
2833  ******************************************************************/
2834
2835 void ProcRicServiceUpdate(uint32_t duId, RICserviceUpdate_t *ricServiceUpdate)
2836 {
2837    RicTmpRanFunList ricRanFuncList;
2838    DuDb    *duDb = NULLP;
2839    int8_t transId =-1;
2840    uint8_t duIdx = 0, elementCnt =0, arrIdx = 0; 
2841    uint16_t ranFuncIdx = 0, failedRanFuncCount=0, recvdRanFuncCount=0;
2842    RanFunction *ranFuncDb = NULLP;
2843    RANfunction_ItemIEs_t *ranFuncItemIe =NULL;
2844    RANfunction_Item_t  *ranFuncItem =NULL;
2845    RANfunctionID_Item_t  *ranFuncIdItem=NULL;
2846    RANfunctions_List_t *ranFuncList=NULL;
2847    RANfunctionsID_List_t *deleteList=NULL;
2848    RANfunctionID_ItemIEs_t *delRanFuncItem=NULL;
2849
2850    SEARCH_DU_DB(duIdx, duId, duDb); 
2851    if(duDb == NULLP)
2852    {
2853       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
2854       return;
2855    }
2856    memset(&ricRanFuncList, 0, sizeof(RicTmpRanFunList)); 
2857
2858    if(!ricServiceUpdate)
2859    {
2860       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate pointer is null"); 
2861       return;
2862    }
2863
2864    if(!ricServiceUpdate->protocolIEs.list.array)      
2865    {
2866       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array pointer is null");
2867       return;
2868    }
2869    elementCnt = ricServiceUpdate->protocolIEs.list.count;
2870    for(arrIdx=0; arrIdx<ricServiceUpdate->protocolIEs.list.count; arrIdx++)
2871    {
2872       if(!ricServiceUpdate->protocolIEs.list.array[arrIdx])
2873       {
2874          DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array idx %d pointer is null",arrIdx);
2875          return;
2876       }
2877
2878       switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
2879       {
2880          case ProtocolIE_IDE2_id_TransactionID:
2881             {
2882                transId = ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
2883
2884                if(transId < 0 || transId > 255)
2885                {
2886                   DU_LOG("\nERROR  -->  E2AP : Received invalid transId %d",transId);
2887                   return;
2888                }
2889                break;
2890             }
2891
2892          case ProtocolIE_IDE2_id_RANfunctionsAdded:
2893             {
2894                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
2895
2896                if(ranFuncList->list.array)
2897                {
2898                   for(ranFuncIdx=0;ranFuncIdx<ranFuncList->list.count; ranFuncIdx++)
2899                   {
2900                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx]; 
2901                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
2902
2903                      /* Adding the ran function in temporary list */
2904                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
2905                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
2906                      ricRanFuncList.numOfRanFunAccepted++;
2907
2908                      /* Adding the new ran function in DB*/
2909                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].id = ranFuncItem->ranFunctionID;
2910                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
2911                      duDb->numOfRanFunction++;
2912
2913                      /* Calculating total number of ran fuctions which are received for addition */
2914                      recvdRanFuncCount++;
2915                   }
2916                }
2917                break;
2918             }
2919
2920          case ProtocolIE_IDE2_id_RANfunctionsModified:
2921             {
2922
2923                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List; 
2924                if(ranFuncList->list.array)
2925                {
2926                   for(ranFuncIdx = 0; ranFuncIdx< ranFuncList->list.count; ranFuncIdx++)
2927                   {
2928                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx];
2929                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
2930                      if(fetchRanFuncFromRanFuncId(duDb, ranFuncItem->ranFunctionID) == NULLP)
2931                      {
2932                         /* Calculating total number of ran fuctions which are not present */
2933                         failedRanFuncCount++;
2934
2935                         /* Adding the ran function in temporary list */
2936                         ricRanFuncList.ranFunRejectedList[ricRanFuncList.numOfRanFuneRejected].id =  ranFuncItem->ranFunctionID; 
2937                         ricRanFuncList.numOfRanFuneRejected++;
2938                      }
2939                      else
2940                      {
2941
2942                         /* Adding the ran function in temporary list */
2943                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
2944                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
2945                         ricRanFuncList.numOfRanFunAccepted++;
2946
2947                         /* Updating the new ran function in DB*/
2948                         duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
2949                      }
2950                      /* Calculating total number of ran fuctions which are received for modification */
2951                      recvdRanFuncCount++;
2952                   }
2953                }
2954                break;
2955             }
2956          case ProtocolIE_IDE2_id_RANfunctionsDeleted:
2957             {
2958
2959                deleteList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List; 
2960                if(deleteList->list.array)
2961                {
2962                   for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
2963                   {
2964                      delRanFuncItem  = (RANfunctionID_ItemIEs_t*) deleteList->list.array[ranFuncIdx];
2965                      ranFuncIdItem = &delRanFuncItem->value.choice.RANfunctionID_Item;
2966                      ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncIdItem->ranFunctionID);
2967                      if(ranFuncDb)
2968                      {
2969                         memset(ranFuncDb, 0, sizeof(RanFunction));
2970                         duDb->numOfRanFunction--; 
2971                      }
2972
2973                      /* Calculating total number of ran fuctions which are received for deletion */
2974                      recvdRanFuncCount++;
2975                   }
2976                }
2977                break;
2978             }
2979
2980          default:
2981             {
2982                DU_LOG("\nERROR  -->  E2AP : IE [%ld] is not supported",ricServiceUpdate->protocolIEs.list.array[arrIdx]->id);
2983                break;
2984             }
2985       }
2986    }
2987    
2988    /* Sending RIC Service Update Failed if all RAN Functions received fail or if any IE processing fails
2989     * Else sending RIC Service Update Acknowledge */  
2990    if((elementCnt > arrIdx) ||((recvdRanFuncCount > 0) && (recvdRanFuncCount == failedRanFuncCount)))
2991    {
2992       if(BuildAndSendRicServiceUpdateFailure(duDb->duId, transId, CauseE2_PR_misc, CauseE2Misc_unspecified) != ROK)
2993       {
2994          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update Failure");
2995          return;
2996       }
2997    }
2998    else
2999    {
3000       if(BuildAndSendRicServiceUpdateAcknowledge(duDb, transId, ricRanFuncList) != ROK)
3001       {
3002          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update acknowledge");
3003          return;
3004       }
3005    }
3006 }
3007
3008 /*******************************************************************
3009  *
3010  * @brief Processing RIC subscription failure from DU
3011  *
3012  * @details
3013  *
3014  *    Function : ProcRicSubscriptionFailure
3015  *
3016  * Functionality: Processing RIC subscription failure from DU
3017  *
3018  * @param  ID of DU from which message was sent
3019  *         RIC Subscription failure message
3020  * @return ROK     - success
3021  *         RFAILED - failure
3022  *
3023  ******************************************************************/
3024 uint8_t ProcRicSubscriptionFailure(uint32_t duId, RICsubscriptionFailure_t *ricSubscriptionFailure)
3025 {
3026    uint8_t ieIdx = 0, duIdx = 0;
3027    uint8_t ranFuncId = 0;
3028    DuDb    *duDb = NULLP;
3029    RanFunction *ranFuncDb = NULLP;
3030    RicSubscription *ricSubs = NULLP;
3031    CmLList *ricSubsNode = NULLP;
3032    RicRequestId ricReqId;
3033    RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
3034
3035    DU_LOG("\nINFO  -->  E2AP : Received RIC subscription failure");
3036
3037    SEARCH_DU_DB(duIdx, duId, duDb);
3038    if(duDb == NULLP)
3039    {
3040       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
3041       return RFAILED;
3042    }
3043
3044    memset(&ricReqId, 0, sizeof(RicRequestId));
3045    if(ricSubscriptionFailure)
3046    {
3047       if(ricSubscriptionFailure->protocolIEs.list.array)
3048       {
3049          for(ieIdx=0; ieIdx<ricSubscriptionFailure->protocolIEs.list.count; ieIdx++)
3050          {
3051             if(ricSubscriptionFailure->protocolIEs.list.array[ieIdx])
3052             {
3053                ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[ieIdx];
3054                switch(ricSubscriptionFailure->protocolIEs.list.array[ieIdx]->id)
3055                {
3056                   case ProtocolIE_IDE2_id_RICrequestID:
3057                   {
3058                      ricReqId.requestorId = ricSubsFailIe->value.choice.RICrequestID.ricRequestorID;
3059                      ricReqId.instanceId = ricSubsFailIe->value.choice.RICrequestID.ricInstanceID;
3060                      break;
3061                   }
3062                   case ProtocolIE_IDE2_id_RANfunctionID:
3063                   {
3064                      ranFuncId = ricSubsFailIe->value.choice.RANfunctionID;
3065                      ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
3066                      if(!ranFuncDb)
3067                      {
3068                         DU_LOG("\nERROR  -->  E2AP : ProcRicSubscriptionFailure : RAN Function Id [%d] not found", ranFuncId);
3069                         return RFAILED;
3070                      }
3071                      else
3072                      {
3073                         /* Remove subscription entry from RAN Function */
3074                         ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
3075                         if(ricSubs)
3076                         {
3077                            cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubsNode);
3078                            deleteRicSubscriptionNode(ricSubsNode);
3079                         }
3080                      }
3081                      break; 
3082                   }
3083                   case ProtocolIE_IDE2_id_CauseE2:
3084                   default:
3085                      /* No handling required as of now since this is a stub */
3086                      break;
3087                }
3088             }
3089          }
3090       }
3091    }
3092    return ROK;
3093 }
3094
3095 /*******************************************************************
3096  *
3097  * @brief Free RIC Subscription Modification Refuse
3098  *
3099  * @details
3100  *
3101  *    Function : FreeRicSubsModRefuse
3102  *
3103  * Functionality: Free RIC Subscription Modification Refuse
3104  *
3105  * @param  E2AP Message PDU to be freed
3106  * @return void
3107  *
3108  ******************************************************************/
3109 void FreeRicSubsModRefuse(E2AP_PDU_t *e2apMsg)
3110 {
3111    uint8_t ieIdx =0;
3112    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
3113
3114    if(e2apMsg)
3115    {
3116       if(e2apMsg->choice.unsuccessfulOutcome)
3117       {
3118          ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
3119          if(ricSubsModRefuse->protocolIEs.list.array)
3120          {
3121             for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++)
3122             {
3123                RIC_FREE(ricSubsModRefuse->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRefuse_IEs_t));
3124             }
3125             RIC_FREE(ricSubsModRefuse->protocolIEs.list.array, ricSubsModRefuse->protocolIEs.list.size);
3126          }
3127          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome , sizeof(UnsuccessfulOutcomeE2_t));
3128       }
3129       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3130    }
3131 }
3132
3133 /*******************************************************************
3134  *
3135  * @brief Build And Send RIC Subscription Modification Refuse
3136  *
3137  * @details
3138  *
3139  *    Function : BuildAndSendRicSubsModRefuse
3140  *
3141  * Functionality: Build And Send RIC Subscription Modification Refuse
3142  *
3143  * @param DU ID
3144  *        RIC Request ID of subscription
3145  *        RAN Function ID
3146  *        Type of failure
3147  *        Cause of failure
3148  * @return ROK - success
3149  *         RFAILED - failure
3150  *
3151  ******************************************************************/
3152 uint8_t BuildAndSendRicSubsModRefuse(uint32_t duId, RicRequestId ricReqId, uint16_t ranFuncId, CauseE2_PR causeType, \
3153    uint8_t cause)
3154 {
3155    uint8_t ieIdx = 0, elementCnt = 0;
3156    uint8_t ret = RFAILED;
3157    E2AP_PDU_t *e2apMsg = NULL;
3158    asn_enc_rval_t encRetVal;
3159    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
3160    RICsubscriptionModificationRefuse_IEs_t *ricSubsModRefuseIe = NULLP;
3161
3162    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Refuse\n");
3163    while(true)
3164    {
3165       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3166       if(e2apMsg == NULLP)
3167       {
3168          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3169          break;
3170       }
3171       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
3172       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(UnsuccessfulOutcomeE2_t));
3173       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
3174       {
3175          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3176          break;
3177       }
3178
3179       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired;
3180       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
3181       e2apMsg->choice.unsuccessfulOutcome->value.present = \
3182          UnsuccessfulOutcomeE2__value_PR_RICsubscriptionModificationRefuse;
3183       ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
3184
3185       elementCnt = 3;
3186       ricSubsModRefuse->protocolIEs.list.count = elementCnt;
3187       ricSubsModRefuse->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationRefuse_IEs_t *);
3188       RIC_ALLOC(ricSubsModRefuse->protocolIEs.list.array, ricSubsModRefuse->protocolIEs.list.size);
3189       if(!ricSubsModRefuse->protocolIEs.list.array)
3190       {
3191          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3192          break;
3193       }
3194
3195       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
3196       {
3197          RIC_ALLOC(ricSubsModRefuse->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRefuse_IEs_t));
3198          if(!ricSubsModRefuse->protocolIEs.list.array[ieIdx])
3199          {
3200             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3201             break;
3202          }
3203       }
3204       
3205       /* RIC Request ID */
3206       ieIdx = 0;
3207       ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
3208       ricSubsModRefuseIe->id = ProtocolIE_IDE2_id_RICrequestID;
3209       ricSubsModRefuseIe->criticality = CriticalityE2_reject;
3210       ricSubsModRefuseIe->value.present = RICsubscriptionModificationRefuse_IEs__value_PR_RICrequestID;
3211       ricSubsModRefuseIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
3212       ricSubsModRefuseIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
3213
3214       /* RAN Function ID */
3215       ieIdx++;
3216       ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
3217       ricSubsModRefuseIe->id = ProtocolIE_IDE2_id_RANfunctionID;
3218       ricSubsModRefuseIe->criticality = CriticalityE2_reject;
3219       ricSubsModRefuseIe->value.present = RICsubscriptionModificationRefuse_IEs__value_PR_RANfunctionID;
3220       ricSubsModRefuseIe->value.choice.RANfunctionID = ranFuncId;
3221
3222       /* Cause */
3223       ieIdx++;
3224       ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
3225       ricSubsModRefuseIe->id = ProtocolIE_IDE2_id_CauseE2;
3226       ricSubsModRefuseIe->criticality = CriticalityE2_reject;
3227       ricSubsModRefuseIe->value.present = RICsubscriptionModificationRefuse_IEs__value_PR_CauseE2;
3228       fillE2FailureCause(&ricSubsModRefuseIe->value.choice.CauseE2, causeType, cause); 
3229
3230       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3231       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3232       encBufSize = 0;
3233       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3234
3235       /* Check encode results */
3236       if(encRetVal.encoded == ENCODE_FAIL)
3237       {
3238          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC subscription modification refuse (at %s)\n",\
3239                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3240          break;
3241       }
3242       else
3243       {
3244          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC subscription modification refuse\n");
3245          for(int i=0; i< encBufSize; i++)
3246          {
3247             DU_LOG("%x",encBuf[i]);
3248          }
3249       }
3250
3251       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
3252       {
3253          DU_LOG("\nERROR  -->  E2AP : Failed to send RIC Subscription Modification Refused");
3254          break;
3255       }
3256
3257       ret =ROK;
3258       break;
3259    }
3260    FreeRicSubsModRefuse(e2apMsg);
3261    return ret;
3262 }
3263
3264 /*******************************************************************
3265  *
3266  * @brief Free memory for RIC Subscription Modification Confirm
3267  *
3268  * @details
3269  *
3270  *    Function : FreeRicSubsModConfirm
3271  *
3272  * Functionality: Free memory for RIC subscription modification
3273  *    confirm
3274  *
3275  * @param E2AP Message PDU to be freed
3276  * @return Void
3277  *
3278  ******************************************************************/
3279 void FreeRicSubsModConfirm(E2AP_PDU_t *e2apMsg)
3280 {
3281    uint8_t ieIdx = 0, arrIdx=0;
3282    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
3283    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
3284    RICactions_ConfirmedForModification_List_t *modCfmList = NULLP;
3285    RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP;
3286    RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP;
3287    RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP;
3288
3289    if(e2apMsg)
3290    {
3291       if(e2apMsg->choice.successfulOutcome)
3292       {
3293          ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
3294          if(ricSubsModCfm->protocolIEs.list.array)
3295          {
3296             for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++)
3297             {
3298                if(ricSubsModCfm->protocolIEs.list.array[ieIdx])
3299                {
3300                   ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
3301                   switch(ricSubsModCfmIe->id)
3302                   {
3303                      case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List:
3304                         {
3305                            modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List;
3306                            if(modCfmList->list.array)
3307                            {
3308                               for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
3309                               {
3310                                  RIC_FREE(modCfmList->list.array[arrIdx], \
3311                                     sizeof(RICaction_ConfirmedForModification_ItemIEs_t));
3312                               }
3313                               RIC_FREE(modCfmList->list.array,  modCfmList->list.size);
3314                            }
3315                            break;
3316                         }
3317
3318                      case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List:
3319                         {
3320                            modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List;
3321                            if(modRefusedList->list.array)
3322                            {
3323                               for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
3324                               {
3325                                  RIC_FREE(modRefusedList->list.array[arrIdx], \
3326                                        sizeof(RICaction_RefusedToBeModified_ItemIEs_t));
3327                               }
3328                               RIC_FREE(modRefusedList->list.array,  modRefusedList->list.size);
3329                            }
3330                            break;
3331                         }
3332
3333                      case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List:
3334                         {
3335                            rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List;
3336                            if(rmvCfmList->list.array)
3337                            {
3338                               for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
3339                               {
3340                                  RIC_FREE(rmvCfmList->list.array[arrIdx], \
3341                                        sizeof(RICaction_ConfirmedForRemoval_ItemIEs_t));
3342                               }
3343                               RIC_FREE(rmvCfmList->list.array,  rmvCfmList->list.size);
3344                            }
3345                            break;
3346                         }
3347
3348                      case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List:
3349                         {
3350                            rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List;
3351                            if(rmvFailList->list.array)
3352                            {
3353                               for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
3354                               {
3355                                  RIC_ALLOC(rmvFailList->list.array[arrIdx], \
3356                                     sizeof(RICaction_RefusedToBeRemoved_ItemIEs_t));
3357                               }
3358                               RIC_FREE(rmvFailList->list.array,  rmvFailList->list.size);
3359                            }
3360                            break;
3361                         }
3362
3363                      default:
3364                         break;
3365
3366                   }
3367                   RIC_FREE(ricSubsModCfmIe, sizeof(RICsubscriptionModificationConfirm_IEs_t));
3368                }
3369             }
3370             RIC_FREE(ricSubsModCfm->protocolIEs.list.array, ricSubsModCfm->protocolIEs.list.size);
3371          }
3372          RIC_FREE(e2apMsg->choice.successfulOutcome , sizeof(SuccessfulOutcomeE2_t));
3373       }
3374       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3375    }
3376 }
3377
3378 /*******************************************************************
3379  *
3380  * @brief Fill the list of actions confirmed for modification
3381  *
3382  * @details
3383  *
3384  *    Function : fillActionModConfirmedList
3385  *
3386  * Functionality: Fill the list of actions confirmed for modification
3387  *
3388  * @param List to be filled
3389  *        Number of actions
3390  *        Source list of actions
3391  * @return ROK - success
3392  *         RFAILED - failure
3393  *
3394  ******************************************************************/
3395 uint8_t fillActionModConfirmedList(RICactions_ConfirmedForModification_List_t *modCfmList, uint8_t numActions, \
3396    uint8_t *actionModifiedList)
3397 {
3398    uint8_t arrIdx = 0;
3399    RICaction_ConfirmedForModification_ItemIEs_t *modCfmListItem = NULLP;
3400
3401    modCfmList->list.count = numActions;
3402    modCfmList->list.size = numActions * sizeof(RICaction_ConfirmedForModification_ItemIEs_t *);
3403    RIC_ALLOC(modCfmList->list.array,  modCfmList->list.size);
3404    if(!modCfmList->list.array)
3405    {
3406       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3407       return RFAILED;
3408    }
3409
3410    for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
3411    {
3412       RIC_ALLOC(modCfmList->list.array[arrIdx], sizeof(RICaction_ConfirmedForModification_ItemIEs_t));
3413       if(!modCfmList->list.array[arrIdx])
3414       {
3415          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3416          return RFAILED;
3417       }
3418
3419       modCfmListItem = (RICaction_ConfirmedForModification_ItemIEs_t *)modCfmList->list.array[arrIdx];
3420       modCfmListItem->id = ProtocolIE_IDE2_id_RICaction_ConfirmedForModification_Item;
3421       modCfmListItem->criticality = CriticalityE2_ignore;
3422       modCfmListItem->value.present = \
3423          RICaction_ConfirmedForModification_ItemIEs__value_PR_RICaction_ConfirmedForModification_Item;
3424       modCfmListItem->value.choice.RICaction_ConfirmedForModification_Item.ricActionID = actionModifiedList[arrIdx];
3425    }
3426
3427    return ROK;
3428 }
3429
3430 /*******************************************************************
3431  *
3432  * @brief Fill the list of actions refused to be modified
3433  *
3434  * @details
3435  *
3436  *    Function : fillActionModRefusedList
3437  *
3438  * Functionality: Fill the list of actions refused to be modified
3439  *
3440  * @param List to be filled
3441  *        Number of list
3442  *        Source list of actions refused tobe modified
3443  * @return ROK - success
3444  *         RFAILED - failure
3445  *
3446  ******************************************************************/
3447 uint8_t fillActionModRefusedList(RICactions_RefusedToBeModified_List_t *modRefusedList, uint8_t numActions, \
3448    ActionFailed *actionModFailedList)
3449 {
3450    uint8_t arrIdx = 0;
3451    RICaction_RefusedToBeModified_ItemIEs_t *modRefusedListItem = NULLP;
3452
3453    modRefusedList->list.count = numActions;
3454    modRefusedList->list.size = numActions * sizeof(RICaction_RefusedToBeModified_ItemIEs_t *);
3455    RIC_ALLOC(modRefusedList->list.array,  modRefusedList->list.size);
3456    if(!modRefusedList->list.array)
3457    {
3458       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3459       return RFAILED;
3460    }
3461
3462    for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
3463    {
3464       RIC_ALLOC(modRefusedList->list.array[arrIdx], sizeof(RICaction_RefusedToBeModified_ItemIEs_t));
3465       if(!modRefusedList->list.array[arrIdx])
3466       {
3467          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3468          return RFAILED;
3469       }
3470
3471       modRefusedListItem = (RICaction_RefusedToBeModified_ItemIEs_t *)modRefusedList->list.array[arrIdx];
3472       modRefusedListItem->id = ProtocolIE_IDE2_id_RICaction_RefusedToBeModified_Item;
3473       modRefusedListItem->criticality = CriticalityE2_ignore;
3474       modRefusedListItem->value.present = \
3475          RICaction_RefusedToBeModified_ItemIEs__value_PR_RICaction_RefusedToBeModified_Item;
3476       modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.ricActionID = \
3477          actionModFailedList[arrIdx].actionId;
3478       fillE2FailureCause(&modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.cause, \
3479          actionModFailedList[arrIdx].failureType, actionModFailedList[arrIdx].cause);
3480    }
3481
3482    return ROK;
3483 }
3484
3485 /*******************************************************************
3486  *
3487  * @brief Fill the list of action confirmed for removal
3488  *
3489  * @details
3490  *
3491  *    Function : fillActionRemovalConfirmedList
3492  *
3493  * Functionality: Fill the list of action confirmed for removal
3494  *
3495  * @param List to be filled
3496  *        Number of actions
3497  *        Source list of actions removed
3498  * @return ROK - success
3499  *         RFAILED - failure
3500  *
3501  ******************************************************************/
3502 uint8_t fillActionRemovalConfirmedList(RICactions_ConfirmedForRemoval_List_t *rmvCfmList, uint8_t numActions, \
3503    uint8_t *actionRemovedList)
3504 {
3505    uint8_t arrIdx = 0;
3506    RICaction_ConfirmedForRemoval_ItemIEs_t *rmvCfmListItem = NULLP;
3507
3508    rmvCfmList->list.count = numActions;
3509    rmvCfmList->list.size = numActions * sizeof(RICaction_ConfirmedForRemoval_ItemIEs_t *);
3510    RIC_ALLOC(rmvCfmList->list.array,  rmvCfmList->list.size);
3511    if(!rmvCfmList->list.array)
3512    {
3513       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3514       return RFAILED;
3515    }
3516
3517    for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
3518    {
3519       RIC_ALLOC(rmvCfmList->list.array[arrIdx], sizeof(RICaction_ConfirmedForRemoval_ItemIEs_t));
3520       if(!rmvCfmList->list.array[arrIdx])
3521       {
3522          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3523          return RFAILED;
3524       }
3525
3526       rmvCfmListItem = (RICaction_ConfirmedForRemoval_ItemIEs_t *)rmvCfmList->list.array[arrIdx];
3527       rmvCfmListItem->id = ProtocolIE_IDE2_id_RICaction_ConfirmedForRemoval_Item;
3528       rmvCfmListItem->criticality = CriticalityE2_ignore;
3529       rmvCfmListItem->value.present = \
3530          RICaction_ConfirmedForRemoval_ItemIEs__value_PR_RICaction_ConfirmedForRemoval_Item;
3531       rmvCfmListItem->value.choice.RICaction_ConfirmedForRemoval_Item.ricActionID = actionRemovedList[arrIdx];
3532    }
3533
3534    return ROK;
3535 }
3536
3537 /*******************************************************************
3538  *
3539  * @brief Fill the list of actions refused to be removed
3540  *
3541  * @details
3542  *
3543  *    Function : fillActionRemovalRefusedList
3544  *
3545  * Functionality: Fill the list of actions refused to be removed
3546  *
3547  * @param List to be filled
3548  *        Number of list
3549  *        Source list of actions refused to be removed
3550  * @return ROK - success
3551  *         RFAILED - failure
3552  *
3553  ******************************************************************/
3554 uint8_t fillActionRemovalRefusedList(RICactions_RefusedToBeRemoved_List_t *rmvFailList, \
3555    uint8_t numActions, ActionFailed *actionRmvlFailList)
3556 {
3557    uint8_t arrIdx = 0;
3558    RICaction_RefusedToBeRemoved_ItemIEs_t *rmvFailListItem = NULLP;
3559
3560    rmvFailList->list.count = numActions;
3561    rmvFailList->list.size = numActions * sizeof(RICaction_RefusedToBeRemoved_ItemIEs_t *);
3562    RIC_ALLOC(rmvFailList->list.array,  rmvFailList->list.size);
3563    if(!rmvFailList->list.array)
3564    {
3565       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3566       return RFAILED;
3567    }
3568
3569    for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
3570    {
3571       RIC_ALLOC(rmvFailList->list.array[arrIdx], sizeof(RICaction_RefusedToBeRemoved_ItemIEs_t));
3572       if(!rmvFailList->list.array[arrIdx])
3573       {
3574          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3575          return RFAILED;
3576       }
3577
3578       rmvFailListItem = (RICaction_RefusedToBeRemoved_ItemIEs_t *)rmvFailList->list.array[arrIdx];
3579       rmvFailListItem->id = ProtocolIE_IDE2_id_RICaction_RefusedToBeRemoved_Item;
3580       rmvFailListItem->criticality = CriticalityE2_ignore;
3581       rmvFailListItem->value.present = \
3582          RICaction_RefusedToBeRemoved_ItemIEs__value_PR_RICaction_RefusedToBeRemoved_Item;
3583       rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.ricActionID = actionRmvlFailList[arrIdx].actionId;
3584       fillE2FailureCause(&rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.cause, \
3585          actionRmvlFailList[arrIdx].failureType, actionRmvlFailList[arrIdx].cause);
3586    }
3587
3588    return ROK;
3589
3590 }
3591
3592 /*******************************************************************
3593  *
3594  * @brief Build And Send RIC Subscription Modification Confirm
3595  *
3596  * @details
3597  *
3598  *    Function : BuildAndSendRicSubsModConfirm
3599  *
3600  * Functionality: Build And Send RIC Subscription Modification Confirm
3601  *
3602  * @param DU ID
3603  *        RIC Request ID of subscription
3604  *        RAN Function ID
3605  *        Temporary source action list
3606  * @return ROK - success
3607  *         RFAILED - failure
3608  *
3609  ******************************************************************/
3610 uint8_t BuildAndSendRicSubsModConfirm(uint32_t duId, RicRequestId ricReqId, uint16_t ranFuncId, RicTmpActionList tmpActionList)
3611 {
3612    uint8_t ieIdx = 0, elementCnt = 0;
3613    uint8_t ret = RFAILED;
3614    E2AP_PDU_t *e2apMsg = NULLP;
3615    asn_enc_rval_t encRetVal;
3616    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
3617    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
3618
3619    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Confirm\n");
3620    while(true)
3621    {
3622       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3623       if(e2apMsg == NULLP)
3624       {
3625          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3626          break;
3627       }
3628
3629       /* Successful Outcome */
3630       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
3631       RIC_ALLOC(e2apMsg->choice.successfulOutcome , sizeof(SuccessfulOutcomeE2_t));
3632       if(e2apMsg->choice.successfulOutcome == NULLP)
3633       {
3634          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3635          break;
3636       }
3637
3638       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired;
3639       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
3640       e2apMsg->choice.successfulOutcome->value.present = \
3641          SuccessfulOutcomeE2__value_PR_RICsubscriptionModificationConfirm;
3642       ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
3643
3644       elementCnt = 2;
3645       if(tmpActionList.numActionModified)
3646          elementCnt++;
3647       if(tmpActionList.numActionModFailed)
3648          elementCnt++;
3649       if(tmpActionList.numActionRemoved)
3650          elementCnt++;
3651       if(tmpActionList.numActionRemovalFailed)
3652          elementCnt++;
3653
3654       ricSubsModCfm->protocolIEs.list.count = elementCnt;
3655       ricSubsModCfm->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationConfirm_IEs_t *);
3656       RIC_ALLOC(ricSubsModCfm->protocolIEs.list.array, ricSubsModCfm->protocolIEs.list.size);
3657       if(!ricSubsModCfm->protocolIEs.list.array)
3658       {
3659          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3660          break;
3661       }
3662
3663       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
3664       {
3665          RIC_ALLOC(ricSubsModCfm->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationConfirm_IEs_t));
3666          if(!ricSubsModCfm->protocolIEs.list.array[ieIdx])
3667          {
3668             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3669             break;
3670          }
3671       }
3672       
3673       /* RIC Request ID */
3674       ieIdx = 0;
3675       ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
3676       ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICrequestID;
3677       ricSubsModCfmIe->criticality = CriticalityE2_reject;
3678       ricSubsModCfmIe->value.present = RICsubscriptionModificationConfirm_IEs__value_PR_RICrequestID;
3679       ricSubsModCfmIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
3680       ricSubsModCfmIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
3681
3682       /* RAN Function ID */
3683       ieIdx++;
3684       ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
3685       ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RANfunctionID;
3686       ricSubsModCfmIe->criticality = CriticalityE2_reject;
3687       ricSubsModCfmIe->value.present = RICsubscriptionModificationConfirm_IEs__value_PR_RANfunctionID;
3688       ricSubsModCfmIe->value.choice.RANfunctionID = ranFuncId;
3689
3690       /* RIC Actions List confirmed for modification */
3691       if(tmpActionList.numActionModified)
3692       {
3693          ieIdx++;
3694          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
3695          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List;
3696          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
3697          ricSubsModCfmIe->value.present = \
3698             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_ConfirmedForModification_List;
3699          if(fillActionModConfirmedList(&ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List, \
3700             tmpActionList.numActionModified, tmpActionList.actionModifiedList) != ROK)
3701          {
3702             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Confirmed for Modification List", __func__);
3703             break;
3704          }
3705       }
3706
3707       /* RIC Actions List refured to be modified */
3708       if(tmpActionList.numActionModFailed)
3709       {
3710          ieIdx++;
3711          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
3712          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List;
3713          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
3714          ricSubsModCfmIe->value.present = \
3715             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_RefusedToBeModified_List;
3716          if(fillActionModRefusedList(&ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List, \
3717             tmpActionList.numActionModFailed, tmpActionList.actionModFailedList) != ROK)
3718          {
3719             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Refused to be Modified List", __func__);
3720             break;
3721          }
3722       }
3723
3724       /* RIC Actions List confirmed for removal */
3725       if(tmpActionList.numActionRemoved)
3726       {
3727          ieIdx++;
3728          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
3729          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List;
3730          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
3731          ricSubsModCfmIe->value.present = \
3732             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_ConfirmedForRemoval_List;
3733          if(fillActionRemovalConfirmedList(&ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List, \
3734             tmpActionList.numActionRemoved, tmpActionList.actionRemovedList) != ROK)
3735          {
3736             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Confirmed for Removal List", __func__);
3737             break;
3738          }
3739       }
3740
3741       /* RIC Actions List Refused to be removed */
3742       if(tmpActionList.numActionRemovalFailed)
3743       {
3744          ieIdx++;
3745          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
3746          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List;
3747          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
3748          ricSubsModCfmIe->value.present = \
3749             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_RefusedToBeRemoved_List;
3750          if(fillActionRemovalRefusedList(&ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List, \
3751             tmpActionList.numActionRemovalFailed, tmpActionList.actionRemovalFailedList) != ROK)
3752          {
3753             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Failed to be Removed List", __func__);
3754             break;
3755          }
3756       }
3757
3758       /* Print and encode E2AP Message PDU */
3759       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3760       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3761       encBufSize = 0;
3762       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3763
3764       /* Check encode results */
3765       if(encRetVal.encoded == ENCODE_FAIL)
3766       {
3767          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC subscription modification confirm (at %s)\n",\
3768                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3769          break;
3770       }
3771       else
3772       {
3773          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC subscription modification confirm\n");
3774          for(int i=0; i< encBufSize; i++)
3775          {
3776             DU_LOG("%x",encBuf[i]);
3777          }
3778       }
3779
3780       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
3781       {
3782          DU_LOG("\nERROR  -->  E2AP : Failed to send RIC Subscription Modification Confirm");
3783          break;
3784       }
3785
3786       ret =ROK;
3787       break;
3788    }
3789
3790    FreeRicSubsModConfirm(e2apMsg);
3791    return ret;
3792 }
3793
3794 /*******************************************************************
3795  *
3796  * @brief Processing of RIC Subscription Modification Required
3797  *
3798  * @details
3799  *
3800  *    Function : ProcRicSubsModReqd
3801  *
3802  * Functionality: Processing of RIC Subscription Modification Required
3803  *    As of now, we do not identify any scenario where this message
3804  *    shall be sent by DU. Hence, bare minimum handling has been
3805  *    done here.
3806  *
3807  * @param  DU ID
3808  *         RIC Subscription Modification Required IEs
3809  * @return ROK-success
3810  *         RFAILED-failure
3811  *
3812  ******************************************************************/
3813 uint8_t ProcRicSubsModReqd(uint32_t duId, RICsubscriptionModificationRequired_t *ricSubsModReqd)
3814 {
3815    uint8_t ieIdx = 0, actionIdx = 0, duIdx = 0;
3816    DuDb    *duDb = NULLP;
3817    uint16_t ranFuncId;
3818    uint16_t actionId;
3819    RicRequestId ricReqId;
3820    RanFunction *ranFuncDb = NULLP;
3821    RicSubscription *ricSubs = NULLP;
3822    CmLList *ricSubsNode = NULLP;
3823    ActionInfo *action = NULLP;
3824    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
3825    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
3826    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
3827    RICaction_RequiredToBeModified_ItemIEs_t *actionToBeMod = NULLP;
3828    RICaction_RequiredToBeRemoved_ItemIEs_t *actionToBeRmv = NULLP;
3829    RicTmpActionList tmpActionList;
3830
3831    memset(&ricReqId, 0, sizeof(RicRequestId));
3832    memset(&tmpActionList, 0, sizeof(RicTmpActionList));
3833
3834    SEARCH_DU_DB(duIdx, duId, duDb);
3835    if(duDb == NULLP)
3836    {
3837       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
3838       return RFAILED;
3839    }
3840
3841    for(ieIdx = 0; ieIdx < ricSubsModReqd->protocolIEs.list.count; ieIdx++)
3842    {
3843       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
3844       switch(ricSubsModReqdIe->id)
3845       {
3846          case ProtocolIE_IDE2_id_RICrequestID:
3847             {
3848                ricReqId.requestorId = ricSubsModReqdIe->value.choice.RICrequestID.ricRequestorID;
3849                ricReqId.instanceId = ricSubsModReqdIe->value.choice.RICrequestID.ricInstanceID;
3850                break;
3851             }
3852          case ProtocolIE_IDE2_id_RANfunctionID:
3853             {
3854                ranFuncId = ricSubsModReqdIe->value.choice.RANfunctionID;
3855                ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
3856                if(!ranFuncDb)
3857                {
3858                   /* If RIC Subscription not found, send RIC Subscription modification refuse to DU */
3859                   DU_LOG("\nERROR  -->  E2AP : ProcRicSubsModReqd: RIC Subscription not found");
3860                   BuildAndSendRicSubsModRefuse(duId, ricReqId, ranFuncId, CauseE2_PR_ricRequest, \
3861                      CauseE2RICrequest_ran_function_id_invalid);
3862                   return RFAILED;
3863                }
3864
3865                ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
3866                if(!ricSubs)
3867                {
3868                   /* If RAN Function not found, send RIC Subscription modification refuse to DU */
3869                   DU_LOG("\nERROR  -->  E2AP : ProcRicSubsModReqd: RAN Function ID [%d] not found",ranFuncId);
3870                   BuildAndSendRicSubsModRefuse(duId, ricReqId, ranFuncId, \
3871                      CauseE2_PR_ricRequest, CauseE2RICrequest_request_id_unknown);
3872                   return RFAILED; 
3873                }
3874                break;
3875             }
3876          case ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List:
3877             {
3878                actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
3879                for(actionIdx = 0; actionIdx < actionToBeModList->list.count; actionIdx++)
3880                {
3881                   actionToBeMod = (RICaction_RequiredToBeModified_ItemIEs_t *)actionToBeModList->list.array[actionIdx];
3882                   actionId = actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricActionID;
3883                   action = fetchActionInfoFromActionId(actionId, ricSubs);
3884                   if(action)
3885                   {
3886                      /* No modification required as of now, hence directly adding to the list */
3887                      tmpActionList.actionModifiedList[tmpActionList.numActionModified++] = actionId;
3888                   }
3889                   else
3890                   {
3891                      tmpActionList.actionModFailedList[tmpActionList.numActionModFailed].actionId = actionId;
3892                      tmpActionList.actionModFailedList[tmpActionList.numActionModFailed].failureType = \
3893                         CauseE2_PR_ricRequest;
3894                      tmpActionList.actionModFailedList[tmpActionList.numActionModFailed].cause = \
3895                         CauseE2RICrequest_action_not_supported;
3896                      tmpActionList.numActionModFailed++;
3897                   }
3898                }
3899                break;
3900             }
3901          case ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List:
3902             {
3903                actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
3904                for(actionIdx = 0; actionIdx < actionToBeRmvList->list.count; actionIdx++)
3905                {
3906                   actionToBeRmv = (RICaction_RequiredToBeRemoved_ItemIEs_t *)actionToBeRmvList->list.array[actionIdx];
3907                   actionId = actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.ricActionID;
3908                   action = fetchActionInfoFromActionId(actionId, ricSubs);
3909                   if(action)
3910                   {
3911                      tmpActionList.actionRemovedList[tmpActionList.numActionRemoved++] = actionId;
3912                      memset(action, 0, sizeof(ActionInfo));
3913                      action->actionId = -1;
3914                      ricSubs->numOfActions--;
3915                   }
3916                }
3917                break;
3918             }
3919          default:
3920             break;
3921       }
3922    }
3923
3924    /* If none of the action modification/removal is supported, 
3925     *   send RIC Subscription Modification Refuse
3926     * Else
3927     *   send RIC Subscription Modification Confirm
3928     */
3929    if(tmpActionList.numActionModified || tmpActionList.numActionRemoved)
3930    {
3931       BuildAndSendRicSubsModConfirm(duId, ricReqId, ranFuncId, tmpActionList);
3932    }
3933    else
3934    {
3935       BuildAndSendRicSubsModRefuse(duId, ricReqId, ranFuncId, CauseE2_PR_ricRequest, \
3936             CauseE2RICrequest_action_not_supported);
3937    }
3938    
3939    return ROK;
3940 }
3941
3942 /*******************************************************************
3943  *
3944  * @brief Free the ErrorIndication Message
3945  *
3946  * @details
3947  *
3948  *    Function : FreeRicIndication
3949  *
3950  * Functionality: Free the ErrorIndication Message
3951  *
3952  * @return void
3953  *
3954  *
3955  ******************************************************************/
3956 void FreeErrorIndication(E2AP_PDU_t  *e2apMsg)
3957 {
3958    uint8_t arrIdx = 0;
3959    ErrorIndicationE2_t *errorIndicationMsg= NULLP;
3960
3961    if(e2apMsg != NULLP)
3962    {
3963       if(e2apMsg->choice.initiatingMessage != NULLP)
3964       {
3965          errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
3966          if(errorIndicationMsg!= NULLP)
3967          {
3968             if(errorIndicationMsg->protocolIEs.list.array != NULLP)
3969             {
3970                for(arrIdx=0; arrIdx<errorIndicationMsg->protocolIEs.list.count; arrIdx++)
3971                {
3972                   RIC_FREE(errorIndicationMsg->protocolIEs.list.array[arrIdx],sizeof(ErrorIndicationE2_t));
3973                }
3974                RIC_FREE(errorIndicationMsg->protocolIEs.list.array,errorIndicationMsg->protocolIEs.list.size);
3975             }
3976          }
3977          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3978       }
3979       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3980    }
3981 }
3982
3983
3984 /*******************************************************************
3985  *
3986  * @brief Builds and Send the ErrorIndication Message
3987  *
3988  * @details
3989  *
3990  *    Function : BuildAndSendErrorIndication
3991  *
3992  * Functionality:Fills the ErrorIndication Message
3993  *
3994  * @params[in] 
3995  *    DU id
3996  *    Trans id
3997  *    Ric req id
3998  *    Ran function id
3999  *    Reason of failure
4000  * @return ROK     - success
4001  *         RFAILED - failure
4002  *
4003  ******************************************************************/
4004
4005 uint8_t BuildAndSendErrorIndication(uint32_t duId, int8_t transId, RicRequestId requestId, uint16_t ranFuncId, uint8_t reason)
4006 {
4007    uint8_t elementCnt =0, arrIdx=0, ret = RFAILED;
4008    E2AP_PDU_t         *e2apMsg = NULLP;
4009    ErrorIndicationE2_t *errorIndicationMsg=NULLP;
4010    asn_enc_rval_t     encRetVal;        /* Encoder return value */
4011
4012    while(true)
4013    {
4014       DU_LOG("\nINFO   -->  E2AP : Building Error Indication Message\n");
4015
4016       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4017       if(e2apMsg == NULLP)
4018       {
4019          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
4020          break;
4021       }
4022
4023       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4024       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4025       if(e2apMsg->choice.initiatingMessage == NULLP)
4026       {
4027          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
4028          break;
4029       }
4030       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_ErrorIndicationE2;
4031       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4032       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ErrorIndicationE2;
4033
4034       errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
4035
4036       /* Element count is 2 for TransactionID/RICrequestID and Cause.
4037        * If the RAN function id is present, the count will be increased.*/
4038       elementCnt = 2;
4039       if(ranFuncId>0)
4040          elementCnt++;
4041
4042       errorIndicationMsg->protocolIEs.list.count = elementCnt;
4043       errorIndicationMsg->protocolIEs.list.size = elementCnt * sizeof(ErrorIndicationE2_IEs_t*);
4044
4045       /* Initialize the E2Setup members */
4046       RIC_ALLOC(errorIndicationMsg->protocolIEs.list.array, errorIndicationMsg->protocolIEs.list.size);
4047       if(errorIndicationMsg->protocolIEs.list.array == NULLP)
4048       {
4049          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements in %s at line %d",__func__, __LINE__);
4050          break;
4051       }
4052       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
4053       {
4054          RIC_ALLOC(errorIndicationMsg->protocolIEs.list.array[arrIdx], sizeof(ErrorIndicationE2_IEs_t));
4055          if(errorIndicationMsg->protocolIEs.list.array[arrIdx] == NULLP)
4056          {
4057             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array Idx %d in %s at line %d",arrIdx,__func__, __LINE__);
4058             break;
4059          }
4060       }
4061       if(arrIdx < elementCnt)
4062          break;
4063
4064       arrIdx = 0;
4065
4066       if(transId >=0 && transId<=255)
4067       {
4068          /* TransactionID */
4069          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4070          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4071          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_TransactionID;
4072          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
4073       }
4074       else
4075       {
4076          /* RICrequestID */
4077          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RICrequestID;
4078          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4079          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RICrequestID;
4080          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricRequestorID = requestId.requestorId;
4081          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricInstanceID = requestId.instanceId;
4082       }
4083       
4084       if(ranFuncId>0)
4085       {
4086          /* RAN Function ID */
4087          arrIdx++;
4088          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionID;
4089          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4090          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RANfunctionID;
4091          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionID = ranFuncId;
4092       }
4093      
4094       /* Cause */
4095       arrIdx++;
4096       errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
4097       errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
4098       errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2;
4099       fillE2FailureCause(&errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, CauseE2_PR_misc, reason);
4100
4101
4102       /* Prints the Msg formed */
4103       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4104       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4105       encBufSize = 0;
4106       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4107             encBuf);
4108       if(encRetVal.encoded == ENCODE_FAIL)
4109       {
4110          DU_LOG("\nERROR  -->  E2AP : Could not encode Error Indication Message (at %s)\n",\
4111                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4112          break;
4113       }
4114       else
4115       {
4116          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for Error Indication Message \n");
4117 #ifdef DEBUG_ASN_PRINT
4118          for(int i=0; i< encBufSize; i++)
4119          {
4120             printf("%x",encBuf[i]);
4121          }
4122 #endif
4123       }
4124
4125       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
4126       {
4127          DU_LOG("\nINFO   -->  E2AP : Sending Error Indication Message");
4128
4129       }
4130       ret = ROK;
4131       break;
4132    }
4133    FreeErrorIndication(e2apMsg);
4134    return ret;
4135 }
4136
4137 /*******************************************************************
4138  *
4139  * @brief Deallocate the memory allocated for ResetRequest msg
4140  *
4141  * @details
4142  *
4143  *    Function : FreeResetRequest
4144  *
4145  *    Functionality:
4146  *       - freeing the memory allocated for ResetRequest
4147  *
4148  * @params[in] E2AP_PDU_t *e2apMsg
4149  * @return ROK     - success
4150  *         RFAILED - failure
4151  *
4152  * ****************************************************************/
4153 void FreeResetRequest(E2AP_PDU_t *e2apMsg)
4154 {
4155    uint8_t ieIdx =0;
4156    ResetRequestE2_t  *resetReq = NULLP;
4157
4158    if(e2apMsg != NULLP)
4159    {
4160       if(e2apMsg->choice.initiatingMessage != NULLP)
4161       {
4162          resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4163          if(resetReq->protocolIEs.list.array)
4164          {
4165             for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
4166             {
4167                RIC_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4168             }
4169             RIC_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4170          }
4171          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4172       }
4173       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4174    }
4175 }
4176
4177 /*******************************************************************
4178  *
4179  * @brief Build and send the reset request msg
4180  *
4181  * @details
4182  *
4183  *    Function : BuildAndSendResetRequest
4184  *
4185  *    Functionality:
4186  *         - Buld and send the reset request msg to E2 node
4187  *
4188  * @params[in]
4189  *    DU database
4190  *    Type of failure 
4191  *    Cause of failure
4192  * @return ROK     - success
4193  *         RFAILED - failure
4194  *
4195  * ****************************************************************/
4196 uint8_t BuildAndSendResetRequest(DuDb *duDb, CauseE2_PR causePresent, uint8_t reason)
4197 {
4198    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
4199    uint8_t ret = RFAILED;
4200    E2AP_PDU_t        *e2apMsg = NULLP;
4201    ResetRequestE2_t  *resetReq = NULLP;
4202    asn_enc_rval_t     encRetVal;       /* Encoder return value */
4203
4204    DU_LOG("\nINFO   -->  E2AP : Building Reset Request\n");
4205
4206    do
4207    {
4208       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4209       if(e2apMsg == NULLP)
4210       {
4211          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation for E2AP-PDU failed");
4212          break;
4213       }
4214
4215       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4216       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4217       if(e2apMsg->choice.initiatingMessage == NULLP)
4218       {
4219          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation for initiatingMessage");
4220          break;
4221       }
4222
4223       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
4224       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4225       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
4226       resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4227
4228       elementCnt = 2;
4229       resetReq->protocolIEs.list.count = elementCnt;
4230       resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
4231
4232       RIC_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4233       if(!resetReq->protocolIEs.list.array)
4234       {
4235          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation failed for \
4236                Reset Request IE array");
4237          break;
4238       }
4239
4240       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
4241       {
4242          RIC_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4243          if(!resetReq->protocolIEs.list.array[ieIdx])
4244          {
4245             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation failed for \
4246                   Reset Request IE array element");
4247             break;
4248          }
4249       }
4250
4251       /* In case of failure */
4252       if(ieIdx < elementCnt)
4253          break;
4254
4255       ieIdx = 0;
4256       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4257       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
4258       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
4259       transId = assignTransactionId(duDb);
4260       resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
4261
4262       ieIdx++;
4263       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
4264       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
4265       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
4266       fillE2FailureCause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, causePresent, reason);
4267
4268       /* Prints the Msg formed */
4269       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4270
4271       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4272       encBufSize = 0;
4273       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4274             encBuf);
4275       if(encRetVal.encoded == ENCODE_FAIL)
4276       {
4277          DU_LOG("\nERROR  -->  E2AP : Could not encode reset request structure (at %s)\n",\
4278                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4279          break;
4280       }
4281       else
4282       {
4283          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for reset request\n");
4284 #ifdef DEBUG_ASN_PRINT
4285          for(int i=0; i< encBufSize; i++)
4286          {
4287             printf("%x",encBuf[i]);
4288          }
4289 #endif
4290       }
4291       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
4292       {
4293          DU_LOG("\nERROR  -->  E2AP : Sending reset request failed");
4294          break;
4295       }
4296
4297
4298       ret = ROK;
4299       break;
4300    }while(true);
4301
4302    /* Free all memory */
4303    FreeResetRequest(e2apMsg);
4304    return ret;
4305 }
4306
4307 /******************************************************************
4308  *
4309  * @brief Delete Ric subscription node
4310  *
4311  * @details
4312  *
4313  *    Function : deleteRicSubscriptionNode
4314  *
4315  *    Functionality: Delete Ric subscription node
4316  *
4317  * @params[in] Ric subscription info
4318  *
4319  * @return void
4320  *
4321  * ****************************************************************/
4322 void deleteRicSubscriptionNode(CmLList *subscriptionNode)
4323 {
4324    uint8_t actionIdx=0;
4325    RicSubscription *ricSubscriptionInfo = NULLP;
4326
4327    ricSubscriptionInfo = (RicSubscription*)subscriptionNode->node;
4328
4329    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
4330    {
4331       if(ricSubscriptionInfo->actionSequence[actionIdx].actionId > -1)
4332       {
4333          memset(&ricSubscriptionInfo->actionSequence[actionIdx], 0, sizeof(ActionInfo));
4334       }
4335    }
4336    memset(ricSubscriptionInfo, 0, sizeof(RicSubscription));
4337    RIC_FREE(subscriptionNode->node, sizeof(RicSubscription));
4338    RIC_FREE(subscriptionNode, sizeof(CmLList));
4339 }
4340
4341 /*******************************************************************
4342  *
4343  * @brief Delete RIC subscription List
4344  *
4345  * @details
4346  *
4347  *    Function : deleteRicSubscriptionList 
4348  *
4349  * Functionality: Delete RIC subscription list
4350  *
4351  * @params[in] RIC Subscription list
4352  * @return void
4353
4354  *
4355  ******************************************************************/
4356 void deleteRicSubscriptionList(CmLListCp *subscriptionList)
4357 {
4358    CmLList *subscriptionNode = NULLP;
4359
4360    CM_LLIST_FIRST_NODE(subscriptionList, subscriptionNode);
4361    while(subscriptionNode)
4362    {
4363       cmLListDelFrm(subscriptionList, subscriptionNode);
4364       deleteRicSubscriptionNode(subscriptionNode);
4365       CM_LLIST_FIRST_NODE(subscriptionList, subscriptionNode);
4366    }
4367 }
4368
4369 /*******************************************************************
4370  *
4371  * @brief process the E2 Reset Response
4372  *
4373  * @details
4374  *
4375  *    Function : ProcResetResponse 
4376  *
4377  * Functionality: Process E2 Reset Response 
4378  *
4379  * @params[in] 
4380  *       du Id
4381  *       Pointer to reset response 
4382  * @return void
4383  *
4384  ******************************************************************/
4385
4386 void ProcResetResponse(uint32_t duId, ResetResponseE2_t *resetRsp)
4387 {
4388    uint8_t ieIdx = 0, duIdx =0;
4389    DuDb *duDb = NULLP;
4390    RanFunction *ranFuncDb = NULLP;
4391    uint16_t ranFuncIdx = 0;
4392
4393    SEARCH_DU_DB(duIdx, duId, duDb); 
4394    if(duDb == NULLP)
4395    {
4396       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
4397       return;
4398    }
4399    
4400    if(!resetRsp)
4401    {
4402       DU_LOG("\nERROR  -->  E2AP : resetRsp pointer is null"); 
4403       return;
4404    }
4405
4406    if(!resetRsp->protocolIEs.list.array)      
4407    {
4408       DU_LOG("\nERROR  -->  E2AP : resetRsp array pointer is null");
4409       return;
4410    }
4411    
4412    for(ieIdx=0; ieIdx < resetRsp->protocolIEs.list.count; ieIdx++)
4413    {
4414       if(resetRsp->protocolIEs.list.array[ieIdx])
4415       {
4416          switch(resetRsp->protocolIEs.list.array[ieIdx]->id)
4417          {
4418             case ProtocolIE_IDE2_id_TransactionID:
4419                {
4420                   for(ranFuncIdx = 0; ranFuncIdx < MAX_RAN_FUNCTION; ranFuncIdx++)
4421                   {
4422                      ranFuncDb = &duDb->ranFunction[ranFuncIdx];
4423                      if(ranFuncDb->id > 0)
4424                      {
4425                         deleteRicSubscriptionList(&ranFuncDb->subscriptionList);
4426                      }
4427                   }
4428                   break;
4429                }
4430             case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
4431                {
4432                   break;
4433                }
4434          }
4435       }
4436    }
4437 }
4438
4439
4440 /*******************************************************************
4441  *
4442  * @brief process the E2 Reset Request
4443  *
4444  * @details
4445  *
4446  *    Function : ProcResetRequest 
4447  *
4448  * Functionality: Process E2 Reset Request 
4449  *
4450  * @params[in] 
4451  *       du Id
4452  *       Pointer to reset response 
4453  * @return void
4454  *
4455  ******************************************************************/
4456
4457 void ProcResetRequest(uint32_t duId, ResetRequestE2_t *resetReq)
4458 {
4459    uint8_t ieIdx = 0, duIdx =0, transId=0;
4460    DuDb *duDb = NULLP;
4461    RanFunction *ranFuncDb = NULLP;
4462    uint16_t ranFuncIdx = 0;
4463
4464    SEARCH_DU_DB(duIdx, duId, duDb); 
4465    if(duDb == NULLP)
4466    {
4467       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
4468       return;
4469    }
4470    
4471    if(!resetReq)
4472    {
4473       DU_LOG("\nERROR  -->  E2AP : resetReq pointer is null"); 
4474       return;
4475    }
4476
4477    if(!resetReq->protocolIEs.list.array)      
4478    {
4479       DU_LOG("\nERROR  -->  E2AP : resetReq array pointer is null");
4480       return;
4481    }
4482    
4483    for(ieIdx=0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
4484    {
4485       if(resetReq->protocolIEs.list.array[ieIdx])
4486       {
4487          switch(resetReq->protocolIEs.list.array[ieIdx]->id)
4488          {
4489             case ProtocolIE_IDE2_id_TransactionID:
4490                {
4491                   transId = resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
4492                   break;
4493                }
4494             case ProtocolIE_IDE2_id_CauseE2:
4495                {
4496                   for(ranFuncIdx = 0; ranFuncIdx < MAX_RAN_FUNCTION; ranFuncIdx++)
4497                   {
4498                      ranFuncDb = &duDb->ranFunction[ranFuncIdx];
4499                      if(ranFuncDb->id > 0)
4500                      {
4501                         deleteRicSubscriptionList(&ranFuncDb->subscriptionList);
4502                      }
4503                   }
4504                   break;
4505                }
4506          }
4507       }
4508    }
4509
4510    if(BuildAndSendResetResponse(duId, transId) !=ROK)
4511    {
4512       DU_LOG("\nERROR  -->  E2AP : Failed to build and send reset response");
4513    }
4514 }
4515
4516 /*******************************************************************
4517  *
4518  * @brief Free RIC Subscription Delete Request Message
4519  *
4520  * @details
4521  *
4522  *    Function : FreeRicSubscriptionDeleteRequest
4523  *
4524  * Functionality:  Free RIC Subscription Delete Request
4525  *
4526  * @param  E2AP Message PDU
4527  * @return void
4528  *
4529  ******************************************************************/
4530 void FreeRicSubscriptionDeleteRequest(E2AP_PDU_t *e2apMsg)
4531 {
4532    uint8_t ieIdx = 0, arrIdx = 0;
4533    RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
4534
4535    if(e2apMsg)
4536    {
4537       if(e2apMsg->choice.initiatingMessage)
4538       {
4539          ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
4540          if(ricSubsDelReq->protocolIEs.list.array)
4541          {
4542             for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++)
4543             {
4544                RIC_FREE(ricSubsDelReq->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequired_IEs_t));
4545             }
4546             RIC_FREE(ricSubsDelReq->protocolIEs.list.array, ricSubsDelReq->protocolIEs.list.size);
4547          }
4548          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4549       }
4550       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));;
4551    }
4552 }
4553
4554 /*******************************************************************
4555  *
4556  * @brief Builds and Send RIC Subscription delete request
4557  *
4558  * @details
4559  *
4560  *    Function : BuildAndSendRicSubscriptionDeleteRequest
4561  *
4562  * Functionality: Build and send RIC subscription delete request.
4563  *
4564  * @params[in] DU ID
4565  *             RIC subscription info to be deleted
4566  * @return ROK     - success
4567  *         RFAILED - failure
4568  *
4569  ******************************************************************/
4570 uint8_t BuildAndSendRicSubscriptionDeleteRequest(uint32_t duId, RicSubscription *ricSubsDb)
4571 {
4572    uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED;
4573    E2AP_PDU_t         *e2apMsg = NULLP;
4574    RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
4575    RICsubscriptionDeleteRequest_IEs_t *ricSubsDelReqIe = NULLP;
4576    asn_enc_rval_t     encRetVal;        /* Encoder return value */
4577
4578    while(true)
4579    {
4580       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Delete Request Message\n");
4581
4582       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4583       if(e2apMsg == NULLP)
4584       {
4585          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
4586          break;
4587       }
4588
4589       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4590       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4591       if(e2apMsg->choice.initiatingMessage == NULLP)
4592       {
4593          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
4594          break;
4595       }
4596       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionDelete;
4597       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4598       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequest;
4599
4600       ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
4601
4602       elementCnt = 2;
4603       ricSubsDelReq->protocolIEs.list.count = elementCnt;
4604       ricSubsDelReq->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionDeleteRequest_IEs_t *);
4605
4606       RIC_ALLOC(ricSubsDelReq->protocolIEs.list.array, ricSubsDelReq->protocolIEs.list.size);
4607       if(ricSubsDelReq->protocolIEs.list.array == NULLP)
4608       {
4609          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__);
4610          break;
4611       }
4612
4613       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
4614       {
4615          RIC_ALLOC(ricSubsDelReq->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequest_IEs_t));
4616          if(ricSubsDelReq->protocolIEs.list.array[ieIdx] == NULLP)
4617          {
4618             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for index [%d] at line %d", \
4619                   __func__, ieIdx, __LINE__);
4620             break;
4621          }
4622       }
4623       if(ieIdx < elementCnt)
4624          break;
4625       
4626       /* RIC Request ID */
4627       ieIdx = 0;
4628       ricSubsDelReqIe = ricSubsDelReq->protocolIEs.list.array[ieIdx];
4629       ricSubsDelReqIe->id = ProtocolIE_IDE2_id_RICrequestID;
4630       ricSubsDelReqIe->criticality = CriticalityE2_reject;
4631       ricSubsDelReqIe->value.present = RICsubscriptionDeleteRequest_IEs__value_PR_RICrequestID;
4632       ricSubsDelReqIe->value.choice.RICrequestID.ricRequestorID = ricSubsDb->requestId.requestorId;
4633       ricSubsDelReqIe->value.choice.RICrequestID.ricInstanceID = ricSubsDb->requestId.instanceId;
4634
4635       /* RAN Function ID */
4636       ieIdx++;
4637       ricSubsDelReqIe = ricSubsDelReq->protocolIEs.list.array[ieIdx];
4638       ricSubsDelReqIe->id = ProtocolIE_IDE2_id_RANfunctionID;
4639       ricSubsDelReqIe->criticality = CriticalityE2_reject;
4640       ricSubsDelReqIe->value.present = RICsubscriptionDeleteRequest_IEs__value_PR_RANfunctionID;
4641       ricSubsDelReqIe->value.choice.RANfunctionID = ricSubsDb->ranFuncId;
4642
4643       /* Prints the Msg formed */
4644       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4645       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4646       encBufSize = 0;
4647       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
4648       if(encRetVal.encoded == ENCODE_FAIL)
4649       {
4650          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Delete Request Message (at %s)\n",\
4651                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4652          break;
4653       }
4654       else
4655       {
4656          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Delete Request Message \n");
4657 #ifdef DEBUG_ASN_PRINT
4658          for(int i=0; i< encBufSize; i++)
4659          {
4660             printf("%x",encBuf[i]);
4661          } 
4662 #endif
4663       }
4664
4665       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
4666       {
4667          DU_LOG("\nERROR   -->  E2AP : Failed to send RIC Susbcription Delete Request Message");      
4668          break;
4669       }
4670
4671       ret = ROK;
4672       break;
4673    }
4674
4675    FreeRicSubscriptionDeleteRequest(e2apMsg);  
4676    return ret;
4677 }
4678
4679 /*******************************************************************
4680  *
4681  * @brief Processing of RIC Subscription Delete Required
4682  *
4683  * @details
4684  *
4685  *    Function : ProcRicSubsDeleteReqd
4686  *
4687  * Functionality: Processing of RIC Subscription Delete Required
4688  *    When received, RIC stub will initiate the RIC subscription
4689  *    deletion procedure towards DU
4690  *
4691  * @param  DU ID
4692  *         RIC Subscription Delete Required IEs
4693  * @return ROK-success
4694  *         RFAILED-failure
4695  *
4696  ******************************************************************/
4697 uint8_t ProcRicSubsDeleteReqd(uint32_t duId, RICsubscriptionDeleteRequired_t *ricSubsDelRqd)
4698 {
4699    uint8_t ieIdx = 0, duIdx = 0;
4700    uint16_t arrIdx = 0;
4701    DuDb *duDb = NULLP;
4702    RicRequestId ricReqId;
4703    RanFunction *ranFuncDb = NULLP;
4704    RicSubscription *subsDb = NULLP;
4705    CmLList *ricSubsNode = NULLP;
4706
4707    RICsubscriptionDeleteRequired_IEs_t *ricSubsDelRqdIe = NULLP;
4708    RICsubscription_List_withCause_t *ricSubsList = NULLP;
4709    RICsubscription_withCause_Item_t *subsItem = NULLP;
4710
4711    memset(&ricReqId, 0, sizeof(RicRequestId));
4712
4713    if(!ricSubsDelRqd)
4714    {
4715       DU_LOG("\nERROR  -->  E2AP : %s: Received NULL message", __func__);
4716       return RFAILED;
4717    }
4718
4719    SEARCH_DU_DB(duIdx, duId, duDb);
4720    if(duDb == NULLP)
4721    {
4722       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
4723       return RFAILED;
4724    }
4725
4726    for(ieIdx = 0; ieIdx < ricSubsDelRqd->protocolIEs.list.count; ieIdx++)
4727    {
4728       ricSubsDelRqdIe = ricSubsDelRqd->protocolIEs.list.array[ieIdx];
4729       switch(ricSubsDelRqdIe->id)
4730       {
4731          case ProtocolIE_IDE2_id_RICsubscriptionToBeRemoved:
4732          {
4733             ricSubsList = &ricSubsDelRqdIe->value.choice.RICsubscription_List_withCause;
4734             for(arrIdx = 0; arrIdx < ricSubsList->list.count; arrIdx++)
4735             {
4736                subsItem = &(((RICsubscription_withCause_ItemIEs_t *)ricSubsList->list.array[arrIdx])->\
4737                   value.choice.RICsubscription_withCause_Item);
4738                ranFuncDb = fetchRanFuncFromRanFuncId(duDb, subsItem->ranFunctionID);
4739                if(!ranFuncDb)
4740                {
4741                   DU_LOG("\nERROR  -->  E2AP : %s: RAN Function ID [%ld] not found", __func__, subsItem->ranFunctionID);
4742                   return RFAILED;
4743                }
4744                
4745                ricReqId.requestorId = subsItem->ricRequestID.ricRequestorID;
4746                ricReqId.instanceId = subsItem->ricRequestID.ricInstanceID;
4747                subsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
4748                if(!subsDb)
4749                {
4750                   DU_LOG("\nERROR  -->  E2AP : %s: RIC Subscription not found for Requestor_ID [%ld] Instance_ID [%ld]", \
4751                      __func__, subsItem->ricRequestID.ricRequestorID, subsItem->ricRequestID.ricInstanceID);
4752                   return RFAILED;
4753                }
4754
4755                /* Delete RIC Subcription from RAN Function */
4756                cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubsNode);
4757                
4758                /* Send RIC Subscription delete request and then free any memory
4759                 * allocated to store subscription info at RIC */
4760                BuildAndSendRicSubscriptionDeleteRequest(duId, (RicSubscription *)ricSubsNode->node);
4761                deleteRicSubscriptionNode(ricSubsNode);
4762             }
4763             
4764             break;
4765          }
4766          default:
4767             break;
4768       }
4769    }  
4770    
4771    return ROK;
4772 }
4773
4774 /*******************************************************************
4775 *
4776 * @brief Handles received E2AP message and sends back response  
4777 *
4778 * @details
4779 *
4780 *    Function : E2APMsgHdlr
4781 *
4782 *    Functionality:
4783 *         - Decodes received E2AP control message
4784 *         - Prepares response message, encodes and sends to SCTP
4785 *
4786 * @params[in] 
4787 * @return ROK     - success
4788 *         RFAILED - failure
4789 *
4790 * ****************************************************************/
4791 void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
4792 {
4793    int             i;
4794    char            *recvBuf;
4795    MsgLen          copyCnt;
4796    MsgLen          recvBufLen;
4797    E2AP_PDU_t      *e2apMsg;
4798    asn_dec_rval_t  rval; /* Decoder return value */
4799    E2AP_PDU_t      e2apasnmsg ;
4800  
4801    DU_LOG("\nINFO  -->  E2AP : Received E2AP message buffer");
4802    ODU_PRINT_MSG(mBuf, 0,0);
4803  
4804    /* Copy mBuf into char array to decode it */
4805    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
4806    RIC_ALLOC(recvBuf, (Size)recvBufLen);
4807
4808    if(recvBuf == NULLP)
4809    {
4810       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
4811       return;
4812    }
4813    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
4814    {
4815       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
4816       return;
4817    }
4818
4819    DU_LOG("\nDEBUG  -->  E2AP : Received flat buffer to be decoded : ");
4820    for(i=0; i< recvBufLen; i++)
4821    {
4822         DU_LOG("%x",recvBuf[i]);
4823    }
4824
4825    /* Decoding flat buffer into E2AP messsage */
4826    e2apMsg = &e2apasnmsg;
4827    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
4828
4829    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
4830    RIC_FREE(recvBuf, (Size)recvBufLen);
4831
4832    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
4833    {
4834       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
4835       return;
4836    }
4837    DU_LOG("\n");
4838    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4839
4840    switch(e2apMsg->present)
4841    {
4842       case E2AP_PDU_PR_initiatingMessage:
4843          {
4844             switch(e2apMsg->choice.initiatingMessage->value.present)
4845             {
4846                case InitiatingMessageE2__value_PR_E2setupRequest:
4847                   {
4848                      DU_LOG("\nINFO  -->  E2AP : E2 setup request received");
4849                      ProcE2SetupReq(duId, &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest);
4850                      break;
4851                   }
4852                case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate:
4853                   {
4854                      DU_LOG("\nINFO  -->  E2AP : E2 node config update received");
4855                      ProcE2NodeConfigUpdate(*duId, &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate);
4856                      break;
4857                   }
4858                case InitiatingMessageE2__value_PR_ResetRequestE2:
4859                   {
4860                      DU_LOG("\nINFO  -->  E2AP : E2 Reset Request received");
4861                      ProcResetRequest(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2);
4862                      break;
4863                   }
4864                case InitiatingMessageE2__value_PR_RICindication:
4865                   {
4866                      DU_LOG("\nINFO  -->  E2AP : RIC Indication received");
4867                      break;
4868                   }
4869                case InitiatingMessageE2__value_PR_RICserviceUpdate:
4870                   {
4871                      DU_LOG("\nINFO  -->  E2AP : RIC Service update received");
4872                      ProcRicServiceUpdate(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate);
4873                      break;
4874                   }
4875                case InitiatingMessageE2__value_PR_RICsubscriptionModificationRequired:
4876                   {
4877                      DU_LOG("\nINFO  -->  E2AP : RIC Subscription Modification Required");
4878                      ProcRicSubsModReqd(*duId, \
4879                            &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired);
4880                      break;
4881                   }
4882                case InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequired:
4883                   {
4884                       DU_LOG("\nINFO  -->  E2AP : RIC Subscription Delete Required");
4885                       ProcRicSubsDeleteReqd(*duId, \
4886                          &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired);
4887                       break;
4888                   }
4889
4890                case InitiatingMessageE2__value_PR_ErrorIndicationE2:
4891                   {
4892                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
4893                      break;
4894                   }
4895                default:
4896                   {
4897                      DU_LOG("\nERROR  -->  E2AP : Invalid type of intiating message [%d]", \
4898                         e2apMsg->choice.initiatingMessage->value.present);
4899                      return;
4900                   }
4901             }/* End of switch(initiatingMessage) */
4902             break;
4903          }
4904       case E2AP_PDU_PR_successfulOutcome: 
4905          {
4906             switch(e2apMsg->choice.successfulOutcome->value.present)
4907             {
4908                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
4909                   {
4910                      DU_LOG("\nINFO  -->  E2AP : Reset response received");
4911                      ProcResetResponse(*duId,  &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2);
4912                      break;
4913                   }
4914                case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:  
4915                   {
4916                      ProcRicSubscriptionResponse(*duId, \
4917                         &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse);
4918                      break;
4919                   }
4920                default:
4921                   {
4922                      DU_LOG("\nERROR  -->  E2AP : Invalid type of successfulOutcome message [%d]", \
4923                         e2apMsg->choice.successfulOutcome->value.present);
4924                      return;
4925                   }
4926                   break;
4927             }
4928             break; 
4929          }
4930          case E2AP_PDU_PR_unsuccessfulOutcome:
4931          {
4932             switch(e2apMsg->choice.successfulOutcome->value.present)
4933             {
4934                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure:
4935                   {
4936                      ProcRicSubscriptionFailure(*duId, \
4937                         &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure);
4938                      break;
4939                   }
4940                default:
4941                   {
4942                      DU_LOG("\nERROR  -->  E2AP : Invalid type of unsuccessfulOutcome message [%d]", \
4943                         e2apMsg->choice.unsuccessfulOutcome->value.present);
4944                      return;
4945                   }
4946             }
4947             break;
4948          }
4949       default:
4950          {
4951             DU_LOG("\nERROR  -->  E2AP : Invalid type message type ");
4952             return;
4953          }
4954
4955    }/* End of switch(e2apMsg->present) */
4956 } /* End of E2APMsgHdlr */
4957
4958
4959 /**********************************************************************
4960   End of file
4961  **********************************************************************/