[Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-531] RIC Subscription Modification Required
[o-du/l2.git] / src / ric_stub / ric_e2ap_msg_hdl.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
5 #   Licensed under the Apache License, Version 2.0 (the "License");            #
6 #   you may not use this file except in compliance with the License.           #
7 #   You may obtain a copy of the License at                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
11 #   Unless required by applicable law or agreed to in writing, software        #
12 #   distributed under the License is distributed on an "AS IS" BASIS,          #
13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
14 #   See the License for the specific language governing permissions and        #
15 #   limitations under the License.                                             #
16 ################################################################################
17 *******************************************************************************/
18
19 /* This file contains E2AP message handler functions */
20 #include "common_def.h"
21 #include "OCTET_STRING.h"
22 #include "BIT_STRING.h"
23 #include "odu_common_codec.h"
24 #include "ric_stub_sctp.h"
25 #include "ric_stub.h"
26 #include "ric_e2ap_msg_hdl.h"
27 #include "GlobalE2node-gNB-ID.h"
28 #include "ProtocolIE-FieldE2.h"
29 #include "InitiatingMessageE2.h"
30 #include "SuccessfulOutcomeE2.h"
31 #include "UnsuccessfulOutcomeE2.h"
32 #include "E2AP-PDU.h"
33 #include "du_log.h"
34 #include "E2nodeComponentInterfaceF1.h"
35 #include "E2SM-KPM-RANfunction-Description.h"
36 #include "RANfunction-Name.h"
37 #include "RIC-EventTriggerStyle-Item.h"
38 #include "RIC-ReportStyle-Item.h"
39 #include "MeasurementInfo-Action-Item.h"
40 #include "MeasurementInfoItem.h"
41 #include "E2SM-KPM-ActionDefinition-Format1.h"
42 #include "E2SM-KPM-ActionDefinition.h"
43 #include "E2SM-KPM-EventTriggerDefinition-Format1.h"
44 #include "E2SM-KPM-EventTriggerDefinition.h"
45
46
47 /*******************************************************************
48  *
49  * @brief Assigns new transaction id to RIC initiated procedure
50  *
51  * @details
52  *
53  *    Function : assignTransactionId
54  *
55  *    Functionality: Assigns new transaction id to a RIC initiated
56  *       procedure
57  *
58  * @params[in] Region region
59  *             Pool pool
60  * @return ROK     - success
61  *         RFAILED - failure
62  *
63  * ****************************************************************/
64
65 uint8_t assignTransactionId(DuDb *duDb)
66 {
67    uint8_t currTransId = duDb->ricTransIdCounter;
68
69    /* Update to next valid value */
70    duDb->ricTransIdCounter++;
71    if(duDb->ricTransIdCounter == MAX_NUM_TRANSACTION)
72       duDb->ricTransIdCounter = 0;
73
74    return currTransId;
75 }
76
77 /*******************************************************************
78 *
79 * @brief Sends E2 msg over SCTP
80 *
81 * @details
82 *
83 *    Function : SendE2APMsg
84 *
85 *    Functionality: Sends E2 msg over SCTP
86 *
87 * @params[in] Region region
88 *             Pool pool
89 * @return ROK     - success
90 *         RFAILED - failure
91 *
92 * ****************************************************************/
93
94 uint8_t SendE2APMsg(Region region, Pool pool, uint32_t duId)
95 {
96    Buffer *mBuf;
97
98    if(ODU_GET_MSG_BUF(region, pool, &mBuf) == ROK)
99    {
100       if(ODU_ADD_POST_MSG_MULT((Data *)encBuf, encBufSize, mBuf) == ROK)
101       {
102          ODU_PRINT_MSG(mBuf, 0,0);
103
104          if(sctpSend(duId, mBuf) != ROK)
105          {
106             DU_LOG("\nERROR  -->  E2AP : SCTP Send for E2  failed");
107             ODU_PUT_MSG_BUF(mBuf);
108             return RFAILED;
109          }
110       }
111       else
112       {
113          DU_LOG("\nERROR  -->  E2AP : ODU_ADD_POST_MSG_MULT failed");
114          ODU_PUT_MSG_BUF(mBuf);
115          return RFAILED;
116       }
117       ODU_PUT_MSG_BUF(mBuf);
118    }
119    else
120    {
121       DU_LOG("\nERROR  -->  E2AP : Failed to allocate memory");
122       return RFAILED;
123    }
124
125    return ROK;
126 } /* SendE2APMsg */
127
128 /*******************************************************************
129  *
130  * @brief Fetches RAN Function DB
131  *
132  * @details
133  *
134  *    Function : fetchRanFuncFromRanFuncId
135  *
136  *    Functionality: Fetches RAN function DB from E2AP DB using
137  *       RAN function ID
138  *
139  * @params[in] RAN Function ID
140  * @return RAN Function DB
141  *         NULL, in case of failure
142  *
143  * ****************************************************************/
144 RanFunction *fetchRanFuncFromRanFuncId(DuDb *duDb, uint16_t ranFuncId)
145 {
146    RanFunction *ranFuncDb = NULLP;
147
148    /* Fetch RAN Function DB */
149    if(duDb->ranFunction[ranFuncId-1].id == ranFuncId)
150    {
151       ranFuncDb = &duDb->ranFunction[ranFuncId-1];
152    }
153    else
154    {
155       DU_LOG("\nERROR  -->  DU_APP : fetchRanFuncFromRanFuncId: Invalid RAN Function ID[%d]", ranFuncId);
156    }
157
158    return ranFuncDb;
159 }
160
161 /*******************************************************************
162  *
163  * @brief Fetch subscripton DB
164  *
165  * @details
166  *
167  *    Function : fetchSubsInfoFromRicReqId
168  *
169  *    Functionality: Fetches subscription DB from RAN Function DB
170  *       using RIC Request ID
171  *
172  * @params[in] RIC Request ID
173  *             RAN Function DB
174  *             Pointer to RIC Subscription node to be searched
175  * @return RIC Subscription from RAN Function's subcription list
176  *         NULL, in case of failure
177  *
178  * ****************************************************************/
179 RicSubscription *fetchSubsInfoFromRicReqId(RicRequestId ricReqId, RanFunction *ranFuncDb)
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;
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 E2 Reset Response msg
1996  *
1997  * @details
1998  *
1999  *    Function : BuildAndSendE2ResetResponse
2000  *
2001  *    Functionality:
2002  *         - Buld and send the E2 Reset Response Message
2003  * @return ROK     - success
2004  *         RFAILED - failure
2005  *
2006  * ****************************************************************/
2007 uint8_t BuildAndSendResetResponse(uint32_t duId, uint8_t transId)
2008 {
2009    uint8_t           ieIdx = 0, elementCnt = 0;
2010    uint8_t           ret = RFAILED;
2011    E2AP_PDU_t        *e2apMsg = NULLP;
2012    ResetResponseE2_t *resetResponse;
2013    asn_enc_rval_t    encRetVal;       /* Encoder return value */
2014
2015    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
2016    do
2017    {
2018       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2019       if(e2apMsg == NULLP)
2020       {
2021          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
2022          break;
2023       }
2024       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
2025
2026       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2027       if(e2apMsg->choice.successfulOutcome == NULLP)
2028       {
2029          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
2030          break;
2031       }
2032  
2033       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
2034       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
2035       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
2036       resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
2037
2038       elementCnt = 1;
2039       resetResponse->protocolIEs.list.count = elementCnt;
2040       resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
2041       RIC_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
2042       if(!resetResponse->protocolIEs.list.array)
2043       {
2044          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
2045          break;
2046       }
2047
2048       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
2049       {
2050          RIC_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
2051          if(!resetResponse->protocolIEs.list.array[ieIdx])
2052          {
2053             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
2054             break;
2055          }
2056       }
2057       if(ieIdx < elementCnt)
2058          break;
2059
2060       ieIdx = 0; 
2061       resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
2062       resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
2063       resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
2064       resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
2065
2066       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2067
2068       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2069       encBufSize = 0;
2070       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2071       if(encRetVal.encoded == ENCODE_FAIL)
2072       {
2073          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
2074                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2075          break;
2076       }
2077       else
2078       {
2079          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
2080          for(int i=0; i< encBufSize; i++)
2081          {
2082             DU_LOG("%x",encBuf[i]);
2083          }
2084       }
2085
2086       /* Sending msg */
2087       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
2088       {
2089          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
2090          break;
2091       }
2092
2093       ret = ROK;
2094       break;
2095    }while(true);
2096
2097    FreeE2ResetResponse(e2apMsg);
2098    return ret;
2099 }
2100
2101 /*******************************************************************
2102  *
2103  * @brief process the E2 Reset Request
2104  *
2105  * @details
2106  *
2107  *    Function : ProcE2ResetReq
2108  *
2109  * Functionality: Process E2 Reset Request
2110  *
2111  * @return ROK     - success
2112  *         RFAILED - failure
2113  *
2114  ******************************************************************/
2115
2116 uint8_t ProcE2ResetReq(uint32_t duId, ResetRequestE2_t  *resetReq)
2117 {
2118    uint8_t ieIdx = 0;
2119    uint8_t transId = 0, cause = 0;
2120
2121    if(resetReq)
2122    {
2123       if(resetReq->protocolIEs.list.array)
2124       {
2125          for(ieIdx=0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
2126          {
2127             if(resetReq->protocolIEs.list.array[ieIdx])
2128             {
2129                switch(resetReq->protocolIEs.list.array[ieIdx]->id)
2130                {
2131                   case ProtocolIE_IDE2_id_TransactionID:
2132                      transId = resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
2133                      break;
2134                   case ProtocolIE_IDE2_id_CauseE2:
2135                      DU_LOG("\nDEBUG  -->  E2AP : Reset reason %d", resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present);
2136                      switch(resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present)
2137                      {
2138                         case CauseE2_PR_NOTHING:
2139                            break;
2140                         case CauseE2_PR_ricRequest:
2141                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricRequest;
2142                            break;
2143                         case CauseE2_PR_ricService:
2144                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricService;
2145                            break;
2146                         case CauseE2_PR_e2Node:
2147                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.e2Node;
2148                            break;
2149                         case CauseE2_PR_transport:
2150                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.transport;
2151                            break;
2152                         case CauseE2_PR_protocol:
2153                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.protocol;
2154                            break;
2155                         case CauseE2_PR_misc:
2156                            cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.misc;
2157                            break;
2158                      }
2159                      DU_LOG("\nDEBUG  -->  E2AP : Reset cause %d", cause);
2160                      break;
2161                }
2162             }
2163          }
2164       }
2165    }
2166    BuildAndSendResetResponse(duId, transId);
2167    return ROK;
2168 }
2169
2170 /*******************************************************************
2171  *
2172  * @brief deallocate the memory allocated in building the
2173  *    Service Query message
2174  *
2175  * @details
2176  *
2177  *    Function : FreeRicServiceQuery 
2178  *
2179  *    Functionality: deallocate the memory allocated in building
2180  *    Ric Service Query message
2181  *
2182  * @params[in] E2AP_PDU_t *e2apMsg
2183  *
2184  * @return void
2185  * ****************************************************************/
2186
2187 void FreeRicServiceQuery(E2AP_PDU_t *e2apMsg)
2188 {
2189    uint8_t arrIdx = 0, ranFuncIdx=0;
2190    RANfunctionsID_List_t *ranFuncAcceptedList=NULL;
2191    RICserviceQuery_t *ricServiceQuery=NULL;
2192    
2193    if(e2apMsg)
2194    {
2195       if(e2apMsg->choice.initiatingMessage)
2196       {
2197          ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
2198          if(ricServiceQuery->protocolIEs.list.array)
2199          {
2200             for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
2201             {
2202                if(ricServiceQuery->protocolIEs.list.array[arrIdx])
2203                {
2204                   switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
2205                   {
2206                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
2207                         {
2208                            ranFuncAcceptedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
2209                            if(ranFuncAcceptedList->list.array)
2210                            {
2211                               for(ranFuncIdx=0;ranFuncIdx<ranFuncAcceptedList->list.count; ranFuncIdx++)
2212                               {
2213                                  RIC_FREE(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
2214                               }
2215                               RIC_FREE(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
2216                            }
2217                            break;
2218                         }
2219                      case RICserviceQuery_IEs__value_PR_TransactionID:
2220                         {
2221                            break;
2222                         }
2223                   }
2224                   RIC_FREE(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t)); 
2225                }
2226             }
2227             RIC_FREE(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
2228          }
2229          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2230       }
2231       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2232    }
2233 }
2234
2235 /*******************************************************************
2236  *
2237  * @brief build and send the ric service Query 
2238  *
2239  * @details
2240  *
2241  *    Function : BuildAndSendRicServiceQuery
2242  *
2243  * Functionality: build and send the ric service Query 
2244  * @return ROK     - success
2245  *         RFAILED - Acknowledge
2246  *
2247  ******************************************************************/
2248
2249 uint8_t BuildAndSendRicServiceQuery(DuDb *duDb)
2250 {
2251    uint8_t arrIdx;
2252    uint8_t elementCnt;
2253    uint8_t ret = RFAILED;
2254    bool  memAllocFailed = false;
2255    E2AP_PDU_t     *e2apMsg = NULL;
2256    asn_enc_rval_t encRetVal;
2257    RICserviceQuery_t *ricServiceQuery;
2258
2259    DU_LOG("\nINFO   -->  E2AP : Building Ric service Query\n");
2260    while(true)
2261    {
2262       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2263       if(e2apMsg == NULLP)
2264       {
2265          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2266          break;
2267       }
2268       e2apMsg->present =  E2AP_PDU_PR_initiatingMessage;
2269       RIC_ALLOC(e2apMsg->choice.initiatingMessage , sizeof(struct InitiatingMessageE2));
2270       if(e2apMsg->choice.initiatingMessage == NULLP)
2271       {
2272          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2273          break;
2274       }
2275
2276       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceQuery;
2277       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2278       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceQuery;
2279       ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
2280
2281       elementCnt = 1;
2282       /* Fill Accepted RAN function IE If Ran function information is stored in databse */
2283       if(duDb->numOfRanFunction)
2284          elementCnt++;
2285
2286       ricServiceQuery->protocolIEs.list.count = elementCnt;
2287       ricServiceQuery->protocolIEs.list.size  = elementCnt * sizeof(RICserviceQuery_IEs_t*);
2288
2289       RIC_ALLOC(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
2290       if(ricServiceQuery->protocolIEs.list.array == NULLP)
2291       {
2292          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2293          break;
2294       }
2295
2296       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2297       {
2298          RIC_ALLOC(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t));
2299          if(ricServiceQuery->protocolIEs.list.array[arrIdx] == NULLP)
2300          {
2301             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2302             memAllocFailed = true;
2303             break;
2304          }
2305       }
2306       if(memAllocFailed == true)
2307       {
2308          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2309          break;
2310       }
2311
2312       /* Trans Id */
2313       arrIdx = 0;
2314       ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2315       ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2316       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_TransactionID;
2317       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = assignTransactionId(duDb);
2318       
2319       if(duDb->numOfRanFunction)
2320       {
2321          /* Accepted RAN function Id */
2322          arrIdx++;
2323          ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
2324          ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2325          ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_RANfunctionsID_List;
2326          if(BuildRanFunctionAcceptedList(duDb, 0, NULL, &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceQuery)!=ROK)
2327          {
2328             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
2329             break;         
2330          }
2331       }
2332       
2333       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2334       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2335       encBufSize = 0;
2336       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2337
2338       /* Check encode results */
2339       if(encRetVal.encoded == ENCODE_FAIL)
2340       {
2341          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service Query structure (at %s)\n",\
2342                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2343          break;
2344       }
2345       else
2346       {
2347          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service Query\n");
2348          for(int i=0; i< encBufSize; i++)
2349          {
2350             DU_LOG("%x",encBuf[i]);
2351          }
2352       }
2353
2354       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
2355       {
2356          DU_LOG("\nERROR  -->  E2AP : Sending of RIC service  Query failed");
2357          break;
2358       }
2359
2360       ret =ROK;
2361       break;
2362    }
2363    FreeRicServiceQuery(e2apMsg);
2364    return ret;
2365 }
2366
2367 /*******************************************************************
2368  *
2369  * @brief deallocate the memory allocated in RicServiceUpdateFailure
2370  *
2371  * @details
2372  *
2373  *    Function : FreeRicServiceUpdateFailure 
2374  *
2375  *    Functionality: deallocate the memory allocated in RicServiceUpdatefailure
2376  *
2377  * @params[in] E2AP_PDU_t *e2apMsg
2378  *
2379  * @return void
2380  * ****************************************************************/
2381
2382 void FreeRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
2383 {
2384    uint8_t arrIdx = 0;
2385    RICserviceUpdateFailure_t *ricServiceUpdateFailure=NULL;
2386    
2387    if(e2apMsg)
2388    {
2389       if(e2apMsg->choice.unsuccessfulOutcome)
2390       {
2391          ricServiceUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
2392          if(ricServiceUpdateFailure->protocolIEs.list.array)
2393          {
2394             for(arrIdx=0; arrIdx<ricServiceUpdateFailure->protocolIEs.list.count; arrIdx++)
2395             {
2396                RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t)); 
2397             }
2398             RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array, ricServiceUpdateFailure->protocolIEs.list.size);
2399          }
2400          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
2401       }
2402       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2403    }
2404 }
2405
2406 /*******************************************************************
2407  *
2408  * @brief fill E2 failure cause 
2409  *
2410  * @details
2411  *
2412  *    Function : fillE2FailureCause
2413  *
2414  * Functionality: fill E2 failure cause
2415  * @return ROK     - success
2416  *         RFAILED - failure
2417  *
2418  ******************************************************************/
2419
2420 void fillE2FailureCause(CauseE2_t *cause, CauseE2_PR causePresent, uint8_t reason)
2421 {
2422    cause->present = causePresent;
2423
2424    switch(cause->present)
2425    {
2426       case CauseE2_PR_ricRequest:
2427          cause->choice.ricRequest = reason;
2428          break;
2429       case CauseE2_PR_ricService:
2430          cause->choice.ricService = reason;
2431          break;
2432       case CauseE2_PR_e2Node:
2433          cause->choice.e2Node = reason;
2434          break;
2435       case CauseE2_PR_transport:
2436          cause->choice.transport = reason;
2437          break;
2438       case CauseE2_PR_protocol:
2439          cause->choice.protocol = reason;
2440          break;
2441       case CauseE2_PR_misc:
2442          cause->choice.misc = reason;
2443          break;
2444       default:
2445          cause->choice.misc = CauseE2Misc_unspecified;
2446          break;
2447    }
2448 }
2449
2450 /*******************************************************************
2451  *
2452  * @brief build and send the ric service update failure 
2453  *
2454  * @details
2455  *
2456  *    Function : BuildAndSendRicServiceUpdateFailure
2457  *
2458  * Functionality: build and send the ric service update failure 
2459  * @return ROK     - success
2460  *         RFAILED - failure
2461  *
2462  ******************************************************************/
2463
2464 uint8_t BuildAndSendRicServiceUpdateFailure(uint32_t duId, int8_t transId, CauseE2_PR causePresent, uint8_t reason)
2465 {
2466
2467    E2AP_PDU_t         *e2apMsg = NULL;
2468    asn_enc_rval_t     encRetVal;
2469    uint8_t            ret = RFAILED;
2470    uint8_t            arrIdx=0;
2471    uint8_t            elementCnt=0;
2472    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
2473
2474    DU_LOG("\nINFO   -->  E2AP : Building Ric service update failure\n");
2475    while(true)
2476    {
2477       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2478       if(e2apMsg == NULLP)
2479       {
2480          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2481          break;
2482       }
2483       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
2484       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
2485       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
2486       {
2487          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2488          break;
2489       }
2490
2491       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
2492       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
2493       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure;
2494       ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
2495
2496       elementCnt = 3;
2497       ricServiceFailure->protocolIEs.list.count = elementCnt;
2498       ricServiceFailure->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateFailure_IEs_t *);
2499
2500       RIC_ALLOC(ricServiceFailure->protocolIEs.list.array, ricServiceFailure->protocolIEs.list.size);
2501       if(ricServiceFailure->protocolIEs.list.array == NULLP)
2502       {
2503          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2504          break;
2505       }
2506
2507       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2508       {
2509          RIC_ALLOC(ricServiceFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t));
2510          if(ricServiceFailure->protocolIEs.list.array[arrIdx] == NULLP)
2511          {
2512             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2513             break;
2514          }
2515       }
2516       if(arrIdx<elementCnt)
2517       {
2518          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2519          break;
2520       }
2521
2522       /* Trans Id */
2523       arrIdx = 0;
2524       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2525       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2526       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TransactionID;
2527       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
2528
2529       arrIdx++;
2530       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
2531       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2532       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_CauseE2;
2533       fillE2FailureCause(&ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, causePresent, reason);
2534
2535       arrIdx++;
2536       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
2537       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
2538       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TimeToWaitE2;
2539       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
2540
2541       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2542       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2543       encBufSize = 0;
2544       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2545
2546       /* Check encode results */
2547       if(encRetVal.encoded == ENCODE_FAIL)
2548       {
2549          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update failure structure (at %s)\n",\
2550                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2551          break;
2552       }
2553       else
2554       {
2555          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Failure\n");
2556          for(int i=0; i< encBufSize; i++)
2557          {
2558             DU_LOG("%x",encBuf[i]);
2559          }
2560       }
2561
2562       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
2563       {
2564          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update failed");
2565          break;
2566       }
2567       ret = ROK;
2568       break;
2569    }
2570
2571    FreeRicServiceUpdateFailure(e2apMsg);
2572    return ret;
2573 }
2574
2575
2576 /*******************************************************************
2577  *
2578  * @brief deallocate the memory allocated in RicServiceUpdateAck(
2579  *
2580  * @details
2581  *
2582  *    Function : FreeRicServiceUpdateAck 
2583  *
2584  *    Functionality: deallocate the memory allocated in RicServiceUpdateAck
2585  *
2586  * @params[in] E2AP_PDU_t *e2apMsg
2587  *
2588  * @return void
2589  * ****************************************************************/
2590
2591 void FreeRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
2592 {
2593    uint8_t arrIdx = 0, ranFuncIdx=0;
2594    RANfunctionsID_List_t *acceptedList=NULL;
2595    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
2596    RANfunctionsIDcause_List_t  *rejectedList=NULL;
2597
2598    if(e2apMsg)
2599    {
2600       if(e2apMsg->choice.successfulOutcome)
2601       {
2602          ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
2603          if(ricServiceUpdateAck->protocolIEs.list.array)
2604          {
2605             for(arrIdx=0; arrIdx<ricServiceUpdateAck->protocolIEs.list.count; arrIdx++)
2606             {
2607                if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx])
2608                {
2609                   switch(ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id)
2610                   {
2611                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
2612                         {
2613                            acceptedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
2614                            if(acceptedList->list.array)
2615                            {
2616                               for(ranFuncIdx=0;ranFuncIdx<acceptedList->list.count; ranFuncIdx++)
2617                               {
2618                                  RIC_FREE(acceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
2619                               }
2620                               RIC_FREE(acceptedList->list.array, acceptedList->list.size);
2621                            }
2622                            break;
2623                         }
2624
2625                      case ProtocolIE_IDE2_id_RANfunctionsRejected:
2626                         {
2627                            rejectedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
2628                            if(rejectedList->list.array)
2629                            {
2630                               for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
2631                               {
2632                                  RIC_FREE(rejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
2633                               }
2634                               RIC_FREE(rejectedList->list.array, rejectedList->list.size);
2635                            }
2636                            break;
2637                         }
2638                   }
2639                   RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t)); 
2640                }
2641             }
2642             RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
2643          }
2644          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2645       }
2646       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2647    }
2648 }
2649
2650 /*******************************************************************
2651  *
2652  * @brief Build RAN function rejected list
2653  *
2654  * @details
2655  *
2656  *    Function : BuildRanFunctionRejectedList
2657  *
2658  *    Functionality: Build RAN function rejected list 
2659  *
2660  * @params[in] 
2661  *    Count of ran functions to be rejected in the list 
2662  *    Received list of RAN functions
2663  *
2664  * @return ROK - success
2665  *         RFAILED - failure
2666  * ****************************************************************/
2667
2668 uint8_t BuildRanFunctionRejectedList(uint8_t count, RanFunction *ranFunRejectedList, RANfunctionsIDcause_List_t *ranFuncRejectedList)
2669 {
2670    uint8_t ranFuncIdx = 0;
2671    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
2672    
2673    ranFuncRejectedList->list.count = count;
2674    
2675    ranFuncRejectedList->list.size = ranFuncRejectedList->list.count*sizeof(RANfunctionIDcause_ItemIEs_t*);
2676    RIC_ALLOC(ranFuncRejectedList->list.array, ranFuncRejectedList->list.size);
2677    if(ranFuncRejectedList->list.array == NULLP)
2678    {
2679       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array");
2680       return RFAILED;
2681    }
2682    
2683    for(ranFuncIdx = 0; ranFuncIdx< ranFuncRejectedList->list.count; ranFuncIdx++)
2684    {
2685       RIC_ALLOC(ranFuncRejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
2686       if(ranFuncRejectedList->list.array[ranFuncIdx] == NULLP)
2687       {
2688          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array item");
2689          return RFAILED;
2690       }
2691       ranFuncRejectedItemIe = (RANfunctionIDcause_ItemIEs_t*)ranFuncRejectedList->list.array[ranFuncIdx];
2692       ranFuncRejectedItemIe->id = ProtocolIE_IDE2_id_RANfunctionIEcause_Item;
2693       ranFuncRejectedItemIe->criticality= CriticalityE2_ignore;
2694       ranFuncRejectedItemIe->value.present = RANfunctionIDcause_ItemIEs__value_PR_RANfunctionIDcause_Item;
2695       ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID = ranFunRejectedList[ranFuncIdx].id;
2696       fillE2FailureCause(&ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.cause, CauseE2_PR_ricService,\
2697             CauseE2RICservice_ran_function_not_supported);
2698    }
2699    
2700    return ROK;
2701 }
2702
2703 /*******************************************************************
2704  *
2705  * @brief build and send the ric service update Acknowledge 
2706  *
2707  * @details
2708  *
2709  *    Function : BuildAndSendRicServiceUpdateAcknowledge
2710  *
2711  * Functionality: build and send the ric service update Acknowledge 
2712  * @return ROK     - success
2713  *         RFAILED - Acknowledge
2714  *
2715  ******************************************************************/
2716
2717 uint8_t BuildAndSendRicServiceUpdateAcknowledge(DuDb *duDb, int8_t transId, RicTmpRanFunList ricRanFuncList)
2718 {
2719    E2AP_PDU_t         *e2apMsg = NULL;
2720    asn_enc_rval_t     encRetVal;
2721    uint8_t  arrIdx=0, elementCnt=0, ret=RFAILED;;
2722    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
2723
2724    DU_LOG("\nINFO   -->  E2AP : Building Ric service update Acknowledge\n");
2725    while(true)
2726    {
2727       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2728       if(e2apMsg == NULLP)
2729       {
2730          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2731          break;
2732       }
2733       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
2734       RIC_ALLOC(e2apMsg->choice.successfulOutcome , sizeof(struct SuccessfulOutcomeE2));
2735       if(e2apMsg->choice.successfulOutcome == NULLP)
2736       {
2737          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2738          break;
2739       }
2740
2741       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
2742       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
2743       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge;
2744       ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
2745
2746       elementCnt = 1;
2747       if(ricRanFuncList.numOfRanFunAccepted)
2748          elementCnt++;
2749       if(ricRanFuncList.numOfRanFuneRejected)
2750          elementCnt++;
2751       
2752
2753       ricServiceUpdateAck->protocolIEs.list.count = elementCnt;
2754       ricServiceUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateAcknowledge_IEs_t*);
2755
2756       RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
2757       if(ricServiceUpdateAck->protocolIEs.list.array == NULLP)
2758       {
2759          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2760          break;
2761       }
2762
2763       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2764       {
2765          RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t));
2766          if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
2767          {
2768             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2769             break;
2770          }
2771       }
2772       if(arrIdx<elementCnt)
2773       {
2774          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
2775          break;
2776       }
2777
2778       /* Trans Id */
2779       arrIdx = 0;
2780       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2781       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2782       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_TransactionID;
2783       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
2784
2785       if(ricRanFuncList.numOfRanFunAccepted)
2786       {
2787          /* Accepted RAN function List */
2788          arrIdx++;
2789          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
2790          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2791          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsID_List;
2792          if(BuildRanFunctionAcceptedList(duDb, ricRanFuncList.numOfRanFunAccepted, ricRanFuncList.ranFunAcceptedList,\
2793          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceUpdate)!=ROK)       
2794          {
2795             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
2796             break;         
2797          }
2798       }
2799       
2800       if(ricRanFuncList.numOfRanFuneRejected)
2801       {
2802          /* RAN Functions Rejected List */
2803          arrIdx++;
2804          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsRejected;
2805          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2806          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsIDcause_List;
2807          if(BuildRanFunctionRejectedList(ricRanFuncList.numOfRanFuneRejected, ricRanFuncList.ranFunRejectedList, \
2808          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List)!=ROK)       
2809          {
2810             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function rejected list");
2811             break;         
2812          }
2813       }
2814       
2815       
2816       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2817       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2818       encBufSize = 0;
2819       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2820
2821       /* Check encode results */
2822       if(encRetVal.encoded == ENCODE_FAIL)
2823       {
2824          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update Acknowledge structure (at %s)\n",\
2825                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2826          break;
2827       }
2828       else
2829       {
2830          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Acknowledge\n");
2831          for(int i=0; i< encBufSize; i++)
2832          {
2833             DU_LOG("%x",encBuf[i]);
2834          }
2835       }
2836
2837       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
2838       {
2839          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update ack failed");
2840          break;
2841       }
2842       ret =ROK;
2843       break;
2844    }
2845    FreeRicServiceUpdateAck(e2apMsg);
2846    return ret; 
2847 }
2848
2849 /*******************************************************************
2850  *
2851  * @brief process the RIC service update 
2852  *
2853  * @details
2854  *
2855  *    Function : ProcRicserviceUpdate 
2856  *
2857  * Functionality: process the RIC service update 
2858  *
2859  * @return ROK     - success
2860  *         RFAILED - failure
2861  *
2862  ******************************************************************/
2863
2864 void ProcRicServiceUpdate(uint32_t duId, RICserviceUpdate_t *ricServiceUpdate)
2865 {
2866    RicTmpRanFunList ricRanFuncList;
2867    DuDb    *duDb = NULLP;
2868    int8_t transId =-1;
2869    uint8_t duIdx = 0, elementCnt =0, arrIdx = 0; 
2870    uint16_t ranFuncIdx = 0, failedRanFuncCount=0, recvdRanFuncCount=0;
2871    RanFunction *ranFuncDb = NULLP;
2872    RANfunction_ItemIEs_t *ranFuncItemIe =NULL;
2873    RANfunction_Item_t  *ranFuncItem =NULL;
2874    RANfunctionID_Item_t  *ranFuncIdItem=NULL;
2875    RANfunctions_List_t *ranFuncList=NULL;
2876    RANfunctionsID_List_t *deleteList=NULL;
2877    RANfunctionID_ItemIEs_t *delRanFuncItem=NULL;
2878
2879    SEARCH_DU_DB(duIdx, duId, duDb); 
2880    if(duDb == NULLP)
2881    {
2882       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
2883       return;
2884    }
2885    memset(&ricRanFuncList, 0, sizeof(RicTmpRanFunList)); 
2886
2887    if(!ricServiceUpdate)
2888    {
2889       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate pointer is null"); 
2890       return;
2891    }
2892
2893    if(!ricServiceUpdate->protocolIEs.list.array)      
2894    {
2895       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array pointer is null");
2896       return;
2897    }
2898    elementCnt = ricServiceUpdate->protocolIEs.list.count;
2899    for(arrIdx=0; arrIdx<ricServiceUpdate->protocolIEs.list.count; arrIdx++)
2900    {
2901       if(!ricServiceUpdate->protocolIEs.list.array[arrIdx])
2902       {
2903          DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array idx %d pointer is null",arrIdx);
2904          return;
2905       }
2906
2907       switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
2908       {
2909          case ProtocolIE_IDE2_id_TransactionID:
2910             {
2911                transId = ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
2912
2913                if(transId < 0 || transId > 255)
2914                {
2915                   DU_LOG("\nERROR  -->  E2AP : Received invalid transId %d",transId);
2916                   return;
2917                }
2918                break;
2919             }
2920
2921          case ProtocolIE_IDE2_id_RANfunctionsAdded:
2922             {
2923                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
2924
2925                if(ranFuncList->list.array)
2926                {
2927                   for(ranFuncIdx=0;ranFuncIdx<ranFuncList->list.count; ranFuncIdx++)
2928                   {
2929                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx]; 
2930                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
2931
2932                      /* Adding the ran function in temporary list */
2933                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
2934                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
2935                      ricRanFuncList.numOfRanFunAccepted++;
2936
2937                      /* Adding the new ran function in DB*/
2938                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].id = ranFuncItem->ranFunctionID;
2939                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
2940                      duDb->numOfRanFunction++;
2941
2942                      /* Calculating total number of ran fuctions which are received for addition */
2943                      recvdRanFuncCount++;
2944                   }
2945                }
2946                break;
2947             }
2948
2949          case ProtocolIE_IDE2_id_RANfunctionsModified:
2950             {
2951
2952                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List; 
2953                if(ranFuncList->list.array)
2954                {
2955                   for(ranFuncIdx = 0; ranFuncIdx< ranFuncList->list.count; ranFuncIdx++)
2956                   {
2957                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx];
2958                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
2959                      if(fetchRanFuncFromRanFuncId(duDb, ranFuncItem->ranFunctionID) == NULLP)
2960                      {
2961                         /* Calculating total number of ran fuctions which are not present */
2962                         failedRanFuncCount++;
2963
2964                         /* Adding the ran function in temporary list */
2965                         ricRanFuncList.ranFunRejectedList[ricRanFuncList.numOfRanFuneRejected].id =  ranFuncItem->ranFunctionID; 
2966                         ricRanFuncList.numOfRanFuneRejected++;
2967                      }
2968                      else
2969                      {
2970
2971                         /* Adding the ran function in temporary list */
2972                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
2973                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
2974                         ricRanFuncList.numOfRanFunAccepted++;
2975
2976                         /* Updating the new ran function in DB*/
2977                         duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
2978                      }
2979                      /* Calculating total number of ran fuctions which are received for modification */
2980                      recvdRanFuncCount++;
2981                   }
2982                }
2983                break;
2984             }
2985          case ProtocolIE_IDE2_id_RANfunctionsDeleted:
2986             {
2987
2988                deleteList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List; 
2989                if(deleteList->list.array)
2990                {
2991                   for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
2992                   {
2993                      delRanFuncItem  = (RANfunctionID_ItemIEs_t*) deleteList->list.array[ranFuncIdx];
2994                      ranFuncIdItem = &delRanFuncItem->value.choice.RANfunctionID_Item;
2995                      ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncIdItem->ranFunctionID);
2996                      if(ranFuncDb)
2997                      {
2998                         memset(ranFuncDb, 0, sizeof(RanFunction));
2999                         duDb->numOfRanFunction--; 
3000                      }
3001
3002                      /* Calculating total number of ran fuctions which are received for deletion */
3003                      recvdRanFuncCount++;
3004                   }
3005                }
3006                break;
3007             }
3008
3009          default:
3010             {
3011                DU_LOG("\nERROR  -->  E2AP : IE [%ld] is not supported",ricServiceUpdate->protocolIEs.list.array[arrIdx]->id);
3012                break;
3013             }
3014       }
3015    }
3016    
3017    /* Sending RIC Service Update Failed if all RAN Functions received fail or if any IE processing fails
3018     * Else sending RIC Service Update Acknowledge */  
3019    if((elementCnt > arrIdx) ||((recvdRanFuncCount > 0) && (recvdRanFuncCount == failedRanFuncCount)))
3020    {
3021       if(BuildAndSendRicServiceUpdateFailure(duDb->duId, transId, CauseE2_PR_misc, CauseE2Misc_unspecified) != ROK)
3022       {
3023          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update Failure");
3024          return;
3025       }
3026    }
3027    else
3028    {
3029       if(BuildAndSendRicServiceUpdateAcknowledge(duDb, transId, ricRanFuncList) != ROK)
3030       {
3031          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update acknowledge");
3032          return;
3033       }
3034    }
3035 }
3036
3037 /*******************************************************************
3038  *
3039  * @brief Processing RIC subscription failure from DU
3040  *
3041  * @details
3042  *
3043  *    Function : ProcRicSubscriptionFailure
3044  *
3045  * Functionality: Processing RIC subscription failure from DU
3046  *
3047  * @param  ID of DU from which message was sent
3048  *         RIC Subscription failure message
3049  * @return ROK     - success
3050  *         RFAILED - failure
3051  *
3052  ******************************************************************/
3053 uint8_t ProcRicSubscriptionFailure(uint32_t duId, RICsubscriptionFailure_t *ricSubscriptionFailure)
3054 {
3055    uint8_t ieIdx = 0, duIdx = 0, subsIdx = 0;
3056    uint8_t ranFuncId = 0;
3057    DuDb    *duDb = NULLP;
3058    RanFunction *ranFuncDb = NULLP;
3059    RicSubscription *ricSubs = NULLP;
3060    RicRequestId ricReqId;
3061    RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
3062
3063    DU_LOG("\nINFO  -->  E2AP : Received RIC subscription failure");
3064
3065    SEARCH_DU_DB(duIdx, duId, duDb);
3066    if(duDb == NULLP)
3067    {
3068       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
3069       return RFAILED;
3070    }
3071
3072    memset(&ricReqId, 0, sizeof(RicRequestId));
3073    if(ricSubscriptionFailure)
3074    {
3075       if(ricSubscriptionFailure->protocolIEs.list.array)
3076       {
3077          for(ieIdx=0; ieIdx<ricSubscriptionFailure->protocolIEs.list.count; ieIdx++)
3078          {
3079             if(ricSubscriptionFailure->protocolIEs.list.array[ieIdx])
3080             {
3081                ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[ieIdx];
3082                switch(ricSubscriptionFailure->protocolIEs.list.array[ieIdx]->id)
3083                {
3084                   case ProtocolIE_IDE2_id_RICrequestID:
3085                   {
3086                      ricReqId.requestorId = ricSubsFailIe->value.choice.RICrequestID.ricRequestorID;
3087                      ricReqId.instanceId = ricSubsFailIe->value.choice.RICrequestID.ricInstanceID;
3088                      break;
3089                   }
3090                   case ProtocolIE_IDE2_id_RANfunctionID:
3091                   {
3092                      ranFuncId = ricSubsFailIe->value.choice.RANfunctionID;
3093                      ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
3094                      if(!ranFuncDb)
3095                      {
3096                         DU_LOG("\nERROR  -->  E2AP : ProcRicSubscriptionFailure : RAN Function Id [%d] not found", ranFuncId);
3097                         return RFAILED;
3098                      }
3099                      else
3100                      {
3101                         /* Remove subscription entry from RAN Function */
3102                         ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb);
3103                         if(ricSubs)
3104                         {
3105                            memset(&ranFuncDb->subscriptionList[subsIdx], 0, sizeof(RicSubscription));
3106                         }
3107                      }
3108                      break; 
3109                   }
3110                   case ProtocolIE_IDE2_id_CauseE2:
3111                   default:
3112                      /* No handling required as of now since this is a stub */
3113                      break;
3114                }
3115             }
3116          }
3117       }
3118    }
3119    return ROK;
3120 }
3121
3122 /*******************************************************************
3123  *
3124  * @brief Processing of RIC Subscription Modification Required
3125  *
3126  * @details
3127  *
3128  *    Function : ProcRicSubsModReqd
3129  *
3130  * Functionality: Processing of RIC Subscription Modification Required
3131  *    As of now, we do not identify any scenario where this message
3132  *    shall be sent by DU. Hence, bare minimum handling has been
3133  *    done here.
3134  *
3135  * @param  DU ID
3136  *         RIC Subscription Modification Required IEs
3137  * @return ROK-success
3138  *         RFAILED-failure
3139  *
3140  ******************************************************************/
3141 uint8_t ProcRicSubsModReqd(uint32_t duId, RICsubscriptionModificationRequired_t *ricSubsModReqd)
3142 {
3143    uint8_t ieIdx = 0, actionIdx = 0, duIdx = 0;
3144    DuDb    *duDb = NULLP;
3145    uint16_t ranFuncId;
3146    uint16_t actionId;
3147    RicRequestId ricReqId;
3148    RanFunction *ranFuncDb = NULLP;
3149    RicSubscription *ricSubs = NULLP;
3150    ActionInfo *action = NULLP;
3151    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
3152    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
3153    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
3154    RICaction_RequiredToBeModified_ItemIEs_t *actionToBeMod = NULLP;
3155    RICaction_RequiredToBeRemoved_ItemIEs_t *actionToBeRmv = NULLP;
3156    RicTmpActionList tmpActionList;
3157
3158    memset(&ricReqId, 0, sizeof(RicRequestId));
3159    memset(&tmpActionList, 0, sizeof(RicTmpActionList));
3160
3161    SEARCH_DU_DB(duIdx, duId, duDb);
3162    if(duDb == NULLP)
3163    {
3164       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
3165       return RFAILED;
3166    }
3167
3168    for(ieIdx = 0; ieIdx < ricSubsModReqd->protocolIEs.list.count; ieIdx++)
3169    {
3170       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
3171       switch(ricSubsModReqdIe->id)
3172       {
3173          case ProtocolIE_IDE2_id_RICrequestID:
3174             {
3175                ricReqId.requestorId = ricSubsModReqdIe->value.choice.RICrequestID.ricRequestorID;
3176                ricReqId.instanceId = ricSubsModReqdIe->value.choice.RICrequestID.ricInstanceID;
3177                break;
3178             }
3179          case ProtocolIE_IDE2_id_RANfunctionID:
3180             {
3181                ranFuncId = ricSubsModReqdIe->value.choice.RANfunctionID;
3182                ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
3183                if(!ranFuncDb)
3184                {
3185                   /* If RIC Subscription not found, send RIC Subscription modification refuse to DU */
3186                   DU_LOG("\nERROR  -->  E2AP : ProcRicSubsModReqd: RIC Subscription not found");
3187                   //BuildAndSendRicSubsModRefuse(duId, ricReqId, ranFuncId, CauseE2_PR_ricRequest, \
3188                      CauseE2RICrequest_request_id_unknown);
3189                   return RFAILED;
3190                }
3191
3192                ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb);
3193                if(!ricSubs)
3194                {
3195                   /* If RAN Function not found, send RIC Subscription modification refuse to DU */
3196                   DU_LOG("\nERROR  -->  E2AP : ProcRicSubsModReqd: RAN Function ID [%d] not found",ranFuncId);
3197                   //BuildAndSendRicSubsModRefuse(duId, ricReqId, ranFuncId, \
3198                      CauseE2_PR_ricRequest, CauseE2RICrequest_ran_function_id_invalid);
3199                   return RFAILED; 
3200                }
3201                break;
3202             }
3203          case ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List:
3204             {
3205                actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
3206                for(actionIdx = 0; actionIdx < actionToBeModList->list.count; actionIdx++)
3207                {
3208                   actionToBeMod = (RICaction_RequiredToBeModified_ItemIEs_t *)actionToBeModList->list.array[actionIdx];
3209                   actionId = actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricActionID;
3210                   action = fetchActionInfoFromActionId(actionId, ricSubs);
3211                   if(action)
3212                   {
3213                      /* No modification required as of now, hence directly adding to the list */
3214                      tmpActionList.actionModifiedList[tmpActionList.numActionModifed++] = actionId;
3215                   }
3216                   else
3217                   {
3218                      tmpActionList.actionModFailedList[tmpActionList.numActionModFailed++] = actionId;
3219                   }
3220                }
3221                break;
3222             }
3223          case ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List:
3224             {
3225                actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
3226                for(actionIdx = 0; actionIdx < actionToBeRmvList->list.count; actionIdx++)
3227                {
3228                   actionToBeRmv = (RICaction_RequiredToBeRemoved_ItemIEs_t *)actionToBeRmvList->list.array[actionIdx];
3229                   actionId = actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.ricActionID;
3230                   action = fetchActionInfoFromActionId(actionId, ricSubs);
3231                   if(action)
3232                   {
3233                      tmpActionList.actionRemovedList[tmpActionList.numActionRemoved++] = actionId;
3234                      memset(action, 0, sizeof(ActionInfo));
3235                      action->actionId = -1;
3236                   }
3237                }
3238                break;
3239             }
3240          default:
3241             break;
3242       }
3243    }
3244
3245    /* If none of the action modification/removal is supported, 
3246     *   send RIC Subscription Modification Refuse
3247     * Else
3248     *   send RIC Subscription Modification Confirm
3249     */
3250    // TO BE DONE IN FUTURE GERRITS
3251    /*
3252    if(tmpActionList.numActionModifed || tmpActionList.numActionRemoved)
3253       BuildAndSendRicSubsModConfirm(duId, ricReqId, ranFuncId, tmpActionList);
3254    else
3255       BuildAndSendRicSubsModRefuse(duId, ricReqId, ranFuncId, CauseE2_PR_ricRequest, \
3256       CauseE2RICrequest_action_not_supported);
3257    */
3258    return ROK;
3259 }
3260
3261 /*******************************************************************
3262  *
3263  * @brief Free the ErrorIndication Message
3264  *
3265  * @details
3266  *
3267  *    Function : FreeRicIndication
3268  *
3269  * Functionality: Free the ErrorIndication Message
3270  *
3271  * @return void
3272  *
3273  *
3274  ******************************************************************/
3275 void FreeErrorIndication(E2AP_PDU_t  *e2apMsg)
3276 {
3277    uint8_t arrIdx = 0;
3278    ErrorIndicationE2_t *errorIndicationMsg= NULLP;
3279
3280    if(e2apMsg != NULLP)
3281    {
3282       if(e2apMsg->choice.initiatingMessage != NULLP)
3283       {
3284          errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
3285          if(errorIndicationMsg!= NULLP)
3286          {
3287             if(errorIndicationMsg->protocolIEs.list.array != NULLP)
3288             {
3289                for(arrIdx=0; arrIdx<errorIndicationMsg->protocolIEs.list.count; arrIdx++)
3290                {
3291                   RIC_FREE(errorIndicationMsg->protocolIEs.list.array[arrIdx],sizeof(ErrorIndicationE2_t));
3292                }
3293                RIC_FREE(errorIndicationMsg->protocolIEs.list.array,errorIndicationMsg->protocolIEs.list.size);
3294             }
3295          }
3296          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3297       }
3298       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3299    }
3300 }
3301
3302
3303 /*******************************************************************
3304  *
3305  * @brief Builds and Send the ErrorIndication Message
3306  *
3307  * @details
3308  *
3309  *    Function : BuildAndSendErrorIndication
3310  *
3311  * Functionality:Fills the ErrorIndication Message
3312  *
3313  * @params[in] 
3314  *    DU id
3315  *    Trans id
3316  *    Ric req id
3317  *    Ran function id
3318  *    Reason of failure
3319  * @return ROK     - success
3320  *         RFAILED - failure
3321  *
3322  ******************************************************************/
3323
3324 uint8_t BuildAndSendErrorIndication(uint32_t duId, int8_t transId, RicRequestId requestId, uint16_t ranFuncId, uint8_t reason)
3325 {
3326    uint8_t elementCnt =0, arrIdx=0, ret = RFAILED;
3327    E2AP_PDU_t         *e2apMsg = NULLP;
3328    ErrorIndicationE2_t *errorIndicationMsg=NULLP;
3329    asn_enc_rval_t     encRetVal;        /* Encoder return value */
3330
3331    while(true)
3332    {
3333       DU_LOG("\nINFO   -->  E2AP : Building Error Indication Message\n");
3334
3335       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3336       if(e2apMsg == NULLP)
3337       {
3338          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
3339          break;
3340       }
3341
3342       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
3343       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
3344       if(e2apMsg->choice.initiatingMessage == NULLP)
3345       {
3346          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
3347          break;
3348       }
3349       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_ErrorIndicationE2;
3350       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
3351       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ErrorIndicationE2;
3352
3353       errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
3354
3355       /* Element count is 2 for TransactionID/RICrequestID and Cause.
3356        * If the RAN function id is present, the count will be increased.*/
3357       elementCnt = 2;
3358       if(ranFuncId>0)
3359          elementCnt++;
3360
3361       errorIndicationMsg->protocolIEs.list.count = elementCnt;
3362       errorIndicationMsg->protocolIEs.list.size = elementCnt * sizeof(ErrorIndicationE2_IEs_t*);
3363
3364       /* Initialize the E2Setup members */
3365       RIC_ALLOC(errorIndicationMsg->protocolIEs.list.array, errorIndicationMsg->protocolIEs.list.size);
3366       if(errorIndicationMsg->protocolIEs.list.array == NULLP)
3367       {
3368          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements in %s at line %d",__func__, __LINE__);
3369          break;
3370       }
3371       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
3372       {
3373          RIC_ALLOC(errorIndicationMsg->protocolIEs.list.array[arrIdx], sizeof(ErrorIndicationE2_IEs_t));
3374          if(errorIndicationMsg->protocolIEs.list.array[arrIdx] == NULLP)
3375          {
3376             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array Idx %d in %s at line %d",arrIdx,__func__, __LINE__);
3377             break;
3378          }
3379       }
3380       if(arrIdx < elementCnt)
3381          break;
3382
3383       arrIdx = 0;
3384
3385       if(transId >=0 && transId<=255)
3386       {
3387          /* TransactionID */
3388          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
3389          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3390          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_TransactionID;
3391          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
3392       }
3393       else
3394       {
3395          /* RICrequestID */
3396          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RICrequestID;
3397          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3398          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RICrequestID;
3399          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricRequestorID = requestId.requestorId;
3400          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricInstanceID = requestId.instanceId;
3401       }
3402       
3403       if(ranFuncId>0)
3404       {
3405          /* RAN Function ID */
3406          arrIdx++;
3407          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionID;
3408          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3409          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RANfunctionID;
3410          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionID = ranFuncId;
3411       }
3412      
3413       /* Cause */
3414       arrIdx++;
3415       errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
3416       errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
3417       errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2;
3418       fillE2FailureCause(&errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, CauseE2_PR_misc, reason);
3419
3420
3421       /* Prints the Msg formed */
3422       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3423       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3424       encBufSize = 0;
3425       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
3426             encBuf);
3427       if(encRetVal.encoded == ENCODE_FAIL)
3428       {
3429          DU_LOG("\nERROR  -->  E2AP : Could not encode Error Indication Message (at %s)\n",\
3430                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3431          break;
3432       }
3433       else
3434       {
3435          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for Error Indication Message \n");
3436 #ifdef DEBUG_ASN_PRINT
3437          for(int i=0; i< encBufSize; i++)
3438          {
3439             printf("%x",encBuf[i]);
3440          }
3441 #endif
3442       }
3443
3444       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
3445       {
3446          DU_LOG("\nINFO   -->  E2AP : Sending Error Indication Message");
3447
3448       }
3449       ret = ROK;
3450       break;
3451    }
3452    FreeErrorIndication(e2apMsg);
3453    return ret;
3454 }
3455
3456 /*******************************************************************
3457 *
3458 * @brief Handles received E2AP message and sends back response  
3459 *
3460 * @details
3461 *
3462 *    Function : E2APMsgHdlr
3463 *
3464 *    Functionality:
3465 *         - Decodes received E2AP control message
3466 *         - Prepares response message, encodes and sends to SCTP
3467 *
3468 * @params[in] 
3469 * @return ROK     - success
3470 *         RFAILED - failure
3471 *
3472 * ****************************************************************/
3473 void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
3474 {
3475    int             i;
3476    char            *recvBuf;
3477    MsgLen          copyCnt;
3478    MsgLen          recvBufLen;
3479    E2AP_PDU_t      *e2apMsg;
3480    asn_dec_rval_t  rval; /* Decoder return value */
3481    E2AP_PDU_t      e2apasnmsg ;
3482  
3483    DU_LOG("\nINFO  -->  E2AP : Received E2AP message buffer");
3484    ODU_PRINT_MSG(mBuf, 0,0);
3485  
3486    /* Copy mBuf into char array to decode it */
3487    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
3488    RIC_ALLOC(recvBuf, (Size)recvBufLen);
3489
3490    if(recvBuf == NULLP)
3491    {
3492       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
3493       return;
3494    }
3495    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
3496    {
3497       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
3498       return;
3499    }
3500
3501    DU_LOG("\nDEBUG  -->  E2AP : Received flat buffer to be decoded : ");
3502    for(i=0; i< recvBufLen; i++)
3503    {
3504         DU_LOG("%x",recvBuf[i]);
3505    }
3506
3507    /* Decoding flat buffer into E2AP messsage */
3508    e2apMsg = &e2apasnmsg;
3509    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
3510
3511    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
3512    RIC_FREE(recvBuf, (Size)recvBufLen);
3513
3514    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
3515    {
3516       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
3517       return;
3518    }
3519    DU_LOG("\n");
3520    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3521
3522    switch(e2apMsg->present)
3523    {
3524       case E2AP_PDU_PR_initiatingMessage:
3525          {
3526             switch(e2apMsg->choice.initiatingMessage->value.present)
3527             {
3528                case InitiatingMessageE2__value_PR_E2setupRequest:
3529                   {
3530                      DU_LOG("\nINFO  -->  E2AP : E2 setup request received");
3531                      ProcE2SetupReq(duId, &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest);
3532                      break;
3533                   }
3534                case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate:
3535                   {
3536                      DU_LOG("\nINFO  -->  E2AP : E2 node config update received");
3537                      ProcE2NodeConfigUpdate(*duId, &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate);
3538                      break;
3539                   }
3540                case InitiatingMessageE2__value_PR_ResetRequestE2:
3541                   {
3542                      DU_LOG("\nINFO  -->  E2AP : E2 Reset Request received");
3543                      ProcE2ResetReq(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2);
3544                      break;
3545                   }
3546                case InitiatingMessageE2__value_PR_RICindication:
3547                   {
3548                      DU_LOG("\nINFO  -->  E2AP : RIC Indication received");
3549                      break;
3550                   }
3551                case InitiatingMessageE2__value_PR_RICserviceUpdate:
3552                   {
3553                      DU_LOG("\nINFO  -->  E2AP : RIC Service update received");
3554                      ProcRicServiceUpdate(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate);
3555                      break;
3556                   }
3557                case InitiatingMessageE2__value_PR_RICsubscriptionModificationRequired:
3558                   {
3559                      DU_LOG("\nINFO  -->  E2AP : RIC Subscription Modification Required");
3560                      ProcRicSubsModReqd(*duId, \
3561                            &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired);
3562                      break;
3563                   }
3564
3565                case InitiatingMessageE2__value_PR_ErrorIndicationE2:
3566                   {
3567                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
3568                      break;
3569                   }
3570                default:
3571                   {
3572                      DU_LOG("\nERROR  -->  E2AP : Invalid type of intiating message [%d]", \
3573                         e2apMsg->choice.initiatingMessage->value.present);
3574                      return;
3575                   }
3576             }/* End of switch(initiatingMessage) */
3577             break;
3578          }
3579       case E2AP_PDU_PR_successfulOutcome: 
3580          {
3581             switch(e2apMsg->choice.successfulOutcome->value.present)
3582             {
3583                case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:  
3584                   {
3585                      ProcRicSubscriptionResponse(*duId, \
3586                         &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse);
3587                      break;
3588                   }
3589                default:
3590                   {
3591                      DU_LOG("\nERROR  -->  E2AP : Invalid type of successfulOutcome message [%d]", \
3592                         e2apMsg->choice.successfulOutcome->value.present);
3593                      return;
3594                   }
3595                   break;
3596             }
3597             break; 
3598          }
3599          case E2AP_PDU_PR_unsuccessfulOutcome:
3600          {
3601             switch(e2apMsg->choice.successfulOutcome->value.present)
3602             {
3603                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure:
3604                   {
3605                      ProcRicSubscriptionFailure(*duId, \
3606                         &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure);
3607                      break;
3608                   }
3609                default:
3610                   {
3611                      DU_LOG("\nERROR  -->  E2AP : Invalid type of unsuccessfulOutcome message [%d]", \
3612                         e2apMsg->choice.unsuccessfulOutcome->value.present);
3613                      return;
3614                   }
3615             }
3616             break;
3617          }
3618       default:
3619          {
3620             DU_LOG("\nERROR  -->  E2AP : Invalid type message type ");
3621             return;
3622          }
3623
3624    }/* End of switch(e2apMsg->present) */
3625 } /* End of E2APMsgHdlr */
3626
3627
3628 /**********************************************************************
3629   End of file
3630  **********************************************************************/