[Epic-ID: ODUHIGH-510][Task-ID: ODUHIGH-512] Implementation of E2 setup failure 43/11343/5
authorlal.harshita <Harshita.Lal@radisys.com>
Thu, 15 Jun 2023 09:10:03 +0000 (14:40 +0530)
committerlal.harshita <Harshita.Lal@radisys.com>
Mon, 19 Jun 2023 10:07:21 +0000 (15:37 +0530)
Change-Id: I4b43019bfaec96d3f68124fe9b25a347dbac75c3
Signed-off-by: lal.harshita <Harshita.Lal@radisys.com>
21 files changed:
src/du_app/du_cell_mgr.c
src/du_app/du_cfg.c
src/du_app/du_e2_conversions.c [new file with mode: 0644]
src/du_app/du_e2_conversions.h [new file with mode: 0644]
src/du_app/du_e2ap_mgr.c
src/du_app/du_e2ap_mgr.h
src/du_app/du_e2ap_msg_hdl.c
src/du_app/du_egtp.c
src/du_app/du_f1ap_msg_hdl.c
src/du_app/du_mgr.h
src/du_app/du_mgr_main.c
src/du_app/du_mgr_msg_router.c
src/du_app/du_msg_hdl.c
src/du_app/du_sctp.c
src/du_app/du_sys_info_hdl.c
src/du_app/du_tmr.c [new file with mode: 0644]
src/du_app/du_tmr.h [new file with mode: 0644]
src/du_app/du_ue_mgr.c
src/du_app/du_utils.c
src/ric_stub/ric_e2ap_msg_hdl.c
src/ric_stub/ric_e2ap_msg_hdl.h

index a09e435..b0eb865 100644 (file)
@@ -18,6 +18,7 @@
 
 /* This file contains message handling functionality for DU cell management */
 #include "common_def.h"
+#include "du_tmr.h"
 #include "lrg.h"
 #include "legtp.h"
 #include "lrg.x"
index 335415c..4c7a1c5 100644 (file)
@@ -18,6 +18,7 @@
 
 /* This file contains all utility functions */
 #include "common_def.h"
+#include "du_tmr.h"
 #include "legtp.h"
 #include "lrg.h"
 #include "lkw.x"
@@ -601,8 +602,8 @@ uint8_t readCfg()
    Sib1Params sib1;
    F1TaiSliceSuppLst *taiSliceSuppLst;
 
-   duCb.e2apDb.transIdCounter = 0;
-   memset(duCb.e2apDb.onGoingTransaction, 0, MAX_NUM_TRANSACTION * sizeof(E2TransInfo));
+   duCb.e2apDb.e2TransInfo.transIdCounter = 0;
+   memset(duCb.e2apDb.e2TransInfo.onGoingTransaction, 0, MAX_NUM_TRANSACTION * sizeof(E2TransInfo));
 
 #ifndef O1_ENABLE
    /* Note: Added these below variable for local testing*/
@@ -1087,7 +1088,26 @@ uint8_t duReadCfg()
    pst.selector = ODU_SELECTOR_TC;
    pst.pool= DU_POOL;
 
+   /* Initialize the timer blocks */
+   cmInitTimers(&(duCb.e2apDb.e2Timers.e2SetupTimer), 1);
 
