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