From 2e252dd377acafe1eac50a1ef51414465dc2c21c Mon Sep 17 00:00:00 2001 From: Robert Schmidt <robert.schmidt@openairinterface.org> Date: Sun, 8 Oct 2023 16:26:54 +0200 Subject: [PATCH] Implement E1 bearer release --- openair1/SIMULATION/NR_PHY/dlsim.c | 1 + openair1/SIMULATION/NR_PHY/ulsim.c | 1 + openair2/COMMON/e1ap_messages_def.h | 3 ++ openair2/COMMON/e1ap_messages_types.h | 7 ++++ openair2/E1AP/CMakeLists.txt | 2 +- openair2/E1AP/e1ap.c | 32 ++++++++++----- openair2/E1AP/e1ap.h | 2 +- openair2/E1AP/e1ap_api.c | 44 --------------------- openair2/E1AP/e1ap_api.h | 4 +- openair2/E1AP/e1ap_common.c | 6 +++ openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c | 21 ++++++++++ openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h | 2 + openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c | 9 +++++ openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c | 9 +++++ openair2/LAYER2/nr_pdcp/cuup_cucp_if.h | 3 ++ openair2/RRC/NR/cucp_cuup_direct.c | 7 ++++ openair2/RRC/NR/cucp_cuup_e1ap.c | 11 ++++++ openair2/RRC/NR/cucp_cuup_if.h | 2 + openair2/RRC/NR/nr_rrc_defs.h | 1 + openair2/RRC/NR/rrc_gNB.c | 22 ++++++++++- 20 files changed, 129 insertions(+), 60 deletions(-) delete mode 100644 openair2/E1AP/e1ap_api.c diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 163107bf84..21a237785d 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -110,6 +110,7 @@ void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) { abort(); } void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req) { abort(); } +void e1_bearer_release_cmd(const e1ap_bearer_release_cmd_t *cmd) { abort(); } int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { return 0; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 7a7058f2f1..668c1cb633 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -106,6 +106,7 @@ void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) { abort(); } void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req) { abort(); } +void e1_bearer_release_cmd(const e1ap_bearer_release_cmd_t *cmd) { abort(); } int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { return 0; diff --git a/openair2/COMMON/e1ap_messages_def.h b/openair2/COMMON/e1ap_messages_def.h index 2759c655ef..ea24ac9e18 100644 --- a/openair2/COMMON/e1ap_messages_def.h +++ b/openair2/COMMON/e1ap_messages_def.h @@ -34,3 +34,6 @@ MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_RESP , MESSAGE_PRIORITY_MED , e1ap_bearer_ MESSAGE_DEF(E1AP_BEARER_CONTEXT_MODIFICATION_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_req_t , e1ap_bearer_mod_req) MESSAGE_DEF(E1AP_BEARER_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, e1ap_bearer_modif_resp_t, e1ap_bearer_modif_resp) + +MESSAGE_DEF(E1AP_BEARER_CONTEXT_RELEASE_CMD, MESSAGE_PRIORITY_MED, e1ap_bearer_release_cmd_t, e1ap_bearer_release_cmd) +MESSAGE_DEF(E1AP_BEARER_CONTEXT_RELEASE_CPLT, MESSAGE_PRIORITY_MED, e1ap_bearer_release_cplt_t, e1ap_bearer_release_cplt) diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index 124a174dab..f98058b85c 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -48,6 +48,8 @@ #define E1AP_BEARER_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_resp #define E1AP_BEARER_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req #define E1AP_BEARER_CONTEXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_modif_resp +#define E1AP_BEARER_CONTEXT_RELEASE_CMD(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_release_cmd +#define E1AP_BEARER_CONTEXT_RELEASE_CPLT(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_release_cplt typedef f1ap_net_ip_address_t e1ap_net_ip_address_t; @@ -193,6 +195,11 @@ typedef struct e1ap_bearer_release_cmd_s { long cause; } e1ap_bearer_release_cmd_t; +typedef struct e1ap_bearer_release_cplt_s { + uint32_t gNB_cu_cp_ue_id; + uint32_t gNB_cu_up_ue_id; +} e1ap_bearer_release_cplt_t; + typedef struct qos_flow_setup_s { long id; } qos_flow_setup_t; diff --git a/openair2/E1AP/CMakeLists.txt b/openair2/E1AP/CMakeLists.txt index 0384c2860b..c7657eed5a 100644 --- a/openair2/E1AP/CMakeLists.txt +++ b/openair2/E1AP/CMakeLists.txt @@ -1,6 +1,6 @@ add_subdirectory(MESSAGES) -add_library(e1ap e1ap.c e1ap_common.c e1ap_api.c) +add_library(e1ap e1ap.c e1ap_common.c) target_link_libraries(e1ap PUBLIC asn1_e1ap f1ap PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs asn1_f1ap UTIL e1_if) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index a6e6886284..d6116309db 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -1505,7 +1505,7 @@ int e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id, e1ap_bea return e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__); } -static int fill_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_bearer_release_cmd_t *const cmd, E1AP_E1AP_PDU_t *pdu) +static int fill_BEARER_CONTEXT_RELEASE_COMPLETE(const e1ap_bearer_release_cplt_t *cplt, E1AP_E1AP_PDU_t *pdu) { pdu->present = E1AP_E1AP_PDU_PR_successfulOutcome; asn1cCalloc(pdu->choice.successfulOutcome, msg); @@ -1519,22 +1519,22 @@ static int fill_BEARER_CONTEXT_RELEASE_COMPLETE(e1ap_bearer_release_cmd_t *const ieC1->id = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID; ieC1->criticality = E1AP_Criticality_reject; ieC1->value.present = E1AP_BearerContextReleaseCompleteIEs__value_PR_GNB_CU_CP_UE_E1AP_ID; - ieC1->value.choice.GNB_CU_CP_UE_E1AP_ID = cmd->gNB_cu_cp_ue_id; + ieC1->value.choice.GNB_CU_CP_UE_E1AP_ID = cplt->gNB_cu_cp_ue_id; /* mandatory */ /* c2. gNB-CU-UP UE E1AP ID */ asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextReleaseCompleteIEs_t, ieC2); ieC2->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID; ieC2->criticality = E1AP_Criticality_reject; ieC2->value.present = E1AP_BearerContextReleaseCompleteIEs__value_PR_GNB_CU_UP_UE_E1AP_ID; - ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = cmd->gNB_cu_cp_ue_id; + ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = cplt->gNB_cu_cp_ue_id; return 0; } -int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, e1ap_bearer_release_cmd_t *const cmd) +int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, const e1ap_bearer_release_cplt_t *cplt) { E1AP_E1AP_PDU_t pdu = {0}; - fill_BEARER_CONTEXT_RELEASE_COMPLETE(cmd, &pdu); + fill_BEARER_CONTEXT_RELEASE_COMPLETE(cplt, &pdu); return e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__); } @@ -1592,12 +1592,12 @@ int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id, e1ap_u e1ap_bearer_release_cmd_t bearerCxt = {0}; extract_BEARER_CONTEXT_RELEASE_COMMAND(pdu, &bearerCxt); - CUUP_process_bearer_release_command(e1_inst->instance, &bearerCxt); + e1_bearer_release_cmd(&bearerCxt); return 0; } void extract_BEARER_CONTEXT_RELEASE_COMPLETE(const E1AP_E1AP_PDU_t *pdu, - e1ap_bearer_release_cmd_t *bearerCxt) { + e1ap_bearer_release_cplt_t *bearerCxt) { const E1AP_BearerContextReleaseComplete_t *in = &pdu->choice.successfulOutcome->value.choice.BearerContextReleaseComplete; E1AP_BearerContextReleaseCompleteIEs_t *ie; @@ -1634,9 +1634,12 @@ int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, e1ap_ DevAssert(pdu->choice.successfulOutcome->criticality == E1AP_Criticality_reject); DevAssert(pdu->choice.successfulOutcome->value.present == E1AP_SuccessfulOutcome__value_PR_BearerContextReleaseComplete); - e1ap_bearer_release_cmd_t bearerCxt = {0}; + e1ap_bearer_release_cplt_t bearerCxt = {0}; extract_BEARER_CONTEXT_RELEASE_COMPLETE(pdu, &bearerCxt); - //TODO: CUCP_process_bearer_release_complete(&beareCxt, instance); + MessageDef *msg = itti_alloc_new_message(TASK_CUUP_E1, 0, E1AP_BEARER_CONTEXT_RELEASE_CPLT); + e1ap_bearer_release_cplt_t *cplt = &E1AP_BEARER_CONTEXT_RELEASE_CPLT(msg); + *cplt = bearerCxt; + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); return 0; } @@ -1864,6 +1867,10 @@ void *E1AP_CUCP_task(void *arg) { e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(assoc_id, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg)); break; + case E1AP_BEARER_CONTEXT_RELEASE_CMD: + e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND(assoc_id, &E1AP_BEARER_CONTEXT_RELEASE_CMD(msg)); + break; + default: LOG_E(E1AP, "Unknown message received in TASK_CUCP_E1\n"); break; @@ -1921,6 +1928,13 @@ void *E1AP_CUUP_task(void *arg) { e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE(inst->cuup.assoc_id, resp); } break; + case E1AP_BEARER_CONTEXT_RELEASE_CPLT: { + const e1ap_bearer_release_cplt_t *cplt = &E1AP_BEARER_CONTEXT_RELEASE_CPLT(msg); + const e1ap_upcp_inst_t *inst = getCxtE1(myInstance); + AssertFatal(inst != NULL, "no E1 instance found for instance %ld\n", myInstance); + e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(inst->cuup.assoc_id, cplt); + } break; + default: LOG_E(E1AP, "Unknown message received in TASK_CUUP_E1\n"); break; diff --git a/openair2/E1AP/e1ap.h b/openair2/E1AP/e1ap.h index fd82ffd147..b41559de09 100644 --- a/openair2/E1AP/e1ap.h +++ b/openair2/E1AP/e1ap.h @@ -50,7 +50,7 @@ int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id, e1ap_u int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu); -int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, e1ap_bearer_release_cmd_t *const cmd); +int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, const e1ap_bearer_release_cplt_t *cplt); void *E1AP_CUUP_task(void *arg); diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c deleted file mode 100644 index dfb6747600..0000000000 --- a/openair2/E1AP/e1ap_api.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 - * - * Author and copyright: Laurent Thomas, open-cells.com - * - * 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. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include <arpa/inet.h> -#include "e1ap_api.h" - -#include "nr_pdcp/nr_pdcp_entity.h" -#include "openair2/RRC/NR/cucp_cuup_if.h" -#include "openair2/RRC/LTE/MESSAGES/asn1_msg.h" -#include "openair3/SECU/key_nas_deriver.h" -#include "openair3/ocp-gtpu/gtp_itf.h" -#include "openair2/F1AP/f1ap_ids.h" -#include "e1ap_asnc.h" -#include "e1ap_common.h" -#include "e1ap.h" - -void CUUP_process_bearer_release_command(instance_t instance, e1ap_bearer_release_cmd_t *const cmd) -{ - e1ap_upcp_inst_t *inst = getCxtE1(instance); - AssertFatal(inst, ""); - newGtpuDeleteAllTunnels(inst->gtpInstN3, cmd->gNB_cu_up_ue_id); - newGtpuDeleteAllTunnels(inst->gtpInstF1U, cmd->gNB_cu_up_ue_id); - e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(inst->cuup.assoc_id, cmd); -} diff --git a/openair2/E1AP/e1ap_api.h b/openair2/E1AP/e1ap_api.h index e2d0c892d1..a3759399c7 100644 --- a/openair2/E1AP/e1ap_api.h +++ b/openair2/E1AP/e1ap_api.h @@ -25,9 +25,7 @@ #define E1AP_API_H #include "platform_types.h" -#include "openair2/COMMON/e1ap_messages_types.h" -#include "openair2/E1AP/e1ap_common.h" + void cuup_init_n3(instance_t instance); -void CUUP_process_bearer_release_command(instance_t, e1ap_bearer_release_cmd_t *const cmd); #endif diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c index 0547680eea..cf8982339d 100644 --- a/openair2/E1AP/e1ap_common.c +++ b/openair2/E1AP/e1ap_common.c @@ -117,6 +117,9 @@ int e1ap_decode_initiating_message(E1AP_E1AP_PDU_t *pdu) { case E1AP_ProcedureCode_id_bearerContextModification: break; + case E1AP_ProcedureCode_id_bearerContextRelease: + break; + default: LOG_E(E1AP, "Unsupported procedure code (%d) for initiating message\n", (int)pdu->choice.initiatingMessage->procedureCode); @@ -137,6 +140,9 @@ int e1ap_decode_successful_outcome(E1AP_E1AP_PDU_t *pdu) { case E1AP_ProcedureCode_id_bearerContextModification: break; + case E1AP_ProcedureCode_id_bearerContextRelease: + break; + default: LOG_E(E1AP, "Unsupported procedure code (%d) for successful message\n", (int)pdu->choice.successfulOutcome->procedureCode); diff --git a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c index aaf5323b03..d661f9c6f4 100644 --- a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c +++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c @@ -257,3 +257,24 @@ void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req) get_e1_if()->bearer_modif_response(&modif); } + +void e1_bearer_release_cmd(const e1ap_bearer_release_cmd_t *cmd) +{ + instance_t n3inst = get_n3_gtp_instance(); + instance_t f1inst = get_f1_gtp_instance(); + + LOG_I(E1AP, "releasing UE %d\n", cmd->gNB_cu_up_ue_id); + + newGtpuDeleteAllTunnels(n3inst, cmd->gNB_cu_up_ue_id); + if (f1inst >= 0) // is there F1-U? + newGtpuDeleteAllTunnels(f1inst, cmd->gNB_cu_up_ue_id); + nr_pdcp_remove_UE(cmd->gNB_cu_up_ue_id); + cu_remove_f1_ue_data(cmd->gNB_cu_up_ue_id); + + e1ap_bearer_release_cplt_t cplt = { + .gNB_cu_cp_ue_id = cmd->gNB_cu_cp_ue_id, + .gNB_cu_up_ue_id = cmd->gNB_cu_up_ue_id, + }; + + get_e1_if()->bearer_release_complete(&cplt); +} diff --git a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h index 7c9c6244f3..7290043371 100644 --- a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h +++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h @@ -27,7 +27,9 @@ void nr_pdcp_e1_if_init(bool uses_e1); struct e1ap_bearer_setup_req_s; +struct e1ap_bearer_release_cmd_s; void e1_bearer_context_setup(const struct e1ap_bearer_setup_req_s *req); void e1_bearer_context_modif(const struct e1ap_bearer_setup_req_s *req); +void e1_bearer_release_cmd(const struct e1ap_bearer_release_cmd_s *cmd); #endif /* CUCP_CUUP_HANDLER_H */ diff --git a/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c b/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c index 52918b4d64..b6ad66e18c 100644 --- a/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c +++ b/openair2/LAYER2/nr_pdcp/cuup_cucp_direct.c @@ -39,8 +39,17 @@ static void bearer_modif_response_direct(const e1ap_bearer_modif_resp_t *resp) itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); } +static void bearer_release_complete_direct(const e1ap_bearer_release_cplt_t *cplt) +{ + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, E1AP_BEARER_CONTEXT_RELEASE_CPLT); + e1ap_bearer_release_cplt_t *msg_cplt = &E1AP_BEARER_CONTEXT_RELEASE_CPLT(msg); + *msg_cplt = *cplt; + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); +} + void cuup_cucp_init_direct(e1_if_t *iface) { iface->bearer_setup_response = bearer_setup_response_direct; iface->bearer_modif_response = bearer_modif_response_direct; + iface->bearer_release_complete = bearer_release_complete_direct; } diff --git a/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c b/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c index 91ed1b1ec8..8454d5a7d8 100644 --- a/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c +++ b/openair2/LAYER2/nr_pdcp/cuup_cucp_e1ap.c @@ -39,8 +39,17 @@ static void bearer_modif_response_e1ap(const e1ap_bearer_modif_resp_t *resp) itti_send_msg_to_task (TASK_CUUP_E1, 0, msg_p); } +static void bearer_release_complete_e1ap(const e1ap_bearer_release_cplt_t *cplt) +{ + MessageDef *msg_p = itti_alloc_new_message(TASK_CUUP_E1, 0, E1AP_BEARER_CONTEXT_RELEASE_CPLT); + e1ap_bearer_release_cplt_t *msg_cplt = &E1AP_BEARER_CONTEXT_RELEASE_CPLT(msg_p); + *msg_cplt = *cplt; + itti_send_msg_to_task (TASK_CUUP_E1, 0, msg_p); +} + void cuup_cucp_init_e1ap(e1_if_t *iface) { iface->bearer_setup_response = bearer_setup_response_e1ap; iface->bearer_modif_response = bearer_modif_response_e1ap; + iface->bearer_release_complete = bearer_release_complete_e1ap; } diff --git a/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h b/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h index 3a576b7f7f..c33694dac3 100644 --- a/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h +++ b/openair2/LAYER2/nr_pdcp/cuup_cucp_if.h @@ -26,12 +26,15 @@ struct e1ap_bearer_setup_resp_s; struct e1ap_bearer_modif_resp_s; +struct e1ap_bearer_release_cplt_s; typedef void (*e1_bearer_setup_response_func_t)(const struct e1ap_bearer_setup_resp_s *resp); typedef void (*e1_bearer_modif_response_func_t)(const struct e1ap_bearer_modif_resp_s *resp); +typedef void (*e1_bearer_release_complete_func_t)(const struct e1ap_bearer_release_cplt_s *cplt); typedef struct e1_if_t { e1_bearer_setup_response_func_t bearer_setup_response; e1_bearer_modif_response_func_t bearer_modif_response; + e1_bearer_release_complete_func_t bearer_release_complete; } e1_if_t; e1_if_t *get_e1_if(void); diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index 3c45598f15..ee3555a14b 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -37,7 +37,14 @@ static void cucp_cuup_bearer_context_modif_direct(sctp_assoc_t assoc_id, const e e1_bearer_context_modif(req); } +static void cucp_cuup_bearer_context_release_cmd_direct(sctp_assoc_t assoc_id, const e1ap_bearer_release_cmd_t *cmd) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d, impossible for integrated CU\n", assoc_id); + e1_bearer_release_cmd(cmd); +} + void cucp_cuup_message_transfer_direct_init(gNB_RRC_INST *rrc) { rrc->cucp_cuup.bearer_context_setup = cucp_cuup_bearer_context_setup_direct; rrc->cucp_cuup.bearer_context_mod = cucp_cuup_bearer_context_modif_direct; + rrc->cucp_cuup.bearer_context_release = cucp_cuup_bearer_context_release_cmd_direct; } diff --git a/openair2/RRC/NR/cucp_cuup_e1ap.c b/openair2/RRC/NR/cucp_cuup_e1ap.c index 1678dd8313..fb099178d4 100644 --- a/openair2/RRC/NR/cucp_cuup_e1ap.c +++ b/openair2/RRC/NR/cucp_cuup_e1ap.c @@ -47,7 +47,18 @@ static void cucp_cuup_bearer_context_mod_e1ap(sctp_assoc_t assoc_id, const e1ap_ itti_send_msg_to_task(TASK_CUCP_E1, 0, msg); } +static void cucp_cuup_bearer_context_release_cmd_e1ap(sctp_assoc_t assoc_id, const e1ap_bearer_release_cmd_t *cmd) +{ + AssertFatal(assoc_id > 0, "illegal assoc_id %d\n", assoc_id); + MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_RELEASE_CMD); + msg->ittiMsgHeader.originInstance = assoc_id; + e1ap_bearer_release_cmd_t *cmd_msg = &E1AP_BEARER_CONTEXT_RELEASE_CMD(msg); + memcpy(cmd_msg, cmd, sizeof(*cmd)); + itti_send_msg_to_task(TASK_CUCP_E1, 0, msg); +} + void cucp_cuup_message_transfer_e1ap_init(gNB_RRC_INST *rrc) { rrc->cucp_cuup.bearer_context_setup = cucp_cuup_bearer_context_setup_e1ap; rrc->cucp_cuup.bearer_context_mod = cucp_cuup_bearer_context_mod_e1ap; + rrc->cucp_cuup.bearer_context_release = cucp_cuup_bearer_context_release_cmd_e1ap; } diff --git a/openair2/RRC/NR/cucp_cuup_if.h b/openair2/RRC/NR/cucp_cuup_if.h index 125ae93522..cbf84a289e 100644 --- a/openair2/RRC/NR/cucp_cuup_if.h +++ b/openair2/RRC/NR/cucp_cuup_if.h @@ -30,7 +30,9 @@ struct e1ap_bearer_setup_req_s; struct e1ap_bearer_setup_resp_s; +struct e1ap_bearer_release_cmd_s; typedef void (*cucp_cuup_bearer_context_setup_func_t)(sctp_assoc_t assoc_id, const struct e1ap_bearer_setup_req_s *req); +typedef void (*cucp_cuup_bearer_context_release_func_t)(sctp_assoc_t assoc_id, const struct e1ap_bearer_release_cmd_s *cmd); struct gNB_RRC_INST_s; void cucp_cuup_message_transfer_direct_init(struct gNB_RRC_INST_s *rrc); diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 92b521cf69..16b7f040ee 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -362,6 +362,7 @@ typedef struct nr_mac_rrc_dl_if_s { typedef struct cucp_cuup_if_s { cucp_cuup_bearer_context_setup_func_t bearer_context_setup; cucp_cuup_bearer_context_setup_func_t bearer_context_mod; + cucp_cuup_bearer_context_release_func_t bearer_context_release; } cucp_cuup_if_t; typedef struct nr_rrc_du_container_t { diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 1534dde669..81455e3549 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2034,8 +2034,6 @@ static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p) } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - nr_pdcp_remove_UE(UE->rrc_ue_id); - newGtpuDeleteAllTunnels(instance, UE->rrc_ue_id); rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance, UE->rrc_ue_id); LOG_I(NR_RRC, "removed UE CU UE ID %u/RNTI %04x \n", UE->rrc_ue_id, UE->rnti); rrc_delete_ue_data(UE); @@ -2411,6 +2409,15 @@ void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t } } +void rrc_gNB_process_e1_bearer_context_release_cplt(const e1ap_bearer_release_cplt_t *cplt) +{ + // there is not really anything to do here as of now + // note that we don't check for the UE: it does not exist anymore if the F1 + // UE context release complete arrived from the DU first, after which we free + // the UE context + LOG_I(RRC, "UE %d: received bearer release complete\n", cplt->gNB_cu_cp_ue_id); +} + static void rrc_CU_process_f1_lost_connection(gNB_RRC_INST *rrc, f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id) { AssertFatal(rrc->du != NULL, "no DU connected, cannot received F1 lost connection\n"); @@ -2694,6 +2701,10 @@ void *rrc_gnb_task(void *args_p) { rrc_gNB_process_e1_bearer_context_modif_resp(&E1AP_BEARER_CONTEXT_MODIFICATION_RESP(msg_p)); break; + case E1AP_BEARER_CONTEXT_RELEASE_CPLT: + rrc_gNB_process_e1_bearer_context_release_cplt(&E1AP_BEARER_CONTEXT_RELEASE_CPLT(msg_p)); + break; + case NGAP_PAGING_IND: rrc_gNB_process_PAGING_IND(msg_p, instance); break; @@ -2845,6 +2856,13 @@ rrc_gNB_generate_RRCRelease( deliver_ue_ctxt_release_data_t data = {.rrc = rrc, .release_cmd = &ue_context_release_cmd}; nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, &data); + sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, UE); + e1ap_bearer_release_cmd_t cmd = { + .gNB_cu_cp_ue_id = UE->rrc_ue_id, + .gNB_cu_up_ue_id = UE->rrc_ue_id, + }; + rrc->cucp_cuup.bearer_context_release(assoc_id, &cmd); + /* UE will be freed after UE context release complete */ } -- 2.26.2