+   /* Initialzie the timer queue */   
+   memset(&(duCb.duTimersInfo.tmrTq), 0, sizeof(CmTqType) * DU_TQ_SIZE);
+   
+   /* Initialize the timer control point */
+   memset(&(duCb.duTimersInfo.tmrTqCp), 0, sizeof(CmTqCp));
+   duCb.duTimersInfo.tmrTqCp.tmrLen = DU_TQ_SIZE;
+   
+   /* Initialize the timer resolution */
+   duCb.duTimersInfo.tmrRes = DU_TIMER_RESOLUTION;
+   
+   /* Timer Registration request to system services */
+   if (ODU_REG_TMR_MT(pst.srcEnt, pst.srcInst, duCb.duTimersInfo.tmrRes, duActvTmr) != ROK)
+   {
+      DU_LOG("\nERROR  -->  DU_APP : Failed to register timer");
+      return RFAILED;
+   }   
+              
    if(ODU_GET_MSG_BUF(DFLT_REGION, DU_POOL, &mBuf) != ROK)
    {
       DU_LOG("\nERROR  -->  DU_APP : Memory allocation failed in duReadCfg");
diff --git a/src/du_app/du_e2_conversions.c b/src/du_app/du_e2_conversions.c
new file mode 100644 (file)
index 0000000..3ee6ca0
--- /dev/null
@@ -0,0 +1,70 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   Licensed under the Apache License, Version 2.0 (the "License");            #
+#   you may not use this file except in compliance with the License.           #
+#   You may obtain a copy of the License at                                    #
+#                                                                              #
+#       http://www.apache.org/licenses/LICENSE-2.0                             #
+#                                                                              #
+#   Unless required by applicable law or agreed to in writing, software        #
+#   distributed under the License is distributed on an "AS IS" BASIS,          #
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
+#   See the License for the specific language governing permissions and        #
+#   limitations under the License.                                             #
+################################################################################
+*******************************************************************************/
+
+/* This file contains functions that maps values received in F1AP message with
+ * its corresponding values used in DU and vice-versa */
+
+#include "common_def.h"
+#include "TimeToWaitE2.h"
+
+/************************************************************************
+ *
+ * @brief Converts enum values into actual value of E2 wait timer
+ *
+ * @details
+ *
+ *    Function : covertE2WaitTimerEnumToValue
+ *
+ *    Functionality: Converts enum values into actual value of E2 wait timer 
+ *
+ * @params[in] Enum value of e2 wait timer 
+ * @return Actual value of e2 wait timer
+ *
+ * **********************************************************************/
+
+uint8_t covertE2WaitTimerEnumToValue(uint8_t timerToWait)
+{
+   switch(timerToWait)
+   {
+      case TimeToWaitE2_v1s:
+         return 1;
+         
+      case TimeToWaitE2_v2s:
+         return 2;
+         
+      case TimeToWaitE2_v5s:
+         return 5;
+         
+      case TimeToWaitE2_v10s:
+         return 10;
+         
+      case TimeToWaitE2_v20s:
+         return 20;
+         
+      case TimeToWaitE2_v60s:
+         return 60;
+         
+      default:
+         DU_LOG("\nERROR  -->  F1AP: Invalid value of E2 Wait timer");
+   }
+   return RFAILED;
+}
+
+/**********************************************************************
+  End of file
+ **********************************************************************/
diff --git a/src/du_app/du_e2_conversions.h b/src/du_app/du_e2_conversions.h
new file mode 100644 (file)
index 0000000..1aa5646
--- /dev/null
@@ -0,0 +1,25 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   Licensed under the Apache License, Version 2.0 (the "License");            #
+#   you may not use this file except in compliance with the License.           #
+#   You may obtain a copy of the License at                                    #
+#                                                                              #
+#       http://www.apache.org/licenses/LICENSE-2.0                             #
+#                                                                              #
+#   Unless required by applicable law or agreed to in writing, software        #
+#   distributed under the License is distributed on an "AS IS" BASIS,          #
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
+#   See the License for the specific language governing permissions and        #
+#   limitations under the License.                                             #
+################################################################################
+*******************************************************************************/
+
+/* This file contains definitions of E2 conversion functions */
+
+uint8_t covertE2WaitTimerEnumToValue(uint8_t timerToWait);
+
+/**********************************************************************
+  End of file
+ **********************************************************************/
index 83ab35a..7c834cd 100644 (file)
 ################################################################################
 *******************************************************************************/
 #include "common_def.h"
+#include "du_tmr.h"
 #include "lrg.h"
 #include "lkw.x"
 #include "lrg.x"
 #include "legtp.h"
+#include "du_e2ap_mgr.h"
 #include "du_app_mac_inf.h"
 #include "du_app_rlc_inf.h"
-#include "du_e2ap_mgr.h"
 #include "du_e2ap_msg_hdl.h"
 #include "du_cfg.h"
 #include "du_sctp.h"
  * ****************************************************************/
 uint8_t assignTransactionId()
 {
-   uint8_t currTransId = duCb.e2apDb.transIdCounter;
+   uint8_t currTransId = duCb.e2apDb.e2TransInfo.transIdCounter;
 
    /* Update to next valid value */
-   duCb.e2apDb.transIdCounter++;
-   if(duCb.e2apDb.transIdCounter == MAX_NUM_TRANSACTION)
-      duCb.e2apDb.transIdCounter = 0;
+   duCb.e2apDb.e2TransInfo.transIdCounter++;
+   if(duCb.e2apDb.e2TransInfo.transIdCounter == MAX_NUM_TRANSACTION)
+      duCb.e2apDb.e2TransInfo.transIdCounter = 0;
 
    return currTransId;
 }
index 9fea513..fc36524 100644 (file)
@@ -19,6 +19,8 @@
 /* This file contains all E2AP message handler related functionality */
 
 #define MAX_NUM_TRANSACTION 256 /* As per, O-RAN WG3 E2AP v3.0, section 9.2.33 */
+#define MAX_E2_SETUP_TMR 1
+#define EVENT_E2_SETUP_TMR 1
 
 typedef enum
 {
@@ -106,18 +108,32 @@ typedef struct
    uint8_t procedureCode;
 }E2TransInfo;
 
+typedef struct e2Transcation
+{
+   uint8_t     transIdCounter;
+   E2TransInfo onGoingTransaction[MAX_NUM_TRANSACTION];
+   /* Any new parameter for transaction handling can be added here in future */
+}E2Transcation;
+
+typedef struct e2Timer
+{
+   CmTimer e2SetupTimer;
+   /* More timers can be added to this structure in future */
+}E2Timer;
+
 typedef struct e2apDb
 {
-   uint16_t     ricId;
-   uint8_t      transIdCounter;
-   E2TransInfo  onGoingTransaction[MAX_NUM_TRANSACTION];
-   uint8_t      *plmn;
-   uint32_t     ricReqId;
-   uint32_t     ricInstanceId;
-   uint32_t     ranFuncId;
-   uint8_t     *ricEventTrigger;
-   uint32_t     ricActionId;
-   uint32_t     ricActionType;
+   uint16_t      ricId;
+   E2Transcation e2TransInfo;
+   uint8_t       *plmn;
+   uint32_t      ricReqId;
+   uint32_t      ricInstanceId;
+   uint32_t      ranFuncId;
+   uint8_t       *ricEventTrigger;
+   uint32_t      ricActionId;
+   uint32_t      ricActionType;
+   E2Timer       e2Timers;
+   uint8_t       e2SetupTimerInterval;
 }E2apDb;
 
 uint8_t assignTransactionId();
index e048d6d..926b328 100644 (file)
@@ -16,6 +16,7 @@
 ################################################################################
 *******************************************************************************/
 #include "common_def.h"
+#include "du_tmr.h"
 #include "lrg.h"
 #include "lkw.x"
 #include "lrg.x"
 #include "E2setupRequest.h"
 #include "InitiatingMessageE2.h"
 #include "SuccessfulOutcomeE2.h"
+#include "UnsuccessfulOutcomeE2.h"
 #include "E2AP-PDU.h"
 #include "odu_common_codec.h"
 #include "E2nodeComponentInterfaceF1.h"
 #include "E2setupRequest.h"
+#include "du_e2_conversions.h"
 
 /*******************************************************************
  *
@@ -158,7 +161,6 @@ uint8_t BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAdd
    memcpy(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\
    duCb.f1SetupReqAndRspMsg.f1MsgReqBuf, e2NodeAddItem->e2nodeComponentConfiguration.\
    e2nodeComponentRequestPart.size);
-   DU_FREE(duCb.f1SetupReqAndRspMsg.f1MsgReqBuf,duCb.f1SetupReqAndRspMsg.f1MsgReqBufSize);
   
    /* E2 Node Component Response Part */
    e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.size = duCb.f1SetupReqAndRspMsg.f1MsgRspBufSize; 
@@ -172,7 +174,6 @@ uint8_t BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAdd
    memcpy(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.buf, \
    duCb.f1SetupReqAndRspMsg.f1MsgRspBuf, e2NodeAddItem->e2nodeComponentConfiguration.\
    e2nodeComponentResponsePart.size);
-   DU_FREE(duCb.f1SetupReqAndRspMsg.f1MsgRspBuf, duCb.f1SetupReqAndRspMsg.f1MsgRspBufSize);
 
    /* E2 Node Component ID */
    e2NodeAddItem->e2nodeComponentID.present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1;
@@ -197,109 +198,6 @@ uint8_t BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAdd
 
 }
 
-/*******************************************************************
- *
- * @brief Fills the initiating IE for E2 Setup Request
- *
- * @details
- *
- *    Function : fillE2SetupReq
- *
- * Functionality:Fills the Initiating message for
- *               E2SetupRequest
- *
- * @params[in] E2setupRequest_t *e2SetupReq,
- *             uint8_t *idx
- * @return ROK     - success
- *         RFAILED - failure
- *
- ******************************************************************/
-
-uint8_t fillE2SetupReq(E2setupRequest_t **e2SetupReq, uint8_t *idx)
-{
-   uint8_t elementCnt = 0;
-   uint8_t arrIdx = 0;
-   uint8_t ret = ROK;
-
-   if(*e2SetupReq != NULLP)
-   {
-      elementCnt = 3;
-      (*e2SetupReq)->protocolIEs.list.count = elementCnt;
-      (*e2SetupReq)->protocolIEs.list.size = elementCnt * sizeof(E2setupRequestIEs_t*);
-
-      /* Initialize the E2Setup members */
-      DU_ALLOC((*e2SetupReq)->protocolIEs.list.array, \
-            (*e2SetupReq)->protocolIEs.list.size);
-      if((*e2SetupReq)->protocolIEs.list.array == NULLP)
-      {
-         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
-         return RFAILED;
-      }
-      for(*idx = 0; *idx < elementCnt; (*idx)++)
-      {
-         DU_ALLOC((*e2SetupReq)->protocolIEs.list.array[*idx],\
-               sizeof(E2setupRequestIEs_t));
-         if((*e2SetupReq)->protocolIEs.list.array[*idx] == NULLP)
-         {
-            DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayidx [%d]", *idx);
-            return RFAILED;
-         }
-      }
-      arrIdx = 0;
-
-      /* TransactionID */
-      (*e2SetupReq)->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
-      (*e2SetupReq)->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
-      (*e2SetupReq)->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
-      (*e2SetupReq)->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = TRANS_ID;
-
-      arrIdx++;
-      /* GlobalE2node_gNB_ID */
-      (*e2SetupReq)->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_GlobalE2node_ID;
-      (*e2SetupReq)->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
-      (*e2SetupReq)->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_GlobalE2node_ID;
-      (*e2SetupReq)->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.present = GlobalE2node_ID_PR_gNB;
-
-      DU_ALLOC((*e2SetupReq)->protocolIEs.list.array[arrIdx]->value.choice.\
-            GlobalE2node_ID.choice.gNB, sizeof(GlobalE2node_gNB_ID_t));
-      if((*e2SetupReq)->protocolIEs.list.array[arrIdx]->value.choice.\
-            GlobalE2node_ID.choice.gNB == NULLP)
-      {
-         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for gNbId");
-         return  RFAILED;
-      }
-      else
-      {
-         ret = BuildGlobalgNBId((*e2SetupReq)->protocolIEs.list.array[arrIdx]->value.\
-               choice.GlobalE2node_ID.choice.gNB);
-         if(ret != ROK)
-         {
-             DU_LOG("\nERROR  -->  E2AP : Failed to build Global Gnb Id");
-             return RFAILED;
-         }
-      }
-      
-      arrIdx++;
-      /* E2 Node Component Configuration Addition List */
-      (*e2SetupReq)->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition;
-      (*e2SetupReq)->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
-      (*e2SetupReq)->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_E2nodeComponentConfigAddition_List;
-      if(BuildE2NodeConfigAddList(&((*e2SetupReq)->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List))!=ROK)
-      {
-         DU_LOG("\nERROR  -->  E2AP : Failed to E2 Node config addition list");
-         return RFAILED;
-      }
-
-   }
-   else
-   {
-      DU_LOG("\nERROR  -->  E2AP : received e2SetupReq is NULL");
-      return RFAILED;
-   }
-   return ROK;
-}
-
-
 /*******************************************************************
  *
  * @brief De Allocate E2 Setup Request Message
@@ -427,8 +325,9 @@ void FreeE2SetupReq(E2AP_PDU_t *e2apMsg)
 
 uint8_t BuildAndSendE2SetupReq()
 {
-   uint8_t idx = 0;
-   uint8_t ret = ROK;
+   uint8_t arrIdx = 0, elementCnt=0;
+   uint8_t transId = 0, ret = ROK;
+   bool memAllocFailed;
    E2AP_PDU_t        *e2apMsg = NULLP;
    E2setupRequest_t  *e2SetupReq = NULLP;
    asn_enc_rval_t     encRetVal;       /* Encoder return value */
@@ -447,20 +346,87 @@ uint8_t BuildAndSendE2SetupReq()
       if(e2apMsg->choice.initiatingMessage == NULLP)
       {
          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
-         DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
-         return RFAILED;
+         break;
       }
       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2setup;
       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2setupRequest;
       e2SetupReq = &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest;
 
-      ret = fillE2SetupReq(&e2SetupReq, &idx);
-      if(ret != ROK)
+      elementCnt = 3;
+      e2SetupReq->protocolIEs.list.count = elementCnt;
+      e2SetupReq->protocolIEs.list.size = elementCnt * sizeof(E2setupRequestIEs_t*);
+
+      /* Initialize the E2Setup members */
+      DU_ALLOC(e2SetupReq->protocolIEs.list.array, \
+            e2SetupReq->protocolIEs.list.size);
+      if(e2SetupReq->protocolIEs.list.array == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements");
+         break;
+      }
+      for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
+      {
+         DU_ALLOC(e2SetupReq->protocolIEs.list.array[arrIdx],\
+               sizeof(E2setupRequestIEs_t));
+         if(e2SetupReq->protocolIEs.list.array[arrIdx] == NULLP)
+         {
+            memAllocFailed = true;
+            DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for arrayarrIdx [%d]", arrIdx);
+            break;
+         }
+      }
+      if(memAllocFailed == true)
+         break;
+
+      arrIdx = 0;
+
+      /* TransactionID */
+      e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
+      e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
+      e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID;
+      transId = assignTransactionId();
+      e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
+
+      arrIdx++;
+      /* GlobalE2node_gNB_ID */
+      e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_GlobalE2node_ID;
+      e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
+      e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_GlobalE2node_ID;
+      e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.present = GlobalE2node_ID_PR_gNB;
+
+      DU_ALLOC(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.\
+            GlobalE2node_ID.choice.gNB, sizeof(GlobalE2node_gNB_ID_t));
+      if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.\
+            GlobalE2node_ID.choice.gNB == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for gNbId");
+         break;
+      }
+      else
       {
-         DU_LOG("\nERROR  -->  E2AP : fillE2SetupReq() failed");
+         ret = BuildGlobalgNBId(e2SetupReq->protocolIEs.list.array[arrIdx]->value.\
+               choice.GlobalE2node_ID.choice.gNB);
+         if(ret != ROK)
+         {
+             DU_LOG("\nERROR  -->  E2AP : Failed to build Global Gnb Id");
+             break;
+         }
+      }
+      
+      arrIdx++;
+      /* E2 Node Component Configuration Addition List */
+      e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition;
+      e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
+      e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_E2nodeComponentConfigAddition_List;
+      if(BuildE2NodeConfigAddList(&(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List))!=ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Failed to E2 Node config addition list");
          break;
       }
+
+
+
       /* Prints the Msg formed */
       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
 
@@ -488,10 +454,12 @@ uint8_t BuildAndSendE2SetupReq()
       {
          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup request failed");
       }
-
       break;
    }while(true);
 
+   duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].transactionId = transId;
+   duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
+   
    FreeE2SetupReq(e2apMsg);
    return ret;
 }/* End of BuildAndSendE2SetupReq */
@@ -954,7 +922,7 @@ void freeAperDecodingOfE2SetupRsp(E2setupResponse_t *e2SetRspMsg)
  * ****************************************************************/
 uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg)
 {
-   uint8_t arrIdx =0; 
+   uint8_t arrIdx =0, transId=0
    uint32_t recvBufLen;             
    E2setupResponse_t *e2SetRspMsg;
 
@@ -967,7 +935,18 @@ uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg)
       switch(e2SetRspMsg->protocolIEs.list.array[arrIdx]->id)
       {
          case ProtocolIE_IDE2_id_TransactionID:
-            break;
+            {
+               transId = e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
+               if((duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].transactionId == transId) &&\
+                     (duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
+                  memset(&duCb.e2apDb.e2TransInfo.onGoingTransaction[transId], 0, sizeof(E2TransInfo));
+               else
+               {
+                  DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
+                  return RFAILED;
+               }
+               break;
+            }
 
          case ProtocolIE_IDE2_id_GlobalRIC_ID:
             {
@@ -996,6 +975,10 @@ uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg)
       }
    }
    freeAperDecodingOfE2SetupRsp(e2SetRspMsg);
+   
+   DU_FREE(duCb.f1SetupReqAndRspMsg.f1MsgReqBuf,duCb.f1SetupReqAndRspMsg.f1MsgReqBufSize);
+   DU_FREE(duCb.f1SetupReqAndRspMsg.f1MsgRspBuf, duCb.f1SetupReqAndRspMsg.f1MsgRspBufSize); 
+   
    BuildAndSendE2NodeConfigUpdate();
    return ROK;
 }
@@ -1728,8 +1711,8 @@ uint8_t BuildAndSendE2ResetRequest(E2CauseType failureType, E2Cause failureCause
 
       /* In case the message is sent successfully, store the transaction info to
        * be used when response is received */
-      duCb.e2apDb.onGoingTransaction[transId].transactionId = transId;
-      duCb.e2apDb.onGoingTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
+      duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].transactionId = transId;
+      duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
 
       ret = ROK;
       break;
@@ -1812,8 +1795,9 @@ uint8_t procResetResponse(E2AP_PDU_t *e2apMsg)
       {
          case ProtocolIE_IDE2_id_TransactionID:
             transId = resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
-            if(duCb.e2apDb.onGoingTransaction[transId].transactionId == transId)
-              memset(&duCb.e2apDb.onGoingTransaction[transId], 0, sizeof(E2TransInfo));
+            if((duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].transactionId == transId) && \
+                  (duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode))
+              memset(&duCb.e2apDb.e2TransInfo.onGoingTransaction[transId], 0, sizeof(E2TransInfo));
             else
             {
                DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
@@ -1840,6 +1824,99 @@ uint8_t procResetResponse(E2AP_PDU_t *e2apMsg)
    return ROK;
 }
 
+/******************************************************************
+ *
+ * @brief Deallocation of memory allocated bu aper decoder for e2 setup Failure
+ *
+ * @details
+ *
+ *    Function : freeAperDecodingOfE2SetupFailure
+ *
+ *    Functionality: Deallocation of memory allocated bu aper decoder for e2
+ *    setup Failure
+ *
+ * @params[in] E2setupFailure_t *e2SetupFailure;
+ * @return void
+ *
+ * ****************************************************************/
+void freeAperDecodingOfE2SetupFailure(E2setupFailure_t *e2SetupFailure)
+{
+   uint8_t arrIdx;
+
+   if(e2SetupFailure)
+   {
+      if(e2SetupFailure->protocolIEs.list.array)
+      {
+         for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
+         {
+            if(e2SetupFailure->protocolIEs.list.array[arrIdx])
+            {
+               free(e2SetupFailure->protocolIEs.list.array[arrIdx]);  
+            }
+         }
+         free(e2SetupFailure->protocolIEs.list.array);
+      }
+   }
+}
+/******************************************************************
+ *
+ * @brief Processes E2 Setup Failure sent by RIC
+ *
+ * @details
+ *
+ *    Function : procE2SetupFailure
+ *
+ *    Functionality: Processes E2 Setup failure sent by RIC
+ *
+ * @params[in] E2AP_PDU_t ASN decoded E2AP message
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+void procE2SetupFailure(E2AP_PDU_t *e2apMsg)
+{
+   uint8_t arrIdx =0, transId =0, timerValue=0; 
+   E2setupFailure_t *e2SetupFailure;
+
+   DU_LOG("\nINFO   -->  E2AP : E2 Setup failure received"); 
+   e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
+
+   for(arrIdx=0; arrIdx<e2SetupFailure->protocolIEs.list.count; arrIdx++)
+   {
+      switch(e2SetupFailure->protocolIEs.list.array[arrIdx]->id)
+      {
+         case ProtocolIE_IDE2_id_TransactionID:
+         {
+            transId = e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
+            if((duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].transactionId == transId) &&\
+            (duCb.e2apDb.e2TransInfo.onGoingTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
+              memset(&duCb.e2apDb.e2TransInfo.onGoingTransaction[transId], 0, sizeof(E2TransInfo));
+            else
+            {
+               DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
+               return ;
+            }
+            break;
+         }
+         case ProtocolIE_IDE2_id_TimeToWaitE2:
+            {
+               timerValue = covertE2WaitTimerEnumToValue(e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2);
+               if((duChkTmr((PTR)&(duCb.e2apDb), EVENT_E2_SETUP_TMR)) == FALSE)
+               {
+                  duStartTmr((PTR)&(duCb.e2apDb), EVENT_E2_SETUP_TMR, timerValue);
+               }
+               else
+               {
+                  DU_LOG("\nERROR   -->  E2AP : EVENT_E2_SETUP_TMR timer is already running");
+                  return;
+               }
+               break; 
+            }
+      }
+   }
+
+   freeAperDecodingOfE2SetupFailure(e2SetupFailure);
+}
 /*******************************************************************
  *
  * @brief Handles received E2AP message and sends back response  
@@ -1910,6 +1987,24 @@ void E2APMsgHdlr(Buffer *mBuf)
 
    switch(e2apMsg->present)
    {
+      case E2AP_PDU_PR_unsuccessfulOutcome:
+         {
+            switch(e2apMsg->choice.unsuccessfulOutcome->value.present)
+            {
+               case UnsuccessfulOutcomeE2__value_PR_E2setupFailure:
+                  {
+                     procE2SetupFailure(e2apMsg);
+                     break;
+                  }
+               default:
+                  {
+                     DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome  [%d]",\
+                           e2apMsg->choice.unsuccessfulOutcome->value.present);
+                     return;
+                  }
+            }
+            break;
+         }
       case E2AP_PDU_PR_successfulOutcome:
          {
             switch(e2apMsg->choice.successfulOutcome->value.present)
index 4cf5be7..a5d63aa 100644 (file)
@@ -18,6 +18,7 @@
  
 /* This file contains all EGTP related functionality */
 #include "common_def.h"
+#include "du_tmr.h"
 #include "lrg.h"
 #include "lkw.x"
 #include "lrg.x"
index a8c6d54..b639f07 100644 (file)
@@ -18,6 +18,7 @@
 
 /* This file contains F1AP message handler functions */
 #include "common_def.h"
+#include "du_tmr.h"
 #include "ckw.h"
 #include "ckw.x"
 #include "kwu.h"
index 7904f47..4210106 100644 (file)
@@ -323,6 +323,13 @@ typedef struct reservedF1apPduInfo
    void *f1apMsg;              /* msg structure */
 }ReservedF1apPduInfo;
 
+typedef struct duTimer
+{
+   CmTqCp       tmrTqCp;               /*!< Timer Task Queue Cntrl Point */
+   CmTqType     tmrTq[DU_TQ_SIZE];    /*!< Timer Task Queue */
+   uint8_t      tmrRes;              /*!< Timer resolution */
+}DuTimers;
+
 /* DU APP DB */
 typedef struct duCb
 {
@@ -341,8 +348,9 @@ typedef struct duCb
    uint8_t       numTeId;                   /* current number of TEIDs configured in the system*/
    UpTnlCfg*     upTnlCfg[MAX_TEID];        /* tunnel info for every Drb */
    CmLListCp     reservedF1apPduList;       /*storing F1AP pdu infomation and transId */
-   SliceCfgState sliceState;
-   F1SetupMsg    f1SetupReqAndRspMsg;
+   SliceCfgState sliceState;                /* Slice status */ 
+   F1SetupMsg    f1SetupReqAndRspMsg;       /* f1 Setup Req And Rsp Msg*/
+   DuTimers      duTimersInfo;              /* Du timers queue */
 }DuCb;
 
 
index ead7595..dfcc198 100644 (file)
@@ -18,6 +18,7 @@
 
 /* This file is the entry point for DU APP */
 #include "common_def.h"
+#include "du_tmr.h"
 #include "lrg.h"
 #include "legtp.h"
 #include "lrg.x"
