Commit e665dbab authored by Sakthivel Velumani's avatar Sakthivel Velumani

Common interface between CUCP & CUUP for E1 and non E1 modes

parent 5dcc1bf5
......@@ -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
......
......@@ -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
}
......@@ -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);
......
/*
* 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;
}
/*
* 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;
}
/*
* 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
......@@ -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;
......
......@@ -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);
......@@ -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
......
......@@ -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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment