From a50cee433ee06d6a8a4215c274432ab4ad8fdb26 Mon Sep 17 00:00:00 2001 From: "lal.harshita" Date: Fri, 9 Jun 2023 15:31:13 +0530 Subject: [PATCH] [Epic-ID: ODUHIGH-510][Task-ID: ODUHIGH-514] DU-initiated E2 Reset Procedure Change-Id: Ica5597cfe641f1271a0d193bcb90e693d112eef6 Signed-off-by: lal.harshita --- src/du_app/du_cell_mgr.c | 1 + src/du_app/du_cfg.c | 4 + src/du_app/du_e2ap_mgr.c | 166 +++++++++++++ src/du_app/du_e2ap_mgr.h | 128 ++++++++++ src/du_app/du_e2ap_msg_hdl.c | 517 +++++++++++++++++++++++++++++----------- src/du_app/du_e2ap_msg_hdl.h | 23 +- src/du_app/du_egtp.c | 1 + src/du_app/du_f1ap_msg_hdl.c | 3 +- src/du_app/du_mgr.h | 1 + src/du_app/du_mgr_main.c | 1 + src/du_app/du_mgr_msg_router.c | 3 +- src/du_app/du_msg_hdl.c | 1 + src/du_app/du_sctp.c | 1 + src/du_app/du_sys_info_hdl.c | 1 + src/du_app/du_ue_mgr.c | 1 + src/du_app/du_utils.c | 1 + src/ric_stub/ric_e2ap_msg_hdl.c | 318 ++++++++++++++++++++---- 17 files changed, 971 insertions(+), 200 deletions(-) create mode 100644 src/du_app/du_e2ap_mgr.c create mode 100644 src/du_app/du_e2ap_mgr.h diff --git a/src/du_app/du_cell_mgr.c b/src/du_app/du_cell_mgr.c index 286d2db88..a09e43591 100644 --- a/src/du_app/du_cell_mgr.c +++ b/src/du_app/du_cell_mgr.c @@ -26,6 +26,7 @@ #include "rgr.x" #include "du_app_mac_inf.h" #include "du_app_rlc_inf.h" +#include "du_e2ap_mgr.h" #include "du_cfg.h" #include "du_mgr.h" #include "du_utils.h" diff --git a/src/du_app/du_cfg.c b/src/du_app/du_cfg.c index fe4ef425b..335415ca4 100644 --- a/src/du_app/du_cfg.c +++ b/src/du_app/du_cfg.c @@ -24,6 +24,7 @@ #include "lrg.x" #include "du_app_mac_inf.h" #include "du_app_rlc_inf.h" +#include "du_e2ap_mgr.h" #include "du_cfg.h" #include "du_mgr.h" #include "du_utils.h" @@ -600,6 +601,9 @@ uint8_t readCfg() Sib1Params sib1; F1TaiSliceSuppLst *taiSliceSuppLst; + duCb.e2apDb.transIdCounter = 0; + memset(duCb.e2apDb.onGoingTransaction, 0, MAX_NUM_TRANSACTION * sizeof(E2TransInfo)); + #ifndef O1_ENABLE /* Note: Added these below variable for local testing*/ Snssai snssai[NUM_OF_SUPPORTED_SLICE] = {{1,{2,3,4}},{5,{6,7,8}}}; diff --git a/src/du_app/du_e2ap_mgr.c b/src/du_app/du_e2ap_mgr.c new file mode 100644 index 000000000..83ab35a30 --- /dev/null +++ b/src/du_app/du_e2ap_mgr.c @@ -0,0 +1,166 @@ +/******************************************************************************* +################################################################################ +# 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 "lrg.h" +#include "lkw.x" +#include "lrg.x" +#include "legtp.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" +#include "du_mgr.h" +#include "du_mgr_main.h" +#include "du_utils.h" + +/******************************************************************* + * + * @brief Assigns new transaction id to DU initiated procedure + * + * @details + * + * Function : assignTransactionId + * + * Functionality: Assigns new transaction id to a DU initiated + * procedure + * + * @params[in] Region region + * Pool pool + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t assignTransactionId() +{ + uint8_t currTransId = duCb.e2apDb.transIdCounter; + + /* Update to next valid value */ + duCb.e2apDb.transIdCounter++; + if(duCb.e2apDb.transIdCounter == MAX_NUM_TRANSACTION) + duCb.e2apDb.transIdCounter = 0; + + return currTransId; +} + +/******************************************************************* + * + * @brief Sends E2 msg over SCTP + * + * @details + * + * Function : SendE2APMsg + * + * Functionality: Sends E2 msg over SCTP + * + * @params[in] Region region + * Pool pool + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + +uint8_t SendE2APMsg(Region region, Pool pool, char *encBuf, int encBufSize) +{ + Buffer *mBuf=NULLP; + + if(ODU_GET_MSG_BUF(region, pool, &mBuf) == ROK) + { + if(ODU_ADD_POST_MSG_MULT((Data *)encBuf, encBufSize, mBuf) == ROK) + { + ODU_PRINT_MSG(mBuf, 0,0); + + if(sctpSend(mBuf, E2_INTERFACE) != ROK) + { + DU_LOG("\nERROR --> E2AP : SCTP Send for E2 failed"); + ODU_PUT_MSG_BUF(mBuf); + return RFAILED; + } + } + else + { + DU_LOG("\nERROR --> E2AP : ODU_ADD_POST_MSG_MULT failed"); + ODU_PUT_MSG_BUF(mBuf); + return RFAILED; + } + ODU_PUT_MSG_BUF(mBuf); + } + else + { + DU_LOG("\nERROR --> E2AP : Failed to allocate memory"); + return RFAILED; + } + + return ROK; +} /* SendE2APMsg */ + +/******************************************************************* + * + * @brief Resets E2 + * + * @details + * + * Function : ResetE2Request + * + * Functionality: This function resets E2. + * As per ORAN WG3 E2GAP v3.0 Spec, section 5.5.3 + * If E2 node initates reset procedure then: + * a. Send reset request to RIC + * b. Delete any pre-established RIC subscriptions + * c. Gracefully terminates any ongoing RIC services + * If RIC initiates reset procedure then : + * a. Delete any pre-established RIC subscriptions + * b. Gracefully terminates any ongoing RIC services + * c. Send reset response to RIC + * + * @params[in] + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t ResetE2Request(E2ProcedureDirection dir, E2CauseType type, E2Cause cause) +{ + /* Send Reset Request to RIC if DU detects any abnormal failure */ + if(dir == E2_NODE_INITIATED) + { + if(BuildAndSendE2ResetRequest(type, cause) != ROK) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendE2ResetRequest failed"); + return RFAILED; + } + } + + /* TODO when RIC subscription service model is implemented + Process following steps of resetting E2 + 1. Deletes any pre-established RIC subscriptions + 2. Gracefully terminates any ongoing RIC services + */ + + /* Send Reset Response if RIC initiated Reset request is received at DU */ + if(dir == RIC_INITIATED) + { + //BuildAndSendE2ResetResponse(); + } + return ROK; +} + +/********************************************************************** + End of file + **********************************************************************/ + diff --git a/src/du_app/du_e2ap_mgr.h b/src/du_app/du_e2ap_mgr.h new file mode 100644 index 000000000..9fea513c7 --- /dev/null +++ b/src/du_app/du_e2ap_mgr.h @@ -0,0 +1,128 @@ +/******************************************************************************* +################################################################################ +# 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 all E2AP message handler related functionality */ + +#define MAX_NUM_TRANSACTION 256 /* As per, O-RAN WG3 E2AP v3.0, section 9.2.33 */ + +typedef enum +{ + RIC_INITIATED, + E2_NODE_INITIATED +}E2ProcedureDirection; + +typedef enum +{ + E2_RAN_FUNCTION_ID_INVALID, + E2_ACTION_NOT_SUPPORTED, + E2_EXECESSIVE_ACTIONS, + E2_DUPLICATE_ACTION, + E2_DUPLICATE_EVENT_TRIGGER, + E2_FUNCTION_RESOURCE_LIMIT, + E2_REQUEST_ID_UNKNOWN, + E2_INCONSISTENT_ACTION_SUBSEQUENT_ACTION_SEQUENCE, + E2_CONTROL_MESSAGE_INVALID, + E2_RIC_CALL_PROCESS_ID_INVALID, + E2_CONTROL_TIMER_EXPIRED, + E2_CONTROL_FAILED_TO_EXECUTE, + E2_SYSTEM_NOT_READY, + E2_RIC_REQUEST_CAUSE_UNSPECIFIED, + E2_RIC_SUBSCRIPTION_END_TIME_EXPIRED, + E2_RIC_SUBSCRIPTION_END_TIME_INVALID, + E2_DUPLICATE_RIC_REQUEST_ID, + E2_EVENT_TRIGGER_NOT_SUPPORTED, + E2_REQUEST_INFORMATION_UNAVAILABLE, + E2_INVALID_INFORMATION_REQUEST +}E2CauseRicRequest; + +typedef enum +{ + E2_RAN_FUNCTION_NOT_SUPPORTED, + E2_EXCESSIVE_FUNCTIONS, + E2_RIC_RESOURCE_LIMIT, +}E2CauseRicService; + +typedef enum +{ + E2_NODE_COMPONENT_UNKNOWN +}E2CauseE2Node; + +typedef enum +{ + E2_TRANSPORT_CAUSE_UNSPECIFIED, + E2_TRANSPORT_RESOURCE_UNAVAILABLE +}E2CauseTransport; + +typedef enum +{ + E2_TRANSFER_SYNTAX_ERROR, + E2_ABSTRACT_SYNTAX_ERROR_REJECT, + E2_ABSTRACT_SYNTAX_ERROR_IGNORE_AND_NOTIFY, + E2_MESSAGE_NOT_COMPATIBLE_WITH_RECEIVER_STATE, + E2_SEMANTIC_ERROR, + E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE, + E2_PROTOCOL_CAUSE_UNSPECIFIED +}E2CauseProtocol; + +typedef enum +{ + E2_CONTROL_PROCESSING_OVERLOAD, + E2_HARDWARE_FAILURE, + E2_OM_INTERVENTION, + E2_MISCELLANEOUS_CAUSE_UNSPECIFIED +}E2CauseMisc; + +typedef enum +{ + E2_NOTHING, + E2_RIC_REQUEST, + E2_RIC_SERVICE, + E2_NODE, + E2_TRANSPORT, + E2_PROTOCOL, + E2_MISCELLANEOUS +}E2CauseType; + +typedef uint8_t E2Cause; + +typedef struct +{ + uint8_t transactionId; + uint8_t procedureCode; +}E2TransInfo; + +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; +}E2apDb; + +uint8_t assignTransactionId(); +uint8_t ResetE2Request(E2ProcedureDirection dir, E2CauseType type, E2Cause cause); +uint8_t SendE2APMsg(Region region, Pool pool, char *encBuf, int encBufSize); +/********************************************************************** + End of file + **********************************************************************/ diff --git a/src/du_app/du_e2ap_msg_hdl.c b/src/du_app/du_e2ap_msg_hdl.c index b01fcb2fb..e048d6d15 100644 --- a/src/du_app/du_e2ap_msg_hdl.c +++ b/src/du_app/du_e2ap_msg_hdl.c @@ -22,17 +22,18 @@ #include "legtp.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_mgr.h" #include "du_mgr_main.h" #include "du_utils.h" #include "GlobalE2node-gNB-ID.h" -#include +#include "ProtocolIE-FieldE2.h" #include "E2setupRequest.h" #include "InitiatingMessageE2.h" #include "SuccessfulOutcomeE2.h" #include "E2AP-PDU.h" -#include "du_e2ap_msg_hdl.h" #include "odu_common_codec.h" #include "E2nodeComponentInterfaceF1.h" #include "E2setupRequest.h" @@ -483,7 +484,7 @@ uint8_t BuildAndSendE2SetupReq() } #endif } - if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL) != ROK) + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) { DU_LOG("\nERROR --> E2AP : Sending E2 Setup request failed"); } @@ -851,7 +852,7 @@ uint8_t BuildAndSendRicSubscriptionRsp() #endif } - if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL) != ROK) + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) { DU_LOG("\nERROR --> E2AP : Sending RIC Subscription Response failed"); break; @@ -973,15 +974,15 @@ uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg) /* To store the Ric Id Params */ recvBufLen = sizeof(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value\ .choice.GlobalRIC_ID.pLMN_Identity.size); - e2apMsgDb.plmn = NULLP; - DU_ALLOC(e2apMsgDb.plmn, recvBufLen); - if(e2apMsgDb.plmn) + duCb.e2apDb.plmn = NULLP; + DU_ALLOC(duCb.e2apDb.plmn, recvBufLen); + if(duCb.e2apDb.plmn) { - memcpy(e2apMsgDb.plmn, e2SetRspMsg->protocolIEs.list.array[arrIdx]\ + memcpy(duCb.e2apDb.plmn, e2SetRspMsg->protocolIEs.list.array[arrIdx]\ ->value.choice.GlobalRIC_ID.pLMN_Identity.buf, recvBufLen); } - bitStringToInt(&e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID, &e2apMsgDb.ricId); - /*TODO : e2apMsgDb.plmn memory to be deallocated after the usage */ + bitStringToInt(&e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID, &duCb.e2apDb.ricId); + /*TODO : duCb.e2apDb.plmn memory to be deallocated after the usage */ break; } @@ -1031,73 +1032,73 @@ uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg) { if(ricSubsReq->protocolIEs.list.array[idx]) { - switch(ricSubsReq->protocolIEs.list.array[idx]->id) - { - case ProtocolIE_IDE2_id_RICrequestID: - { - e2apMsgDb.ricReqId = ricSubsReq->protocolIEs.list.array[idx]->\ - value.choice.RICrequestID.ricRequestorID; - e2apMsgDb.ricInstanceId = ricSubsReq->protocolIEs.list.array[idx]-> \ - value.choice.RICrequestID.ricInstanceID; - break; - } - case ProtocolIE_IDE2_id_RANfunctionID: - { - e2apMsgDb.ranFuncId = ricSubsReq->protocolIEs.list.array[idx]-> \ - value.choice.RANfunctionID; - break; - } - case ProtocolIE_IDE2_id_RICsubscriptionDetails: - { - recvBufLen = sizeof(ricSubsReq->protocolIEs.list.array[idx]->value\ - .choice.RICsubscriptionDetails.ricEventTriggerDefinition.size); - e2apMsgDb.ricEventTrigger = NULLP; - DU_ALLOC(e2apMsgDb.ricEventTrigger, recvBufLen); - /*TODO : e2apMsgDb.ricEventTrigger memory to be deallocated after the usage */ - if(e2apMsgDb.ricEventTrigger) - { - memcpy(e2apMsgDb.ricEventTrigger, ricSubsReq->protocolIEs.list.array[idx]\ - ->value.choice.RICsubscriptionDetails.ricEventTriggerDefinition.buf, \ - recvBufLen); - free(ricSubsReq->protocolIEs.list.array[idx]->value.choice.\ - RICsubscriptionDetails.ricEventTriggerDefinition.buf); - } - if(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\ - list.array) - { - actionItem =(RICaction_ToBeSetup_ItemIEs_t *)ricSubsReq->protocolIEs.list\ - .array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List\ - .list.array[0]; + switch(ricSubsReq->protocolIEs.list.array[idx]->id) + { + case ProtocolIE_IDE2_id_RICrequestID: + { + duCb.e2apDb.ricReqId = ricSubsReq->protocolIEs.list.array[idx]->\ + value.choice.RICrequestID.ricRequestorID; + duCb.e2apDb.ricInstanceId = ricSubsReq->protocolIEs.list.array[idx]-> \ + value.choice.RICrequestID.ricInstanceID; + break; + } + case ProtocolIE_IDE2_id_RANfunctionID: + { + duCb.e2apDb.ranFuncId = ricSubsReq->protocolIEs.list.array[idx]-> \ + value.choice.RANfunctionID; + break; + } + case ProtocolIE_IDE2_id_RICsubscriptionDetails: + { + recvBufLen = sizeof(ricSubsReq->protocolIEs.list.array[idx]->value\ + .choice.RICsubscriptionDetails.ricEventTriggerDefinition.size); + duCb.e2apDb.ricEventTrigger = NULLP; + DU_ALLOC(duCb.e2apDb.ricEventTrigger, recvBufLen); + /*TODO : duCb.e2apDb.ricEventTrigger memory to be deallocated after the usage */ + if(duCb.e2apDb.ricEventTrigger) + { + memcpy(duCb.e2apDb.ricEventTrigger, ricSubsReq->protocolIEs.list.array[idx]\ + ->value.choice.RICsubscriptionDetails.ricEventTriggerDefinition.buf, \ + recvBufLen); + free(ricSubsReq->protocolIEs.list.array[idx]->value.choice.\ + RICsubscriptionDetails.ricEventTriggerDefinition.buf); + } + if(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\ + list.array) + { + actionItem =(RICaction_ToBeSetup_ItemIEs_t *)ricSubsReq->protocolIEs.list\ + .array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List\ + .list.array[0]; - for(ied = 0; ied < ricSubsReq->protocolIEs.list.array[idx]->value.choice.\ - RICsubscriptionDetails.ricAction_ToBeSetup_List.list.count; ied++) - { - switch(actionItem->id) - { - case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item: - { - e2apMsgDb.ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID; - e2apMsgDb.ricActionType = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType; - break; - } - default: - DU_LOG("\nERROR --> E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id); - break; - } - free(actionItem); - } - free(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\ - list.array); - } - break; - } + for(ied = 0; ied < ricSubsReq->protocolIEs.list.array[idx]->value.choice.\ + RICsubscriptionDetails.ricAction_ToBeSetup_List.list.count; ied++) + { + switch(actionItem->id) + { + case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item: + { + duCb.e2apDb.ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID; + duCb.e2apDb.ricActionType = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType; + break; + } + default: + DU_LOG("\nERROR --> E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id); + break; + } + free(actionItem); + } + free(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\ + list.array); + } + break; + } - default: - DU_LOG("\nERROR --> E2AP : Invalid IE received in RIC SubsReq:%ld", - ricSubsReq->protocolIEs.list.array[idx]->id); - break; - } - free(ricSubsReq->protocolIEs.list.array[idx]); + default: + DU_LOG("\nERROR --> E2AP : Invalid IE received in RIC SubsReq:%ld", + ricSubsReq->protocolIEs.list.array[idx]->id); + break; + } + free(ricSubsReq->protocolIEs.list.array[idx]); } } free(ricSubsReq->protocolIEs.list.array); @@ -1231,9 +1232,9 @@ uint8_t FillRicIndication(RICindication_t *ricIndicationMsg) ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \ RICindication_IEs__value_PR_RICrequestID; ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID =\ - e2apMsgDb.ricReqId; + duCb.e2apDb.ricReqId; ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID =\ - e2apMsgDb.ricInstanceId; + duCb.e2apDb.ricInstanceId; idx++; ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID; @@ -1241,7 +1242,7 @@ uint8_t FillRicIndication(RICindication_t *ricIndicationMsg) ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \ RICindication_IEs__value_PR_RANfunctionID; ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = - e2apMsgDb.ranFuncId; + duCb.e2apDb.ranFuncId; idx++; ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID; @@ -1249,7 +1250,7 @@ uint8_t FillRicIndication(RICindication_t *ricIndicationMsg) ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \ RICindication_IEs__value_PR_RICactionID; ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = - e2apMsgDb.ricActionId; + duCb.e2apDb.ricActionId; idx++; ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType; @@ -1257,7 +1258,7 @@ uint8_t FillRicIndication(RICindication_t *ricIndicationMsg) ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \ RICindication_IEs__value_PR_RICindicationType; ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = - e2apMsgDb.ricActionType; + duCb.e2apDb.ricActionType; idx++; ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader; @@ -1379,7 +1380,7 @@ uint8_t BuildAndSendRicIndication() #endif } - if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL) != ROK) + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) { DU_LOG("\nINFO --> E2AP : Sending RIC Indication Message"); @@ -1391,57 +1392,6 @@ uint8_t BuildAndSendRicIndication() return ret; } -/******************************************************************* - * - * @brief Sends E2 msg over SCTP - * - * @details - * - * Function : SendE2APMsg - * - * Functionality: Sends E2 msg over SCTP - * - * @params[in] Region region - * Pool pool - * @return ROK - success - * RFAILED - failure - * - * ****************************************************************/ - -uint8_t SendE2APMsg(Region region, Pool pool) -{ - Buffer *mBuf=NULLP; - - if(ODU_GET_MSG_BUF(region, pool, &mBuf) == ROK) - { - if(ODU_ADD_POST_MSG_MULT((Data *)encBuf, encBufSize, mBuf) == ROK) - { - ODU_PRINT_MSG(mBuf, 0,0); - - if(sctpSend(mBuf, E2_INTERFACE) != ROK) - { - DU_LOG("\nERROR --> E2AP : SCTP Send for E2 failed"); - ODU_PUT_MSG_BUF(mBuf); - return RFAILED; - } - } - else - { - DU_LOG("\nERROR --> E2AP : ODU_ADD_POST_MSG_MULT failed"); - ODU_PUT_MSG_BUF(mBuf); - return RFAILED; - } - ODU_PUT_MSG_BUF(mBuf); - } - else - { - DU_LOG("\nERROR --> E2AP : Failed to allocate memory"); - return RFAILED; - } - - return ROK; -} /* SendE2APMsg */ - /******************************************************************* * * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg @@ -1583,7 +1533,7 @@ uint8_t BuildAndSendE2NodeConfigUpdate() } #endif } - if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL) != ROK) + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize)) { DU_LOG("\nERROR --> E2AP : Sending E2 node config update failed"); return RFAILED; @@ -1596,6 +1546,300 @@ uint8_t BuildAndSendE2NodeConfigUpdate() return ret; } +/******************************************************************* + * + * @brief Deallocate the memory allocated for E2ResetRequest msg + * + * @details + * + * Function : FreeE2ResetRequest + * + * Functionality: + * - freeing the memory allocated for E2ResetRequest + * + * @params[in] E2AP_PDU_t *e2apMsg + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg) +{ + uint8_t ieIdx =0; + ResetRequestE2_t *resetReq = NULLP; + + if(e2apMsg != NULLP) + { + if(e2apMsg->choice.initiatingMessage != NULLP) + { + resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2; + if(resetReq->protocolIEs.list.array) + { + for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++) + { + DU_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t)); + } + DU_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size); + } + DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + } + DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); + } +} + +/******************************************************************* + * + * @brief Build and send the E2 reset request msg + * + * @details + * + * Function : BuildAndSendE2ResetRequest + * + * Functionality: + * - Buld and send the E2 reset request msg to RIC + * + * @params[in] + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t BuildAndSendE2ResetRequest(E2CauseType failureType, E2Cause failureCause) +{ + uint8_t ieIdx = 0, elementCnt = 0, transId = 0; + uint8_t ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + ResetRequestE2_t *resetReq = NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ + + DU_LOG("\nINFO --> E2AP : Building E2 Reset Request\n"); + + do + { + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendE2ResetRequest(): Memory allocation for E2AP-PDU failed"); + break; + } + + e2apMsg->present = E2AP_PDU_PR_initiatingMessage; + DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + if(e2apMsg->choice.initiatingMessage == NULLP) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendE2ResetRequest(): Memory allocation for initiatingMessage"); + break; + } + + e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset; + e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject; + e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2; + resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2; + + elementCnt = 2; + resetReq->protocolIEs.list.count = elementCnt; + resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *); + + DU_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size); + if(!resetReq->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \ + Reset Request IE array"); + break; + } + + for(ieIdx = 0; ieIdx < elementCnt; ieIdx++) + { + DU_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t)); + if(!resetReq->protocolIEs.list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \ + Reset Request IE array element"); + break; + } + } + + /* In case of failure */ + if(ieIdx < elementCnt) + break; + + ieIdx = 0; + resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID; + resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject; + resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID; + transId = assignTransactionId(); + resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId; + + ieIdx++; + resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2; + resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore; + resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2; + resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present = failureType; + switch(resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present) + { + case CauseE2_PR_NOTHING: + break; + case CauseE2_PR_ricRequest: + resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricRequest = failureCause; + break; + case CauseE2_PR_ricService: + resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricService = failureCause; + break; + case CauseE2_PR_e2Node: + resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.e2Node = failureCause; + break; + case CauseE2_PR_transport: + resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.transport = failureCause; + break; + case CauseE2_PR_protocol: + resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.protocol = failureCause; + break; + case CauseE2_PR_misc: + resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.misc = failureCause; + break; + } + + /* Prints the Msg formed */ + 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); + if(encRetVal.encoded == ENCODE_FAIL) + { + DU_LOG("\nERROR --> E2AP : Could not encode E2SetupRequest structure (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2SetupRequest\n"); +#ifdef DEBUG_ASN_PRINT + for(int i=0; i< encBufSize; i++) + { + printf("%x",encBuf[i]); + } +#endif + } + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) + { + DU_LOG("\nERROR --> E2AP : Sending E2 Setup request failed"); + break; + } + + /* 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; + + ret = ROK; + break; + }while(true); + + /* Free all memory */ + FreeE2ResetRequest(e2apMsg); + return ret; +} + +/******************************************************************* + * + * @brief Deallocate the memory allocated for Reset Response msg + * + * @details + * + * Function : freeAperDecodingOfE2ResetRsp + * + * Functionality: + * - freeing the memory allocated for Reset response + * + * @params[in] ResetResponseE2_t *resetResponse + * @return void + * + * ****************************************************************/ +void freeAperDecodingOfE2ResetRsp(ResetResponseE2_t *resetResponse) +{ + uint8_t ieIdx; + + if(resetResponse) + { + if(resetResponse->protocolIEs.list.array) + { + for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++) + { + if(resetResponse->protocolIEs.list.array[ieIdx]) + { + switch(resetResponse->protocolIEs.list.array[ieIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + break; + + case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2: + break; + } + free(resetResponse->protocolIEs.list.array[ieIdx]); + } + } + free(resetResponse->protocolIEs.list.array); + } + } +} + +/****************************************************************** + * + * @brief Processes E2 Reset Response sent by RIC + * + * @details + * + * Function : procResetResponse + * + * Functionality: Processes E2 Reset Response sent by RIC + * + * @params[in] E2AP_PDU_t ASN decoded E2AP message + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t procResetResponse(E2AP_PDU_t *e2apMsg) +{ + uint8_t ieIdx =0, transId; + ResetResponseE2_t *resetResponse; + + DU_LOG("\nINFO --> E2AP : E2 Reset Response received"); + resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;; + + for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++) + { + switch(resetResponse->protocolIEs.list.array[ieIdx]->id) + { + 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)); + else + { + DU_LOG("\nERROR --> E2AP : Invalid transaction id [%d]", transId); + return RFAILED; + } + break; + case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2: + /* As per ORAN WG3 E2AP spec v3.0, section 9.2.2 + Criticality Diagnostics IE is sent by Near-RT RIC when parts of a received message i.e. + Reset Request in this case, have not been comprehended or were missing, or if the message + contained logical errors. + + Processing of this ID should be implemented when negative call flows are to be supported. + */ + break; + default: + DU_LOG("\nERROR --> E2AP : Invalid IE received in E2 Reset Response : %ld", + resetResponse->protocolIEs.list.array[ieIdx]->id); + break; + } + } + + freeAperDecodingOfE2ResetRsp(resetResponse); + return ROK; +} + /******************************************************************* * * @brief Handles received E2AP message and sends back response @@ -1674,7 +1918,6 @@ void E2APMsgHdlr(Buffer *mBuf) { if(!duCb.e2Status) { - DU_LOG("\nDEBUG --> E2AP : Store E2 setup response Params"); procE2SetupRsp(e2apMsg); } break; @@ -1684,6 +1927,11 @@ void E2APMsgHdlr(Buffer *mBuf) DU_LOG("\nDEBUG --> E2AP : E2 node Config update ack message recevied"); break; } + case SuccessfulOutcomeE2__value_PR_ResetResponseE2: + { + procResetResponse(e2apMsg); + break; + } default: { DU_LOG("\nERROR --> E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome [%d]",\ @@ -1694,6 +1942,7 @@ void E2APMsgHdlr(Buffer *mBuf) free(e2apMsg->choice.successfulOutcome); break; } + case E2AP_PDU_PR_initiatingMessage: { switch(e2apMsg->choice.initiatingMessage->value.present) diff --git a/src/du_app/du_e2ap_msg_hdl.h b/src/du_app/du_e2ap_msg_hdl.h index a10fe03d0..8e6a9b1e0 100644 --- a/src/du_app/du_e2ap_msg_hdl.h +++ b/src/du_app/du_e2ap_msg_hdl.h @@ -20,25 +20,10 @@ #define ENCODE_FAIL -1 -uint8_t sctpSend(Buffer *mBuf, uint8_t itfType); - -typedef struct e2apDb -{ - uint16_t ricId; - uint8_t *plmn; - uint32_t ricReqId; - uint32_t ricInstanceId; - uint32_t ranFuncId; - uint8_t *ricEventTrigger; - uint32_t ricActionId; - uint32_t ricActionType; -}E2apMsgDb; - -E2apMsgDb e2apMsgDb; -uint8_t BuildAndSendE2SetupReq(); -uint8_t SendE2APMsg(Region , Pool ); -void E2APMsgHdlr(Buffer *mBuf); -uint8_t BuildAndSendE2NodeConfigUpdate(); +uint8_t BuildAndSendE2SetupReq(); +uint8_t BuildAndSendE2NodeConfigUpdate(); +uint8_t BuildAndSendE2ResetRequest(E2CauseType failureType, E2Cause failureCause); +void E2APMsgHdlr(Buffer *mBuf); /********************************************************************** End of file **********************************************************************/ diff --git a/src/du_app/du_egtp.c b/src/du_app/du_egtp.c index a4a8d8055..4cf5be761 100644 --- a/src/du_app/du_egtp.c +++ b/src/du_app/du_egtp.c @@ -25,6 +25,7 @@ #include "legtp.h" #include "cm_inet.x" #include "du_app_mac_inf.h" +#include "du_e2ap_mgr.h" #include "du_cfg.h" #include "du_egtp.h" #include "du_app_rlc_inf.h" diff --git a/src/du_app/du_f1ap_msg_hdl.c b/src/du_app/du_f1ap_msg_hdl.c index eeaa1d3b8..a8c6d541c 100644 --- a/src/du_app/du_f1ap_msg_hdl.c +++ b/src/du_app/du_f1ap_msg_hdl.c @@ -33,6 +33,8 @@ #include "du_app_mac_inf.h" #include "du_cfg.h" #include "du_app_rlc_inf.h" +#include "du_e2ap_mgr.h" +#include "du_e2ap_msg_hdl.h" #include "du_mgr_main.h" #include "du_mgr.h" #include "du_utils.h" @@ -160,7 +162,6 @@ #include "UPTransportLayerInformation.h" #include "GTPTunnel.h" #include "SupportedSULFreqBandItem.h" -#include "du_e2ap_msg_hdl.h" #include "du_f1ap_conversions.h" #include "CNUEPagingIdentity.h" #include "PCCH-Config.h" diff --git a/src/du_app/du_mgr.h b/src/du_app/du_mgr.h index 0cdc00d69..7904f4737 100644 --- a/src/du_app/du_mgr.h +++ b/src/du_app/du_mgr.h @@ -330,6 +330,7 @@ typedef struct duCb TskInit init; /* DU Init */ bool f1Status; /* Status of F1 connection */ bool e2Status; /* Status of E2 connection */ + E2apDb e2apDb; /* E2AP database */ uint8_t numCfgCells; /* number of configured cells */ DuCellCb* cfgCellLst[MAX_NUM_CELL]; /* List of cells at DU APP of type DuCellCb */ uint8_t numActvCells; /* Number of active cells */ diff --git a/src/du_app/du_mgr_main.c b/src/du_app/du_mgr_main.c index fd2902c9c..ead75959b 100644 --- a/src/du_app/du_mgr_main.c +++ b/src/du_app/du_mgr_main.c @@ -24,6 +24,7 @@ #include "lkw.x" #include "du_app_mac_inf.h" #include "du_app_rlc_inf.h" +#include "du_e2ap_mgr.h" #include "du_cfg.h" #include "du_mgr.h" #include "du_mgr_main.h" diff --git a/src/du_app/du_mgr_msg_router.c b/src/du_app/du_mgr_msg_router.c index da12de625..f548da7dd 100644 --- a/src/du_app/du_mgr_msg_router.c +++ b/src/du_app/du_mgr_msg_router.c @@ -29,13 +29,14 @@ #include "kwu.x" #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_mgr.h" #include "E2AP-PDU.h" #include "du_sctp.h" #include "F1AP-PDU.h" #include "du_f1ap_msg_hdl.h" -#include "du_e2ap_msg_hdl.h" #include "du_app_mac_inf.h" #include "du_ue_mgr.h" #include "du_utils.h" diff --git a/src/du_app/du_msg_hdl.c b/src/du_app/du_msg_hdl.c index e5b2f79d8..dfc80b608 100644 --- a/src/du_app/du_msg_hdl.c +++ b/src/du_app/du_msg_hdl.c @@ -27,6 +27,7 @@ #include "kwu.x" #include "du_app_mac_inf.h" #include "du_app_rlc_inf.h" +#include "du_e2ap_mgr.h" #include "du_cfg.h" #include "du_app_rlc_inf.h" #include "du_mgr.h" diff --git a/src/du_app/du_sctp.c b/src/du_app/du_sctp.c index 746fe012c..78048d7ae 100644 --- a/src/du_app/du_sctp.c +++ b/src/du_app/du_sctp.c @@ -25,6 +25,7 @@ #include "cm_inet.h" #include "cm_inet.x" #include "du_app_mac_inf.h" +#include "du_e2ap_mgr.h" #include "du_cfg.h" #include "du_sctp.h" #include "lsctp.h" diff --git a/src/du_app/du_sys_info_hdl.c b/src/du_app/du_sys_info_hdl.c index 64bde2675..b8184ce40 100644 --- a/src/du_app/du_sys_info_hdl.c +++ b/src/du_app/du_sys_info_hdl.c @@ -25,6 +25,7 @@ #include "du_app_mac_inf.h" #include "du_cfg.h" #include "du_app_rlc_inf.h" +#include "du_e2ap_mgr.h" #include "du_mgr.h" #include "du_utils.h" #include "BCCH-BCH-Message.h" diff --git a/src/du_app/du_ue_mgr.c b/src/du_app/du_ue_mgr.c index 1baee239a..cf5df231f 100644 --- a/src/du_app/du_ue_mgr.c +++ b/src/du_app/du_ue_mgr.c @@ -28,6 +28,7 @@ #include "legtp.h" #include "du_app_mac_inf.h" #include "du_app_rlc_inf.h" +#include "du_e2ap_mgr.h" #include "du_cfg.h" #include "du_mgr.h" #include "du_utils.h" diff --git a/src/du_app/du_utils.c b/src/du_app/du_utils.c index ca278ac5a..882eef9e8 100644 --- a/src/du_app/du_utils.c +++ b/src/du_app/du_utils.c @@ -22,6 +22,7 @@ #include "lkw.x" #include "du_app_mac_inf.h" #include "du_app_rlc_inf.h" +#include "du_e2ap_mgr.h" #include "du_cfg.h" #include "du_mgr.h" #include "du_utils.h" diff --git a/src/ric_stub/ric_e2ap_msg_hdl.c b/src/ric_stub/ric_e2ap_msg_hdl.c index c372278eb..7db9c3546 100644 --- a/src/ric_stub/ric_e2ap_msg_hdl.c +++ b/src/ric_stub/ric_e2ap_msg_hdl.c @@ -904,6 +904,228 @@ uint8_t BuildAndSendE2NodeConfigUpdateAck(uint32_t duId) return ret; } +/******************************************************************* + * + * @brief Deallocate the memory allocated for E2 Reset Response + * + * @details + * + * Function : FreeE2ResetResponse + * + * Functionality: + * - freeing the memory allocated for E2ResetResponse + * + * @params[in] E2AP_PDU_t *e2apMsg + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg) +{ + uint8_t ieIdx =0; + ResetResponseE2_t *resetResponse; + + if(e2apMsg != NULLP) + { + if(e2apMsg->choice.successfulOutcome != NULLP) + { + resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2; + if(resetResponse->protocolIEs.list.array) + { + for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++) + { + if(resetResponse->protocolIEs.list.array[ieIdx]) + { + RIC_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t)); + } + } + RIC_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size); + } + RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); + } + RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t)); + } +} + +/******************************************************************* + * + * @brief Buld and send the E2 Reset Response msg + * + * @details + * + * Function : BuildAndSendE2ResetResponse + * + * Functionality: + * - Buld and send the E2 Reset Response Message + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t BuildAndSendResetResponse(uint32_t duId, uint8_t transId) +{ + uint8_t ieIdx = 0, elementCnt = 0; + uint8_t ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + ResetResponseE2_t *resetResponse; + asn_enc_rval_t encRetVal; /* Encoder return value */ + + DU_LOG("\nINFO --> E2AP : Building E2 Reset Response Message\n"); + do + { + RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed"); + break; + } + e2apMsg->present = E2AP_PDU_PR_successfulOutcome; + + RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); + if(e2apMsg->choice.successfulOutcome == NULLP) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome"); + RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t)); + return RFAILED; + } + + e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset; + e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject; + e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2; + resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2; + + elementCnt = 1; + resetResponse->protocolIEs.list.count = elementCnt; + resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *); + RIC_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size); + if(!resetResponse->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array"); + break; + } + + for(ieIdx=0; ieIdx < elementCnt; ieIdx++) + { + RIC_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t)); + if(!resetResponse->protocolIEs.list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element"); + break; + } + } + if(ieIdx < elementCnt) + break; + + ieIdx = 0; + resetResponse->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID; + resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject; + resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID; + resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId; + + 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); + if(encRetVal.encoded == ENCODE_FAIL) + { + DU_LOG("\nERROR --> E2AP : Could not encode E2 reset response structure (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + return RFAILED; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2 Reset Response \n"); + for(int i=0; i< encBufSize; i++) + { + DU_LOG("%x",encBuf[i]); + } + } + + /* Sending msg */ + if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to send E2 Reset Response"); + return RFAILED; + } + + ret = ROK; + break; + }while(true); + + FreeE2ResetResponse(e2apMsg); + return ROK; +} + +/******************************************************************* + * + * @brief process the E2 Reset Request + * + * @details + * + * Function : ProcE2ResetReq + * + * Functionality: Process E2 Reset Request + * + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ + +uint8_t ProcE2ResetReq(uint32_t duId, ResetRequestE2_t *resetReq) +{ + uint8_t ieIdx = 0, duIdx = 0; + uint8_t transId = 0, cause = 0; + DuDb *duDb = NULLP; + + if(resetReq) + { + if(resetReq->protocolIEs.list.array) + { + for(ieIdx=0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++) + { + if(resetReq->protocolIEs.list.array[ieIdx]) + { + switch(resetReq->protocolIEs.list.array[ieIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + transId = resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID; + break; + case ProtocolIE_IDE2_id_CauseE2: + DU_LOG("\nDEBUG --> E2AP : Reset reason %d", resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present); + switch(resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present) + { + case CauseE2_PR_NOTHING: + break; + case CauseE2_PR_ricRequest: + cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricRequest; + break; + case CauseE2_PR_ricService: + cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricService; + break; + case CauseE2_PR_e2Node: + cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.e2Node; + break; + case CauseE2_PR_transport: + cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.transport; + break; + case CauseE2_PR_protocol: + cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.protocol; + break; + case CauseE2_PR_misc: + cause = resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.misc; + break; + } + DU_LOG("\nDEBUG --> E2AP : Reset cause %d", cause); + break; + } + } + } + } + } + BuildAndSendResetResponse(duId, transId); + return ROK; +} + /******************************************************************* * * @brief Handles received E2AP message and sends back response @@ -973,59 +1195,65 @@ void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf) switch(e2apMsg->present) { case E2AP_PDU_PR_initiatingMessage: - { - switch(e2apMsg->choice.initiatingMessage->value.present) { - case InitiatingMessageE2__value_PR_E2setupRequest: - { - DU_LOG("\nINFO --> E2AP : E2 setup request received"); - ProcE2SetupReq(duId, &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest); - break; - } - case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate: - { - DU_LOG("\nINFO --> E2AP : E2 node config update received"); - BuildAndSendE2NodeConfigUpdateAck(*duId); - break; - } - case InitiatingMessageE2__value_PR_RICindication: + switch(e2apMsg->choice.initiatingMessage->value.present) { - DU_LOG("\nINFO --> E2AP : RIC Indication Acknowledged"); - break; - } - default: - { - DU_LOG("\nERROR --> E2AP : Invalid type of intiating message [%d]",e2apMsg->choice.initiatingMessage->value.present); - return; - } - }/* End of switch(initiatingMessage) */ - break; - } + case InitiatingMessageE2__value_PR_E2setupRequest: + { + DU_LOG("\nINFO --> E2AP : E2 setup request received"); + ProcE2SetupReq(duId, &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest); + break; + } + case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate: + { + DU_LOG("\nINFO --> E2AP : E2 node config update received"); + BuildAndSendE2NodeConfigUpdateAck(*duId); + break; + } + case InitiatingMessageE2__value_PR_ResetRequestE2: + { + DU_LOG("\nINFO --> E2AP : E2 Reset Request received"); + ProcE2ResetReq(*duId, &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2); + break; + } + case InitiatingMessageE2__value_PR_RICindication: + { + DU_LOG("\nINFO --> E2AP : RIC Indication Acknowledged"); + break; + } + default: + { + DU_LOG("\nERROR --> E2AP : Invalid type of intiating message [%d]",e2apMsg->choice.initiatingMessage->value.present); + return; + } + }/* End of switch(initiatingMessage) */ + break; + } case E2AP_PDU_PR_successfulOutcome: - { - switch(e2apMsg->choice.successfulOutcome->value.present) { - case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse: - { - ProcRicSubscriptionResponse(*duId); - break; - } - default: + switch(e2apMsg->choice.successfulOutcome->value.present) { - DU_LOG("\nERROR --> E2AP : Invalid type of successfulOutcome message [%d]",e2apMsg->choice.successfulOutcome->value.present); - return; + case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse: + { + ProcRicSubscriptionResponse(*duId); + break; + } + default: + { + DU_LOG("\nERROR --> E2AP : Invalid type of successfulOutcome message [%d]",e2apMsg->choice.successfulOutcome->value.present); + return; + } + break; } - break; + break; } - break; - } default: - { - DU_LOG("\nERROR --> E2AP : Invalid type message type "); - return; - } - - }/* End of switch(e2apMsg->present) */ + { + DU_LOG("\nERROR --> E2AP : Invalid type message type "); + return; + } + + }/* End of switch(e2apMsg->present) */ } /* End of E2APMsgHdlr */ -- 2.16.6