index f548da7..073b3e7 100644 (file)
@@ -18,6 +18,7 @@
 /* File : du_mgr_msg_router.c */
 /* This file contains message handling functionality for DU APP */
 #include "common_def.h"
+#include "du_tmr.h"
 #include "lrg.h"
 #include "legtp.h"
 #include "lsctp.h"
index dfc80b6..5ab931b 100644 (file)
@@ -19,6 +19,7 @@
 /* This file contains message handling functionality for DU APP */
 #include "common_def.h"
 #include "lrg.h"
+#include "du_tmr.h"
 #include "legtp.h"
 #include "lkw.h"
 #include "kwu.h"
index 78048d7..93cd7dc 100644 (file)
@@ -18,6 +18,7 @@
 
 /* This file contains all SCTP related functionality */
 #include "common_def.h"
+#include "du_tmr.h"
 #include "lrg.h"
 #include "legtp.h"
 #include "lrg.x"
index b8184ce..08a86f0 100644 (file)
@@ -18,6 +18,7 @@
 
 /* This file contains ASN codec for MIB and SIB1 msgs */
 #include "common_def.h"
+#include "du_tmr.h"
 #include "lrg.h"
 #include "lkw.x"
 #include "lrg.x"
diff --git a/src/du_app/du_tmr.c b/src/du_app/du_tmr.c
new file mode 100644 (file)
index 0000000..d635836
--- /dev/null
@@ -0,0 +1,175 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   Licensed under the Apache License, Version 2.0 (the "License");            #
+#   you may not use this file except in compliance with the License.           #
+#   You may obtain a copy of the License at                                    #
+#                                                                              #
+#       http://www.apache.org/licenses/LICENSE-2.0                             #
+#                                                                              #
+#   Unless required by applicable law or agreed to in writing, software        #
+#   distributed under the License is distributed on an "AS IS" BASIS,          #
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
+#   See the License for the specific language governing permissions and        #
+#   limitations under the License.                                             #
+################################################################################
+*******************************************************************************/
+
+#include "common_def.h"
+#include "lkw.h"
+#include "lkw.x"
+#include "lrg.h"
+#include "lrg.x"
+#include "du_tmr.h"
+#include "du_app_rlc_inf.h"
+#include "du_app_mac_inf.h"
+#include "du_cfg.h"
+#include "du_e2ap_mgr.h"
+#include "du_mgr.h"
+#include "du_e2ap_msg_hdl.h"
+
+/**
+ * @brief Handler to check if the timer is running
+ *
+ * @param[in] cb        Control block depending on the type of the timer event.
+ *                      It can be uplink/downlink rbCb or rgu sap control block
+ * @param[in] tmrEvnt   Timer event to be started
+ *
+ * @return  Bool indicating whether the timer is running or not
+ *      -# ROK
+ *      -# RFAILED
+*/
+
+bool duChkTmr(PTR cb, int16_t tmrEvnt)
+{
+   switch (tmrEvnt)
+   {
+      case EVENT_E2_SETUP_TMR:
+      {
+         if(((E2apDb *)cb)->e2Timers.e2SetupTimer.tmrEvnt == EVENT_E2_SETUP_TMR)
+         {
+             DU_LOG("\nERROR  -->  DU_APP : duChkTmr: Invalid tmr Evnt [%d]", tmrEvnt);
+             return TRUE;
+         }
+      }
+      
+      default:
+      {
+         DU_LOG("\nERROR  -->  DU_APP : duChkTmr: Invalid tmr Evnt [%d]", tmrEvnt);
+      }
+   }
+
+   return FALSE;
+}
+
+/**
+ * @brief Handler to start timer
+ *
+ * @param[in] cb        Control block depending on the type of the timer event.
+ *                      It can be uplink/downlink rbCb or rgu sap control block
+ * @param[in] tmrEvnt   Timer event to be started
+ *
+ * @return  Void
+*/
+
+void duStartTmr(PTR cb, int16_t tmrEvnt, uint8_t timerValue)
+{
+   E2apDb *e2apDb;
+   CmTmrArg arg;
+   arg.wait = 0;
+   
+   switch (tmrEvnt)
+   {
+      case EVENT_E2_SETUP_TMR:
+      {
+         e2apDb = ((E2apDb *)cb);
+         DU_TMR_CALCUATE_WAIT(arg.wait, timerValue, duCb.duTimersInfo.tmrRes);
+
+         arg.timers = &e2apDb->e2Timers.e2SetupTimer;
+         arg.max = MAX_E2_SETUP_TMR;
+         break;
+      }
+      default:
+      {
+         DU_LOG("\nERROR  -->  DU : duStartTmr: Invalid tmr Evnt [%d]", tmrEvnt);
+      }
+   }
+
+   if(arg.wait != 0)
+   {
+      arg.tqCp   = &(duCb.duTimersInfo.tmrTqCp);
+      arg.tq     = duCb.duTimersInfo.tmrTq;
+      arg.cb     = cb;
+      arg.evnt   = tmrEvnt;
+      arg.tNum   = 0;
+
+      cmPlcCbTq(&arg);
+   }
+   return;
+}
+
+/**
+ * @brief Handler to invoke events on expiry of timer.
+ *
+ * @details
+ *    This function is used to handle expiry of timer,it invokes relevant
+ *    functions.
+ *
+ * @param[in] cb        Control block depending on the type of the timer event.
+ *                      It can be uplink/downlink rbCb or rgu sap control block
+ * @param[in] tmrEvnt   Timer event to be started
+ *
+ * @return  Void
+*/
+
+void duTmrExpiry(PTR cb,int16_t tmrEvnt)
+{
+   switch (tmrEvnt)
+   {
+      case EVENT_E2_SETUP_TMR:
+      {
+         BuildAndSendE2SetupReq();
+         break;
+      }
+      default:
+      {
+         DU_LOG("\nERROR  -->  DU : duStartTmr: Invalid tmr Evnt [%d]", tmrEvnt);
+         break;
+      }
+   }
+
+   return;
+}
+
+/**
+ * @brief DU instance timer call back function registered with system services.
+ *
+ * @details
+ *
+ *     Function :  duActvTmr
+ *
+ *     This function is invoked for every timer activation
+ *     period expiry. Note that SS_MT_TMR flag needs to be enabled for this
+ *     as isntId is needed.As part of SRegTmr call for du instance
+ *     SS_MT_TMR flag needs to be enabled and duActvTmr needs to be given as
+ *     callback function
+ *
+ *  @return  short int
+ *      -# ROK
+ **/
+
+short int duActvTmr(Ent ent,Inst inst)
+{
+   /* Check if any timer in the du instance has expired */
+   cmPrcTmr(&(duCb.duTimersInfo.tmrTqCp), duCb.duTimersInfo.tmrTq, (PFV) duTmrExpiry);
+
+   return ROK;
+
+} /* end of duActvTmr */
+
+/**********************************************************************
+
+         End of file
+**********************************************************************/
+
diff --git a/src/du_app/du_tmr.h b/src/du_app/du_tmr.h
new file mode 100644 (file)
index 0000000..d7529b7
--- /dev/null
@@ -0,0 +1,50 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   Licensed under the Apache License, Version 2.0 (the "License");            #
+#   you may not use this file except in compliance with the License.           #
+#   You may obtain a copy of the License at                                    #
+#                                                                              #
+#       http://www.apache.org/licenses/LICENSE-2.0                             #
+#                                                                              #
+#   Unless required by applicable law or agreed to in writing, software        #
+#   distributed under the License is distributed on an "AS IS" BASIS,          #
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
+#   See the License for the specific language governing permissions and        #
+#   limitations under the License.                                             #
+################################################################################
+*******************************************************************************/
+
+#define DU_TIMER_RESOLUTION 1
+#define DU_TQ_SIZE 2
+
+/**
+ * @def DU_TMR_CALCUATE_WAIT
+ *
+ *    This macro calculates and assigns wait time based on the value of the
+ *    timer and the timer resolution. Timer value of 0 signifies that the
+ *    timer is not configured
+ *
+ * @param[out] _wait   Time for which to arm the timer changed to proper
+ *                     value according to the resolution
+ * @param[in] _tmrVal   Value of the timer
+ * @param[in] _timerRes   Resolution of the timer
+ *
+*/
+#define DU_TMR_CALCUATE_WAIT(_wait, _tmrVal, _timerRes)       \
+{                                                             \
+   (_wait) = ((_tmrVal) * SS_TICKS_SEC)/((_timerRes) * 1000); \
+   if((0 != (_tmrVal)) && (0 == (_wait)))                     \
+   {                                                          \
+      (_wait) = 1;                                            \
+   }                                                          \
+}
+
+short int duActvTmr(Ent ent,Inst inst); 
+bool duChkTmr(PTR cb, int16_t tmrEvnt);
+void duStartTmr(PTR cb, int16_t tmrEvnt, uint8_t timerValue);
+
+/**********************************************************************
+  End of file
+ **********************************************************************/
index cf5df23..7d75f00 100644 (file)
@@ -18,6 +18,7 @@
 /* This file contains UE management handling functionality for DU APP */
 #include "common_def.h"
 #include "lrg.h"
