From e665dbab28c49327066cff72aed22e1de7797b59 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani <velumani@eurecom.fr> Date: Thu, 1 Sep 2022 17:52:07 -0400 Subject: [PATCH] Common interface between CUCP & CUUP for E1 and non E1 modes --- CMakeLists.txt | 2 + openair2/E1AP/e1ap_api.c | 67 +-------- openair2/E1AP/e1ap_api.h | 9 -- openair2/RRC/NR/cucp_cuup_direct.c | 219 +++++++++++++++++++++++++++++ openair2/RRC/NR/cucp_cuup_e1ap.c | 61 ++++++++ openair2/RRC/NR/cucp_cuup_if.h | 42 ++++++ openair2/RRC/NR/nr_rrc_defs.h | 12 +- openair2/RRC/NR/nr_rrc_proto.h | 5 + openair2/RRC/NR/rrc_gNB.c | 176 ++--------------------- openair2/RRC/NR/rrc_gNB_NGAP.c | 2 +- 10 files changed, 356 insertions(+), 239 deletions(-) create mode 100644 openair2/RRC/NR/cucp_cuup_direct.c create mode 100644 openair2/RRC/NR/cucp_cuup_e1ap.c create mode 100644 openair2/RRC/NR/cucp_cuup_if.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 71728f79f49..e8642f5fafa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1900,6 +1900,8 @@ set(L2_NR_SRC ${NR_RRC_DIR}/L2_nr_interface.c ${NR_RRC_DIR}/mac_rrc_dl_direct.c ${NR_RRC_DIR}/mac_rrc_dl_f1ap.c + ${NR_RRC_DIR}/cucp_cuup_direct.c + ${NR_RRC_DIR}/cucp_cuup_e1ap.c ${NR_RRC_DIR}/nr_rrc_config.c ${NR_RRC_DIR}/rrc_gNB_nsa.c ${NR_RRC_DIR}/rrc_gNB_internode.c diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c index 45c7be47565..ec60e0c9504 100644 --- a/openair2/E1AP/e1ap_api.c +++ b/openair2/E1AP/e1ap_api.c @@ -25,9 +25,10 @@ #include "UTIL/OSA/osa_defs.h" #include "nr_pdcp/nr_pdcp_entity.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h" +#include "openair2/RRC/NR/cucp_cuup_if.h" #include "openair3/ocp-gtpu/gtp_itf.h" -static void fill_DRB_configList(NR_DRB_ToAddModList_t *DRB_configList, pdu_session_to_setup_t *pdu) { +static void fill_DRB_configList_e1(NR_DRB_ToAddModList_t *DRB_configList, pdu_session_to_setup_t *pdu) { for (int i=0; i < pdu->numDRB2Setup; i++) { DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + i; @@ -109,7 +110,7 @@ static int drb_config_N3gtpu_create(e1ap_bearer_setup_req_t *req, sizeof(uint8_t)*4); create_tunnel_req.dst_addr[i].length = 32; // 8bits * 4bytes create_tunnel_req.outgoing_teid[i] = pdu->teId; - fill_DRB_configList(&DRB_configList, pdu); + fill_DRB_configList_e1(&DRB_configList, pdu); } create_tunnel_req.num_tunnels = req->numPDUSessions; create_tunnel_req.ue_id = (req->gNB_cu_cp_ue_id & 0xFFFF); @@ -145,44 +146,6 @@ static int drb_config_N3gtpu_create(e1ap_bearer_setup_req_t *req, return ret; } -void gNB_CU_create_up_ul_tunnel(e1ap_bearer_setup_resp_t *resp, - e1ap_bearer_setup_req_t *req, - instance_t gtpInst, - ue_id_t ue_id, - int remote_port, - in_addr_t my_addr) { - - resp->numPDUSessions = req->numPDUSessions; - transport_layer_addr_t dummy_address = {0}; - dummy_address.length = 32; // IPv4 - for (int i=0; i < req->numPDUSessions; i++) { - resp->pduSession[i].numDRBSetup = req->pduSession[i].numDRB2Setup; - for (int j=0; j < req->pduSession[i].numDRB2Setup; j++) { - DRB_nGRAN_to_setup_t *drb2Setup = req->pduSession[i].DRBnGRanList + j; - DRB_nGRAN_setup_t *drbSetup = resp->pduSession[i].DRBnGRanList + j; - - drbSetup->numUpParam = 1; - drbSetup->UpParamList[0].tlAddress = my_addr; - drbSetup->UpParamList[0].teId = newGtpuCreateTunnel(gtpInst, - (ue_id & 0xFFFF), - drb2Setup->id, - drb2Setup->id, - 0xFFFF, // We will set the right value from DU answer - -1, // no qfi - dummy_address, // We will set the right value from DU answer - remote_port, - cu_f1u_data_req, - NULL); - drbSetup->id = drb2Setup->id; - - drbSetup->numQosFlowSetup = drb2Setup->numQosFlow2Setup; - for (int k=0; k < drbSetup->numQosFlowSetup; k++) { - drbSetup->qosFlows[k].id = drb2Setup->qosFlows[k].id; - } - } - } -} - void CUUP_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, instance_t instance) { gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp_N3={0}; @@ -200,7 +163,7 @@ void CUUP_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, inst &my_addr); gtpInst = getCxtE1(UPtype, instance)->gtpInstF1U; - gNB_CU_create_up_ul_tunnel(&resp, req, gtpInst, req->gNB_cu_cp_ue_id, remote_port, my_addr); + CU_create_UP_DL_tunnel(&resp, req, gtpInst, req->gNB_cu_cp_ue_id, remote_port, my_addr); resp.gNB_cu_cp_ue_id = req->gNB_cu_cp_ue_id; resp.numPDUSessions = req->numPDUSessions; @@ -224,29 +187,9 @@ void CUUP_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, inst e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(instance, &resp); } -void update_UL_UP_tunnel_info(e1ap_bearer_setup_req_t *req, instance_t instance, ue_id_t ue_id) { - for (int i=0; i < req->numPDUSessionsMod; i++) { - for (int j=0; j < req->pduSessionMod[i].numDRB2Modify; j++) { - DRB_nGRAN_to_setup_t *drb_p = req->pduSessionMod[i].DRBnGRanModList + j; - - transport_layer_addr_t newRemoteAddr; - newRemoteAddr.length = 32; // IPv4 - memcpy(newRemoteAddr.buffer, - &drb_p->DlUpParamList[0].tlAddress, - sizeof(in_addr_t)); - - GtpuUpdateTunnelOutgoingPair(instance, - (ue_id & 0xFFFF), - (ebi_t)drb_p->id, - drb_p->DlUpParamList[0].teId, - newRemoteAddr); - } - } -} - void CUUP_process_bearer_context_mod_req(e1ap_bearer_setup_req_t *req, instance_t instance) { instance_t gtpInst = getCxtE1(UPtype, instance)->gtpInstF1U; - update_UL_UP_tunnel_info(req, gtpInst, req->gNB_cu_cp_ue_id); + CU_update_UP_DL_tunnel(req, gtpInst, req->gNB_cu_cp_ue_id); // TODO: send bearer cxt mod response } diff --git a/openair2/E1AP/e1ap_api.h b/openair2/E1AP/e1ap_api.h index fa0de8fd0d8..482cd3dd60c 100644 --- a/openair2/E1AP/e1ap_api.h +++ b/openair2/E1AP/e1ap_api.h @@ -28,15 +28,6 @@ #include "e1ap_common.h" #include "NR_DRB-ToAddModList.h" -void gNB_CU_create_up_ul_tunnel(e1ap_bearer_setup_resp_t *resp, - e1ap_bearer_setup_req_t *req, - instance_t gtpInst, - ue_id_t ue_id, - int remote_port, - in_addr_t my_addr); - -void update_UL_UP_tunnel_info(e1ap_bearer_setup_req_t *req, instance_t instance, ue_id_t ue_id); - void CUUP_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, instance_t instance); void CUUP_process_bearer_context_mod_req(e1ap_bearer_setup_req_t *req, instance_t instance); diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c new file mode 100644 index 00000000000..1aa48b10e0e --- /dev/null +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -0,0 +1,219 @@ +/* + * 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 + * + * 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: + * conmnc_digit_lengtht@openairinterface.org + */ + +#include <arpa/inet.h> + +#include "cucp_cuup_if.h" +#include "platform_types.h" +#include "nr_rrc_defs.h" + +#include "softmodem-common.h" +#include "nr_rrc_proto.h" +#include "nr_rrc_extern.h" +#include "openair2/E1AP/e1ap_common.h" +#include "UTIL/OSA/osa_defs.h" +#include "nr_pdcp/nr_pdcp_entity.h" +#include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h" +#include <openair2/RRC/NR/rrc_gNB_UE_context.h> +#include "openair3/ocp-gtpu/gtp_itf.h" +#include "openair2/F1AP/f1ap_common.h" +#include "rrc_gNB_GTPV1U.h" +#include "common/ran_context.h" + +extern RAN_CONTEXT_t RC; + +void CU_create_UP_DL_tunnel(e1ap_bearer_setup_resp_t *resp, + e1ap_bearer_setup_req_t *req, + instance_t gtpInst, + ue_id_t ue_id, + int remote_port, + in_addr_t my_addr) { + + resp->numPDUSessions = req->numPDUSessions; + transport_layer_addr_t dummy_address = {0}; + dummy_address.length = 32; // IPv4 + for (int i=0; i < req->numPDUSessions; i++) { + resp->pduSession[i].numDRBSetup = req->pduSession[i].numDRB2Setup; + for (int j=0; j < req->pduSession[i].numDRB2Setup; j++) { + DRB_nGRAN_to_setup_t *drb2Setup = req->pduSession[i].DRBnGRanList + j; + DRB_nGRAN_setup_t *drbSetup = resp->pduSession[i].DRBnGRanList + j; + + drbSetup->numUpParam = 1; + drbSetup->UpParamList[0].tlAddress = my_addr; + drbSetup->UpParamList[0].teId = newGtpuCreateTunnel(gtpInst, + (ue_id & 0xFFFF), + drb2Setup->id, + drb2Setup->id, + 0xFFFF, // We will set the right value from DU answer + -1, // no qfi + dummy_address, // We will set the right value from DU answer + remote_port, + cu_f1u_data_req, + NULL); + drbSetup->id = drb2Setup->id; + + drbSetup->numQosFlowSetup = drb2Setup->numQosFlow2Setup; + for (int k=0; k < drbSetup->numQosFlowSetup; k++) { + drbSetup->qosFlows[k].id = drb2Setup->qosFlows[k].id; + } + } + } +} + +void CU_update_UP_DL_tunnel(e1ap_bearer_setup_req_t *req, instance_t instance, ue_id_t ue_id) { + for (int i=0; i < req->numPDUSessionsMod; i++) { + for (int j=0; j < req->pduSessionMod[i].numDRB2Modify; j++) { + DRB_nGRAN_to_setup_t *drb_p = req->pduSessionMod[i].DRBnGRanModList + j; + + transport_layer_addr_t newRemoteAddr; + newRemoteAddr.length = 32; // IPv4 + memcpy(newRemoteAddr.buffer, + &drb_p->DlUpParamList[0].tlAddress, + sizeof(in_addr_t)); + + GtpuUpdateTunnelOutgoingPair(instance, + (ue_id & 0xFFFF), + (ebi_t)drb_p->id, + drb_p->DlUpParamList[0].teId, + newRemoteAddr); + } + } +} + +static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, + rrc_gNB_ue_context_t *ue_context_p, + e1ap_bearer_setup_req_t *req, + NR_DRB_ToAddModList_t *DRB_configList, + NR_SRB_ToAddModList_t *SRB_configList, + instance_t instance) { + + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0}; + gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0}; + + for (int i=0; i < ue_context_p->ue_context.nb_of_pdusessions; i++) { + pdu_session_param_t *pdu = ue_context_p->ue_context.pduSession + i; + create_tunnel_req.pdusession_id[i] = pdu->param.pdusession_id; + create_tunnel_req.incoming_rb_id[i] = i + 1; + create_tunnel_req.outgoing_qfi[i] = req->pduSession[i].DRBnGRanList[0].qosFlows[0].id; + memcpy(&create_tunnel_req.dst_addr[i].buffer, + &pdu->param.upf_addr.buffer, + sizeof(uint8_t)*20); + create_tunnel_req.dst_addr[i].length = pdu->param.upf_addr.length; + create_tunnel_req.outgoing_teid[i] = pdu->param.gtp_teid; + } + create_tunnel_req.num_tunnels = ue_context_p->ue_context.nb_of_pdusessions; + create_tunnel_req.ue_id = ue_context_p->ue_context.rnti; + + int ret = gtpv1u_create_ngu_tunnel(instance, + &create_tunnel_req, + &create_tunnel_resp); + + if (ret != 0) { + LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE rnti %ld\n", + create_tunnel_req.ue_id); + return ret; + } + + nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(ctxt_p, + &create_tunnel_resp); + + uint8_t *kRRCenc = NULL; + uint8_t *kRRCint = NULL; + uint8_t *kUPenc = NULL; + uint8_t *kUPint = NULL; + /* Derive the keys from kgnb */ + if (DRB_configList != NULL) { + nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm, + ue_context_p->ue_context.kgnb, + &kUPenc); + nr_derive_key_up_int(ue_context_p->ue_context.integrity_algorithm, + ue_context_p->ue_context.kgnb, + &kUPint); + } + + nr_derive_key_rrc_enc(ue_context_p->ue_context.ciphering_algorithm, + ue_context_p->ue_context.kgnb, + &kRRCenc); + nr_derive_key_rrc_int(ue_context_p->ue_context.integrity_algorithm, + ue_context_p->ue_context.kgnb, + &kRRCint); + /* Refresh SRBs/DRBs */ + + LOG_D(NR_RRC,"Configuring PDCP DRBs/SRBs for UE %x\n",ue_context_p->ue_context.rnti); + + nr_pdcp_add_srbs(ctxt_p->enb_flag, ctxt_p->rnti, + SRB_configList, + (ue_context_p->ue_context.integrity_algorithm << 4) + | ue_context_p->ue_context.ciphering_algorithm, + kRRCenc, + kRRCint); + + nr_pdcp_add_drbs(ctxt_p->enb_flag, ctxt_p->rnti, + DRB_configList, + (ue_context_p->ue_context.integrity_algorithm << 4) + | ue_context_p->ue_context.ciphering_algorithm, + kUPenc, + kUPint, + get_softmodem_params()->sa ? ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL); + + return ret; +} + +static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *req, instance_t instance) { + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], req->rnti); + protocol_ctxt_t ctxt = {0}; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0); + + fill_DRB_configList(&ctxt, ue_context_p); + + gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; + // GTP tunnel for UL + int ret = drb_config_gtpu_create(&ctxt, + ue_context_p, + req, + ue_context_p->ue_context.DRB_configList, + ue_context_p->ue_context.SRB_configList, + rrc->gtpInstN3); + if (ret < 0) AssertFatal(false, "Unable to configure DRB or to create GTP Tunnel\n"); + + if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)) { + rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, NULL); + } else { + e1ap_bearer_setup_resp_t resp; // Used to store teids + int remote_port = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd; + in_addr_t my_addr = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr); + instance_t gtpInst = getCxt(CUtype, instance)->gtpInst; + // GTP tunnel for DL + CU_create_UP_DL_tunnel(&resp, req, gtpInst, ue_context_p->ue_context.rnti, remote_port, my_addr); + + prepare_and_send_ue_context_modification_f1(ue_context_p, &resp); + } +} + +static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *req, instance_t instance) { + instance_t gtpInst = getCxt(CUtype, instance)->gtpInst; + CU_update_UP_DL_tunnel(req, gtpInst, req->rnti); +} + +void cucp_cuup_message_transfer_direct_init(gNB_RRC_INST *rrc) { + rrc->cucp_cuup.cucp_cuup_bearer_context_setup = cucp_cuup_bearer_context_setup_direct; + rrc->cucp_cuup.cucp_cuup_bearer_context_mod = cucp_cuup_bearer_context_mod_direct; +} diff --git a/openair2/RRC/NR/cucp_cuup_e1ap.c b/openair2/RRC/NR/cucp_cuup_e1ap.c new file mode 100644 index 00000000000..2b90af4880f --- /dev/null +++ b/openair2/RRC/NR/cucp_cuup_e1ap.c @@ -0,0 +1,61 @@ +/* + * 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 + * + * 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: + * conmnc_digit_lengtht@openairinterface.org + */ + +#include "cucp_cuup_if.h" +#include <arpa/inet.h> + +#include "platform_types.h" +#include "nr_rrc_defs.h" + +#include "nr_rrc_proto.h" +#include "nr_rrc_extern.h" +#include "cucp_cuup_if.h" +#include "openair2/E1AP/e1ap_common.h" +#include "UTIL/OSA/osa_defs.h" +#include <openair2/RRC/NR/rrc_gNB_UE_context.h> +#include "common/ran_context.h" + +extern RAN_CONTEXT_t RC; + +static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *req, instance_t instance) { + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], req->rnti); + protocol_ctxt_t ctxt = {0}; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0); + + fill_DRB_configList(&ctxt, ue_context_p); + MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_SETUP_REQ); + e1ap_bearer_setup_req_t *bearer_req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p); + memcpy(bearer_req, req, sizeof(e1ap_bearer_setup_req_t)); + + itti_send_msg_to_task (TASK_CUCP_E1, instance, msg_p); +} + +static void cucp_cuup_bearer_context_mod_e1ap(e1ap_bearer_setup_req_t *req, instance_t instance) { + MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_MODIFICATION_REQ); + e1ap_bearer_setup_req_t *req_msg = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg); + memcpy(req_msg, req, sizeof(*req)); + itti_send_msg_to_task(TASK_CUCP_E1, instance, msg); +} + +void cucp_cuup_message_transfer_e1ap_init(gNB_RRC_INST *rrc) { + rrc->cucp_cuup.cucp_cuup_bearer_context_setup = cucp_cuup_bearer_context_setup_e1ap; + rrc->cucp_cuup.cucp_cuup_bearer_context_mod = cucp_cuup_bearer_context_mod_e1ap; +} diff --git a/openair2/RRC/NR/cucp_cuup_if.h b/openair2/RRC/NR/cucp_cuup_if.h new file mode 100644 index 00000000000..6b641b55f8a --- /dev/null +++ b/openair2/RRC/NR/cucp_cuup_if.h @@ -0,0 +1,42 @@ +/* + * 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 + * + * 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: + * conmnc_digit_lengtht@openairinterface.org + */ + +#ifndef CUCP_CUUP_IF_H +#define CUCP_CUUP_IF_H + +#include <netinet/in.h> +#include "platform_types.h" + +struct e1ap_bearer_setup_req_s; +struct e1ap_bearer_setup_resp_s; +typedef void (*cucp_cuup_bearer_context_setup_func_t)(struct e1ap_bearer_setup_req_s *req, instance_t instance); + +struct gNB_RRC_INST_s; +void cucp_cuup_message_transfer_direct_init(struct gNB_RRC_INST_s *rrc); +void cucp_cuup_message_transfer_e1ap_init(struct gNB_RRC_INST_s *rrc); +void CU_create_UP_DL_tunnel(struct e1ap_bearer_setup_resp_s *resp, + struct e1ap_bearer_setup_req_s *req, + instance_t gtpInst, + ue_id_t ue_id, + int remote_port, + in_addr_t my_addr); +void CU_update_UP_DL_tunnel(struct e1ap_bearer_setup_req_s *req, instance_t instance, ue_id_t ue_id); +#endif diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 0c3fc2b15c6..502a4c43b59 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -43,6 +43,7 @@ #include "COMMON/platform_constants.h" #include "COMMON/platform_types.h" #include "mac_rrc_dl.h" +#include "cucp_cuup_if.h" //#include "COMMON/mac_rrc_primitives.h" @@ -467,16 +468,16 @@ typedef struct { int do_drb_integrity; } nr_security_configuration_t; -typedef void (*nr_e1_bearer_cxt_msg_transfer_func_t)(e1ap_bearer_setup_req_t *req, instance_t instance); -typedef void (*nr_e1_ue_cxt_mod_msg_transfer_func_t)(MessageDef *msg, instance_t instance); - typedef struct nr_mac_rrc_dl_if_s { /* TODO add other message types as necessary */ dl_rrc_message_transfer_func_t dl_rrc_message_transfer; - nr_e1_bearer_cxt_msg_transfer_func_t nr_e1_bearer_cxt_msg_transfer; - nr_e1_ue_cxt_mod_msg_transfer_func_t nr_e1_ue_cxt_mod_msg_transfer; } nr_mac_rrc_dl_if_t; +typedef struct cucp_cuup_if_s { + cucp_cuup_bearer_context_setup_func_t cucp_cuup_bearer_context_setup; + cucp_cuup_bearer_context_setup_func_t cucp_cuup_bearer_context_mod; +} cucp_cuup_if_t; + //---NR---(completely change)--------------------- typedef struct gNB_RRC_INST_s { @@ -531,6 +532,7 @@ typedef struct gNB_RRC_INST_s { nr_security_configuration_t security; nr_mac_rrc_dl_if_t mac_rrc; + cucp_cuup_if_t cucp_cuup; } gNB_RRC_INST; diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 25223f118a2..a1ead3750a0 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -231,3 +231,8 @@ void ue_cxt_mod_send_e1ap(MessageDef *msg, void ue_cxt_mod_direct(MessageDef *msg, instance_t instance); +void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_pP); + +void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, + e1ap_bearer_setup_resp_t *e1ap_resp); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index e4d3c4bf3e7..382692b6f62 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -88,8 +88,6 @@ #include "nr_pdcp/nr_pdcp_entity.h" #include "pdcp.h" -#include "openair3/ocp-gtpu/gtp_itf.h" - #include "intertask_interface.h" #include "SIMULATION/TOOLS/sim.h" // for taus @@ -105,6 +103,7 @@ #include "openair2/E1AP/e1ap_common.h" #include "openair2/SDAP/nr_sdap/nr_sdap_entity.h" #include "openair2/E1AP/e1ap_api.h" +#include "cucp_cuup_if.h" #include "BIT_STRING.h" #include "assertions.h" @@ -201,23 +200,20 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration } } -static void rrc_gNB_mac_rrc_init(gNB_RRC_INST *rrc) +static void rrc_gNB_CU_DU_init(gNB_RRC_INST *rrc) { switch (rrc->node_type) { case ngran_gNB_CUCP: mac_rrc_dl_f1ap_init(&rrc->mac_rrc); - rrc->mac_rrc.nr_e1_bearer_cxt_msg_transfer = bearer_context_setup_e1ap; - rrc->mac_rrc.nr_e1_ue_cxt_mod_msg_transfer = ue_cxt_mod_send_e1ap; + cucp_cuup_message_transfer_e1ap_init(rrc); break; case ngran_gNB_CU: mac_rrc_dl_f1ap_init(&rrc->mac_rrc); - rrc->mac_rrc.nr_e1_bearer_cxt_msg_transfer = bearer_context_setup_direct; - rrc->mac_rrc.nr_e1_ue_cxt_mod_msg_transfer = ue_cxt_mod_direct; + cucp_cuup_message_transfer_direct_init(rrc); break; case ngran_gNB: mac_rrc_dl_direct_init(&rrc->mac_rrc); - rrc->mac_rrc.nr_e1_bearer_cxt_msg_transfer = bearer_context_setup_direct; - rrc->mac_rrc.nr_e1_ue_cxt_mod_msg_transfer = ue_cxt_mod_direct; + cucp_cuup_message_transfer_direct_init(rrc); break; case ngran_gNB_DU: /* silently drop this, as we currently still need the RRC at the DU. As @@ -243,7 +239,7 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu rrc->module_id = gnb_mod_idP; rrc->Nb_ue = 0; rrc->carrier.Srb0.Active = 0; - rrc_gNB_mac_rrc_init(rrc); + rrc_gNB_CU_DU_init(rrc); uid_linear_allocator_init(&rrc->uid_allocator); RB_INIT(&rrc->rrc_ue_head); rrc->initial_id2_s1ap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL); @@ -1322,85 +1318,6 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( } } -int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, - rrc_gNB_ue_context_t *ue_context_p, - e1ap_bearer_setup_req_t *req, - NR_DRB_ToAddModList_t *DRB_configList, - NR_SRB_ToAddModList_t *SRB_configList, - instance_t instance) { - - gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0}; - gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0}; - - for (int i=0; i < ue_context_p->ue_context.nb_of_pdusessions; i++) { - pdu_session_param_t *pdu = ue_context_p->ue_context.pduSession + i; - create_tunnel_req.pdusession_id[i] = pdu->param.pdusession_id; - create_tunnel_req.incoming_rb_id[i] = i + 1; - create_tunnel_req.outgoing_qfi[i] = req->pduSession[i].DRBnGRanList[0].qosFlows[0].id; - memcpy(&create_tunnel_req.dst_addr[i].buffer, - &pdu->param.upf_addr.buffer, - sizeof(uint8_t)*20); - create_tunnel_req.dst_addr[i].length = pdu->param.upf_addr.length; - create_tunnel_req.outgoing_teid[i] = pdu->param.gtp_teid; - } - create_tunnel_req.num_tunnels = ue_context_p->ue_context.nb_of_pdusessions; - create_tunnel_req.ue_id = ue_context_p->ue_context.rnti; - - int ret = gtpv1u_create_ngu_tunnel(instance, - &create_tunnel_req, - &create_tunnel_resp); - - if (ret != 0) { - LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE rnti %ld\n", - create_tunnel_req.ue_id); - return ret; - } - - nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(ctxt_p, - &create_tunnel_resp); - - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - uint8_t *kUPenc = NULL; - uint8_t *kUPint = NULL; - /* Derive the keys from kgnb */ - if (DRB_configList != NULL) { - nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm, - ue_context_p->ue_context.kgnb, - &kUPenc); - nr_derive_key_up_int(ue_context_p->ue_context.integrity_algorithm, - ue_context_p->ue_context.kgnb, - &kUPint); - } - - nr_derive_key_rrc_enc(ue_context_p->ue_context.ciphering_algorithm, - ue_context_p->ue_context.kgnb, - &kRRCenc); - nr_derive_key_rrc_int(ue_context_p->ue_context.integrity_algorithm, - ue_context_p->ue_context.kgnb, - &kRRCint); - /* Refresh SRBs/DRBs */ - - LOG_D(NR_RRC,"Configuring PDCP DRBs/SRBs for UE %x\n",ue_context_p->ue_context.rnti); - - nr_pdcp_add_srbs(ctxt_p->enb_flag, ctxt_p->rnti, - SRB_configList, - (ue_context_p->ue_context.integrity_algorithm << 4) - | ue_context_p->ue_context.ciphering_algorithm, - kRRCenc, - kRRCint); - - nr_pdcp_add_drbs(ctxt_p->enb_flag, ctxt_p->rnti, - DRB_configList, - (ue_context_p->ue_context.integrity_algorithm << 4) - | ue_context_p->ue_context.ciphering_algorithm, - kUPenc, - kUPint, - get_softmodem_params()->sa ? ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL); - - return ret; -} - //----------------------------------------------------------------------------- /* * Process the RRC Reconfiguration Complete from the UE @@ -3607,21 +3524,6 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const ch } -void ue_cxt_mod_send_e1ap(MessageDef *msg, instance_t instance) { - int module_id = 0; - itti_send_msg_to_task(TASK_CUCP_E1, module_id, msg); -} - -void ue_cxt_mod_direct(MessageDef *msg, instance_t instance) { - e1ap_bearer_setup_req_t *req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg); - instance_t gtpInst = getCxt(CUtype, instance)->gtpInst; - - update_UL_UP_tunnel_info(req, gtpInst, req->rnti); - - int result = itti_free (ITTI_MSG_ORIGIN_ID(msg), msg); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); -} - static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, const char *msg_name, instance_t instance){ f1ap_ue_context_setup_t *resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p); @@ -3636,16 +3538,15 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, c gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rnti); - MessageDef *msg_e1 = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_MODIFICATION_REQ); - e1ap_bearer_setup_req_t *req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg_e1); - req->numPDUSessionsMod = ue_context_p->ue_context.nb_of_pdusessions; - req->gNB_cu_cp_ue_id = ue_context_p->ue_context.gNB_ue_ngap_id; - req->rnti = ue_context_p->ue_context.rnti; - for (int i=0; i < req->numPDUSessionsMod; i++) { - req->pduSessionMod[i].numDRB2Modify = resp->drbs_to_be_setup_length; + e1ap_bearer_setup_req_t req = {0}; + req.numPDUSessionsMod = ue_context_p->ue_context.nb_of_pdusessions; + req.gNB_cu_cp_ue_id = ue_context_p->ue_context.gNB_ue_ngap_id; + req.rnti = ue_context_p->ue_context.rnti; + for (int i=0; i < req.numPDUSessionsMod; i++) { + req.pduSessionMod[i].numDRB2Modify = resp->drbs_to_be_setup_length; for (int j=0; j < resp->drbs_to_be_setup_length; j++) { f1ap_drb_to_be_setup_t *drb_f1 = resp->drbs_to_be_setup + j; - DRB_nGRAN_to_setup_t *drb_e1 = req->pduSessionMod[i].DRBnGRanModList + j; + DRB_nGRAN_to_setup_t *drb_e1 = req.pduSessionMod[i].DRBnGRanModList + j; drb_e1->id = drb_f1->drb_id; drb_e1->numDlUpParam = drb_f1->up_dl_tnl_length; @@ -3655,7 +3556,7 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, c } // send the F1 response message up to update F1-U tunnel info - rrc->mac_rrc.nr_e1_ue_cxt_mod_msg_transfer(msg_e1, instance); + rrc->cucp_cuup.cucp_cuup_bearer_context_mod(&req, instance); NR_CellGroupConfig_t *cellGroupConfig = NULL; @@ -4030,55 +3931,6 @@ void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_contex itti_send_msg_to_task (TASK_CU_F1, ctxt.module_id, message_p); } -void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req, instance_t instance) { - - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], req->rnti); - protocol_ctxt_t ctxt = {0}; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0); - - fill_DRB_configList(&ctxt, ue_context_p); - - gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; - // GTP tunnel for UL - int ret = drb_config_gtpu_create(&ctxt, - ue_context_p, - req, - ue_context_p->ue_context.DRB_configList, - ue_context_p->ue_context.SRB_configList, - rrc->gtpInstN3); - if (ret < 0) AssertFatal(false, "Unable to configure DRB or to create GTP Tunnel\n"); - - if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)) { - rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, NULL); - } else { - e1ap_bearer_setup_resp_t resp; // Used to store teids - int remote_port = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd; - in_addr_t my_addr = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr); - instance_t gtpInst = getCxt(CUtype, instance)->gtpInst; - gNB_CU_create_up_ul_tunnel(&resp, req, gtpInst, ue_context_p->ue_context.rnti, remote_port, my_addr); - - prepare_and_send_ue_context_modification_f1(ue_context_p, &resp); - } - // call the code that sends UE context modification message to DU -} - -void bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *req, instance_t instance) { - - // create ITTI msg and send to CUCP E1 task to send via SCTP - // then in CUUP the function rrc_gNB_process_e1_bearer_context_setup_req - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], req->rnti); - protocol_ctxt_t ctxt = {0}; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0); - - fill_DRB_configList(&ctxt, ue_context_p); - MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_SETUP_REQ); - e1ap_bearer_setup_req_t *bearer_req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p); - memcpy(bearer_req, req, sizeof(e1ap_bearer_setup_req_t)); - - itti_send_msg_to_task (TASK_CUCP_E1, instance, msg_p); - -} - void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance) { // Find the UE context from UE ID and send ITTI message to F1AP to send UE context modification message to DU diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 1f3b5a2f10c..f44abd6ae5d 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -1072,7 +1072,7 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( } } - rrc->mac_rrc.nr_e1_bearer_cxt_msg_transfer(&bearer_req, instance); + rrc->cucp_cuup.cucp_cuup_bearer_context_setup(&bearer_req, instance); return; } -- GitLab