+#include "du_tmr.h"
 #include "lrg.x"
 #include "ckw.h"
 #include "ckw.x"
index 882eef9..e6544ac 100644 (file)
@@ -17,6 +17,7 @@
  *******************************************************************************/
 /* Utility definitions to be used in du app */
 #include "common_def.h"
+#include "du_tmr.h"
 #include "lrg.h"
 #include "lrg.x"
 #include "lkw.x"
index 7db9c35..4ee806d 100644 (file)
@@ -28,6 +28,7 @@
 #include "ProtocolIE-FieldE2.h"
 #include "InitiatingMessageE2.h"
 #include "SuccessfulOutcomeE2.h"
+#include "UnsuccessfulOutcomeE2.h"
 #include "E2AP-PDU.h"
 #include "du_log.h"
 #include "E2nodeComponentInterfaceF1.h"
@@ -245,7 +246,7 @@ uint8_t BuildE2nodeComponentConfigAdditionAck(E2nodeComponentConfigAdditionAck_L
  *         RFAILED - failure
  *
  * ****************************************************************/
-uint8_t BuildAndSendE2SetupRsp(uint32_t duId)
+uint8_t BuildAndSendE2SetupRsp(uint32_t duId, uint8_t transId)
 {
    E2AP_PDU_t         *e2apMsg = NULL;
    E2setupResponse_t  *e2SetupRsp;
@@ -279,7 +280,7 @@ uint8_t BuildAndSendE2SetupRsp(uint32_t duId)
 
       elementCnt = 3;
       e2SetupRsp->protocolIEs.list.count = elementCnt;
-      e2SetupRsp->protocolIEs.list.size  = elementCnt * sizeof(E2setupResponseIEs_t);
+      e2SetupRsp->protocolIEs.list.size  = elementCnt * sizeof(E2setupResponseIEs_t*);
 
       RIC_ALLOC(e2SetupRsp->protocolIEs.list.array, e2SetupRsp->protocolIEs.list.size);
       if(e2SetupRsp->protocolIEs.list.array == NULLP)
@@ -309,7 +310,7 @@ uint8_t BuildAndSendE2SetupRsp(uint32_t duId)
       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_TransactionID;
       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
       e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_TransactionID; 
-      e2SetupRsp->protocolIEs.list.array[idx]->value.choice.TransactionID  = TRANS_ID;
+      e2SetupRsp->protocolIEs.list.array[idx]->value.choice.TransactionID  = transId;
 
       /* Global RIC ID */
       idx++;
@@ -671,6 +672,170 @@ void ProcRicSubscriptionResponse(uint32_t duId)
       duDb->ricSubscribedToDu = true;
 }
 
+/*******************************************************************
+ *
+ * @brief deallocate the memory allocated in E2SetupFailure
+ *
+ * @details
+ *
+ *    Function : FreeE2SetupFailure 
+ *
+ *    Functionality: deallocate the memory allocated in E2SetupFailure 
+ *
+ * @params[in] E2AP_PDU_t *e2apMsg
+ *
+ * @return void
+ * ****************************************************************/
+void FreeE2SetupFailure(E2AP_PDU_t *e2apMsg)
+{
+   uint8_t arrIdx = 0;
+   E2setupFailure_t  *e2SetupFail;
+
+   if(e2apMsg)
+   {
+      if(e2apMsg->choice.unsuccessfulOutcome)
+      {
+         e2SetupFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
+         if(e2SetupFail->protocolIEs.list.array)
+         {
+            for(arrIdx=0; arrIdx<e2SetupFail->protocolIEs.list.count; arrIdx++)
+            {
+               RIC_FREE(e2SetupFail->protocolIEs.list.array[arrIdx], sizeof(E2setupFailureIEs_t)); 
+            }
+            RIC_FREE(e2SetupFail->protocolIEs.list.array, e2SetupFail->protocolIEs.list.size);
+         }
+         RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
+      }
+      RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Buld and send the E2 Setup failure
+ *
+ * @details
+ *
+ *    Function : BuildAndSendE2SetupFailure
+ *
+ *    Functionality:
+ *         - Buld and send the E2 Setup failure
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+
+uint8_t BuildAndSendE2SetupFailure(uint32_t duId, uint8_t transId)
+{
+   E2AP_PDU_t         *e2apMsg = NULL;
+   E2setupFailure_t   *e2SetupFailure;
+   asn_enc_rval_t     encRetVal;
+   uint8_t            arrIdx;
+   uint8_t            elementCnt;
+   bool  memAllocFailed = false;
+
+   DU_LOG("\nINFO   -->  E2AP : Building E2 Setup failure\n");
+   while(true)
+   {
+      RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
+      if(e2apMsg == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
+         break;
+      }
+      e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
+      RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
+      if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
+         break;
+      }
+
+      e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
+      e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
+      e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2setupFailure;
+      e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
+
+      elementCnt = 3;
+      e2SetupFailure->protocolIEs.list.count = elementCnt;
+      e2SetupFailure->protocolIEs.list.size  = elementCnt * sizeof(struct E2setupFailureIEs *);
+
+      RIC_ALLOC(e2SetupFailure->protocolIEs.list.array, e2SetupFailure->protocolIEs.list.size);
+      if(e2SetupFailure->protocolIEs.list.array == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
+         break;
+      }
+
+      for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
+      {
+         RIC_ALLOC(e2SetupFailure->protocolIEs.list.array[arrIdx], sizeof(struct E2setupFailureIEs));
+         if(e2SetupFailure->protocolIEs.list.array[arrIdx] == NULLP)
+         {
+            DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
+            memAllocFailed = true;
+            break;
+         }
+      }
+
+      if(memAllocFailed == true)
+      {
+          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
+          break;
+      }
+
+      /* Trans Id */
+      arrIdx = 0;
+      e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
+      e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
+      e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TransactionID;
+      e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
+
+      arrIdx++;
+      e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
+      e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
+      e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_CauseE2;
+      e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.present = CauseE2_PR_protocol;
+      e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.protocol = CauseE2Protocol_unspecified;
+
+      arrIdx++;
+      e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
+      e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
+      e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TimeToWaitE2;
+      e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
+
+      xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
+      memset(encBuf, 0, ENC_BUF_MAX_LEN);
+      encBufSize = 0;
+      encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
+
+      /* Check encode results */
+      if(encRetVal.encoded == ENCODE_FAIL)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Setup failure structure (at %s)\n",\
+               encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+         break;
+      }
+      else
+      {
+         DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Setup Failure\n");
+         for(int i=0; i< encBufSize; i++)
+         {
+            DU_LOG("%x",encBuf[i]);
+         }
+      }
+
+      if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Failure failed");
+         break;
+      }
+      break;
+   }
+
+   FreeE2SetupFailure(e2apMsg);
+}
+
 /*******************************************************************
  *
  * @brief process the e2setup request 
@@ -688,7 +853,7 @@ void ProcRicSubscriptionResponse(uint32_t duId)
 
 uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
 {
-   uint8_t arrIdx = 0, e2NodeAddListIdx =0, duIdx = 0;
+   uint8_t arrIdx = 0, e2NodeAddListIdx =0, duIdx = 0, transId =0;
    DuDb    *duDb = NULLP;
    E2nodeComponentConfigAddition_List_t *e2NodeAddList;
    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
@@ -703,6 +868,11 @@ uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
                {
                   switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
                   {
+                     case ProtocolIE_IDE2_id_TransactionID:
+                     {
+                        transId = e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; 
+                        break;
+                     }
                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
                      {
                         e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;      
@@ -730,7 +900,7 @@ uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
                                        memset(duDb, 0, sizeof(DuDb));
                                        duDb->duId = *duId;
 
-                                       if(BuildAndSendE2SetupRsp(*duId) !=ROK)
+                                       if(BuildAndSendE2SetupRsp(*duId, transId) !=ROK)
                                        {
                                            DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 setup response");
                                            return RFAILED;
index 15caa79..dfd816f 100644 (file)
@@ -52,7 +52,7 @@
 
 
 void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf);
-uint8_t BuildAndSendE2SetupRsp(uint32_t duId);
+uint8_t BuildAndSendE2SetupRsp(uint32_t duId, uint8_t transId);
 uint8_t BuildAndSendRicSubscriptionReq(uint32_t duId);
 uint8_t SendE2APMsg(Region region, Pool pool, uint32_t duId);