Commit ecfd0fe2 authored by Sakthivel Velumani's avatar Sakthivel Velumani

Update GTP remote address from response message

Modified GTP tunnel update function accordingly
Put GTP tunnel update out of F1AP
F1 split works
parent 14a37e41
......@@ -29,3 +29,5 @@ MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_s
MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_RESP , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_resp_t , e1ap_bearer_setup_resp)
MESSAGE_DEF(E1AP_BEARER_CONTEXT_MODIFICATION_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_req_t , e1ap_bearer_mod_req)
......@@ -36,10 +36,11 @@
#define E1AP_MAX_NUM_DRBS 4
#define E1AP_MAX_NUM_UP_PARAM 4
#define E1AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_req
#define E1AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_resp
#define E1AP_BEARER_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req
#define E1AP_BEARER_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_resp
#define E1AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_req
#define E1AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_resp
#define E1AP_BEARER_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req
#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
typedef f1ap_net_ip_address_t e1ap_net_ip_address_t;
......@@ -112,6 +113,8 @@ typedef struct DRB_nGRAN_to_setup_s {
long discardTimer;
long reorderingTimer;
long rLC_Mode;
in_addr_t tlAddress;
int teId;
int numCellGroups;
cell_group_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS];
int numQosFlow2Setup;
......@@ -136,6 +139,7 @@ typedef struct pdu_session_to_setup_s {
typedef struct e1ap_bearer_setup_req_s {
uint64_t gNB_cu_cp_ue_id;
rnti_t rnti;
uint64_t cipheringAlgorithm;
uint64_t integrityProtectionAlgorithm;
char encryptionKey[128];
......
......@@ -186,6 +186,7 @@ typedef struct gtpv1u_gnb_create_tunnel_resp_s {
int num_tunnels;
teid_t gnb_NGu_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier
pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
int bearer_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
transport_layer_addr_t gnb_addr;
} gtpv1u_gnb_create_tunnel_resp_t;
typedef struct gtpv1u_gnb_delete_tunnel_req_s {
......
......@@ -1086,7 +1086,8 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance,
BEARER CONTEXT MODIFICATION REQUEST
*/
int e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance) {
int e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
e1ap_bearer_setup_req_t *req) {
AssertFatal(false,"Not implemented yet\n");
return -1;
}
......@@ -1373,6 +1374,11 @@ void *E1AP_CUCP_task(void *arg) {
e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(myInstance, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg));
break;
case E1AP_BEARER_CONTEXT_MODIFICATION_REQ:
LOG_I(E1AP, "CUCP Task Received E1AP_BEARER_CONTEXT_MODIFICATION_REQ\n");
e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(myInstance, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg));
break;
default:
LOG_E(E1AP, "Unknown message received in TASK_CUCP_E1\n");
break;
......
......@@ -30,38 +30,8 @@
#include "openair2/COMMON/e1ap_messages_types.h"
#include "openair3/UTILS/conversions.h"
#include "openair2/F1AP/f1ap_common.h"
#include "openair2/E1AP/e1ap_common.h"
#include <E1AP_Cause.h>
#include <E1AP_InitiatingMessage.h>
#include <E1AP_E1AP-PDU.h>
#include <E1AP_ProtocolIE-Field.h>
#include <E1AP_SupportedPLMNs-Item.h>
#include <E1AP_SuccessfulOutcome.h>
#include <E1AP_ProtocolIE-Field.h>
#include <E1AP_UnsuccessfulOutcome.h>
#include <E1AP_GNB-CU-UP-E1SetupFailure.h>
#include <E1AP_GNB-CU-UP-ConfigurationUpdate.h>
#include <E1AP_GNB-CU-UP-TNLA-To-Remove-Item.h>
#include <E1AP_CP-TNL-Information.h>
#include <E1AP_UP-Parameters-Item.h>
#include <E1AP_UP-TNL-Information.h>
#include <E1AP_PDU-Session-Resource-Setup-Item.h>
#include <E1AP_DRB-Setup-Item-EUTRAN.h>
#include <E1AP_DRB-Setup-Item-NG-RAN.h>
#include <E1AP_QoS-Flow-QoS-Parameter-Item.h>
#include <E1AP_QoS-Flow-Item.h>
#include <E1AP_DRB-Failed-List-NG-RAN.h>
#include <E1AP_DRB-Failed-Item-NG-RAN.h>
#include <E1AP_BearerContextSetupResponse.h>
#include <E1AP_BearerContextSetupRequest.h>
#include <E1AP_DRB-To-Setup-Item-EUTRAN.h>
#include <E1AP_DRB-To-Setup-Item-NG-RAN.h>
#include <E1AP_Cell-Group-Information-Item.h>
#include <E1AP_PDU-Session-Resource-To-Setup-Item.h>
#include <E1AP_GTPTunnel.h>
#include <E1AP_Non-Dynamic5QIDescriptor.h>
#include <E1AP_Dynamic5QIDescriptor.h>
#include <E1AP_T-ReorderingTimer.h>
#endif
......
......@@ -51,6 +51,7 @@ void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req) {
if (type == CPtype) {
AssertFatal(e1ap_cp_inst[instance] == NULL, "Double call to E1 CP instance %d\n", (int)instance);
e1ap_cp_inst[instance] = (e1ap_upcp_inst_t *) calloc(1, sizeof(e1ap_upcp_inst_t));
memcpy(&e1ap_cp_inst[instance]->setupReq, req, sizeof(e1ap_setup_req_t));
} else if (type == UPtype) {
AssertFatal(e1ap_up_inst[instance] == NULL, "Double call to E1 UP instance %d\n", (int)instance);
e1ap_up_inst[instance] = (e1ap_upcp_inst_t *) calloc(1, sizeof(e1ap_upcp_inst_t));
......
......@@ -25,6 +25,39 @@
#define E1AP_COMMON_H_
#include "openair2/E1AP/e1ap_default_values.h"
#include "openair2/COMMON/e1ap_messages_types.h"
#include <E1AP_Cause.h>
#include <E1AP_InitiatingMessage.h>
#include <E1AP_E1AP-PDU.h>
#include <E1AP_ProtocolIE-Field.h>
#include <E1AP_SupportedPLMNs-Item.h>
#include <E1AP_SuccessfulOutcome.h>
#include <E1AP_ProtocolIE-Field.h>
#include <E1AP_UnsuccessfulOutcome.h>
#include <E1AP_GNB-CU-UP-E1SetupFailure.h>
#include <E1AP_GNB-CU-UP-ConfigurationUpdate.h>
#include <E1AP_GNB-CU-UP-TNLA-To-Remove-Item.h>
#include <E1AP_CP-TNL-Information.h>
#include <E1AP_UP-Parameters-Item.h>
#include <E1AP_UP-TNL-Information.h>
#include <E1AP_PDU-Session-Resource-Setup-Item.h>
#include <E1AP_DRB-Setup-Item-EUTRAN.h>
#include <E1AP_DRB-Setup-Item-NG-RAN.h>
#include <E1AP_QoS-Flow-QoS-Parameter-Item.h>
#include <E1AP_QoS-Flow-Item.h>
#include <E1AP_DRB-Failed-List-NG-RAN.h>
#include <E1AP_DRB-Failed-Item-NG-RAN.h>
#include <E1AP_BearerContextSetupResponse.h>
#include <E1AP_BearerContextSetupRequest.h>
#include <E1AP_DRB-To-Setup-Item-EUTRAN.h>
#include <E1AP_DRB-To-Setup-Item-NG-RAN.h>
#include <E1AP_Cell-Group-Information-Item.h>
#include <E1AP_PDU-Session-Resource-To-Setup-Item.h>
#include <E1AP_GTPTunnel.h>
#include <E1AP_Non-Dynamic5QIDescriptor.h>
#include <E1AP_Dynamic5QIDescriptor.h>
#include <E1AP_T-ReorderingTimer.h>
int e1ap_decode_pdu(E1AP_E1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length);
e1ap_upcp_inst_t *getCxtE1(E1_t type, instance_t instance);
......
......@@ -700,10 +700,15 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance,
F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel;
BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address);
OCTET_STRING_TO_INT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid);
GtpuUpdateTunnelOutgoingTeid(getCxt(CUtype, instance)->gtpInst,
transport_layer_addr_t addr;
int sz=sizeof(drb_p->up_dl_tnl[0].tl_address);
memcpy(addr.buffer, &drb_p->up_dl_tnl[0].tl_address, sz);
addr.length = sz*8;
GtpuUpdateTunnelOutgoingPair(getCxt(CUtype, instance)->gtpInst,
f1ap_ue_context_setup_resp->rnti,
(ebi_t)drbs_setup_item_p->dRBID,
drb_p->up_dl_tnl[0].teid);
drb_p->up_dl_tnl[0].teid,
addr);
}
}
......@@ -1691,10 +1696,6 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance,
F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel;
BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address);
OCTET_STRING_TO_INT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid);
GtpuUpdateTunnelOutgoingTeid(getCxt(CUtype, instance)->gtpInst,
f1ap_ue_context_modification_resp->rnti,
(ebi_t)drbs_setupmod_item_p->dRBID,
drb_p->up_dl_tnl[0].teid);
}
}
// SRBs_FailedToBeSetupMod_List
......
......@@ -468,11 +468,13 @@ typedef struct {
} 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;
//---NR---(completely change)---------------------
......
......@@ -225,3 +225,9 @@ void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req,
void bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *req,
instance_t instance);
void ue_cxt_mod_send_e1ap(MessageDef *msg,
instance_t instance);
void ue_cxt_mod_direct(MessageDef *msg,
instance_t instance);
......@@ -102,6 +102,7 @@
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h"
#include "openair2/F1AP/f1ap_common.h"
#include "openair2/E1AP/e1ap_common.h"
#include "BIT_STRING.h"
#include "assertions.h"
......@@ -202,24 +203,23 @@ static void rrc_gNB_mac_rrc_init(gNB_RRC_INST *rrc)
{
switch (rrc->node_type) {
case ngran_gNB_CUCP:
rrc->cu_if.nr_e1_bearer_cxt_msg_transfer = bearer_context_setup_e1ap;
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;
break;
case ngran_gNB_CUUP:
// CUUP should not have a RRC instance but we let it for now
break;
case ngran_gNB_CU:
case ngran_gNB:
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;
break;
case ngran_gNB_DU:
/* silently drop this, as we currently still need the RRC at the DU. As
* soon as this is not the case anymore, we can add the AssertFatal() */
//AssertFatal(1==0,"nothing to do for DU\n");
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;
break;
default:
AssertFatal(0 == 1, "Unknown node type %d\n", rrc->node_type);
break;
......@@ -3596,9 +3596,49 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const ch
}
static 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->numPDUSessions; i++) {
for (int j=0; j < req->pduSession[i].numDRB2Setup; j++) {
DRB_nGRAN_to_setup_t *drb_p = req->pduSession[i].DRBnGRanList + j;
transport_layer_addr_t newRemoteAddr;
newRemoteAddr.length = 32; // IPv4
memcpy(newRemoteAddr.buffer,
&drb_p->tlAddress,
sizeof(in_addr_t));
GtpuUpdateTunnelOutgoingPair(instance,
ue_id,
(ebi_t)drb_p->id,
drb_p->teId,
newRemoteAddr);
}
}
}
void rrc_CUUP_process_bearer_context_mod_req(e1ap_bearer_setup_req_t *req, instance_t instance) {
update_UL_UP_tunnel_info(req, instance, req->gNB_cu_cp_ue_id);
// TODO: send bearer cxt mod response
}
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);
f1ap_ue_context_setup_t *resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p);
protocol_ctxt_t ctxt = {
.rnti = resp->rnti,
.module_id = instance,
......@@ -3606,8 +3646,30 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, c
.enb_flag = 1,
.eNB_index = instance
};
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->numPDUSessions = 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->numPDUSessions; i++) {
req->pduSession[i].numDRB2Setup = 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->pduSession[i].DRBnGRanList + j;
drb_e1->id = drb_f1->drb_id;
drb_e1->tlAddress = drb_f1->up_dl_tnl[0].tl_address;
drb_e1->teId = drb_f1->up_dl_tnl[0].teid;
}
}
// send the F1 response message up to update F1-U tunnel info
rrc->cu_if.nr_e1_ue_cxt_mod_msg_transfer(msg_e1, instance);
NR_CellGroupConfig_t *cellGroupConfig = NULL;
if(resp->du_to_cu_rrc_information->cellGroupConfig!=NULL){
......@@ -4007,33 +4069,35 @@ void fill_DRB_configList_e1(NR_DRB_ToAddModList_t *DRB_configList, pdu_session_t
}
}
int drb_config_gtpu_create_e1(e1ap_bearer_setup_req_t *req,
gtpv1u_gnb_create_tunnel_req_t *create_tunnel_req,
gtpv1u_gnb_create_tunnel_resp_t *create_tunnel_resp,
instance_t instance) {
int drb_config_N3gtpu_create_e1(e1ap_bearer_setup_req_t *req,
gtpv1u_gnb_create_tunnel_resp_t *create_tunnel_resp,
instance_t instance) {
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
NR_DRB_ToAddModList_t DRB_configList = {0};
for (int i=0; i < req->numPDUSessions; i++) {
pdu_session_to_setup_t *pdu = &req->pduSession[i];
create_tunnel_req->pdusession_id[i] = pdu->sessionId;
create_tunnel_req->incoming_rb_id[i] = pdu->DRBnGRanList[0].id; // taking only the first DRB. TODO:change this
memcpy(&create_tunnel_req->dst_addr[i].buffer,
create_tunnel_req.pdusession_id[i] = pdu->sessionId;
create_tunnel_req.incoming_rb_id[i] = pdu->DRBnGRanList[0].id; // taking only the first DRB. TODO:change this
memcpy(&create_tunnel_req.dst_addr[i].buffer,
&pdu->tlAddress,
sizeof(uint8_t)*4);
create_tunnel_req->dst_addr[i].length = 32; // 8bits * 4bytes
create_tunnel_req->outgoing_teid[i] = pdu->teId;
create_tunnel_req.dst_addr[i].length = 32; // 8bits * 4bytes
create_tunnel_req.outgoing_teid[i] = pdu->teId;
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);
create_tunnel_req.num_tunnels = req->numPDUSessions;
create_tunnel_req.ue_id = (req->gNB_cu_cp_ue_id & 0xFFFF);
// Create N3 tunnel
int ret = gtpv1u_create_ngu_tunnel(
instance,
create_tunnel_req,
&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 id %ld\n",
create_tunnel_req->ue_id);
create_tunnel_req.ue_id);
return ret;
}
......@@ -4050,7 +4114,7 @@ int drb_config_gtpu_create_e1(e1ap_bearer_setup_req_t *req,
&kUPint);
nr_pdcp_e1_add_drbs(false,
create_tunnel_req->ue_id,
create_tunnel_req.ue_id,
&DRB_configList,
(req->integrityProtectionAlgorithm << 4) | req->cipheringAlgorithm,
kUPenc,
......@@ -4060,46 +4124,61 @@ int drb_config_gtpu_create_e1(e1ap_bearer_setup_req_t *req,
void gNB_CU_create_up_ul_tunnel(e1ap_bearer_setup_resp_t *resp,
e1ap_bearer_setup_req_t *req,
instance_t instance,
ue_id_t ue_id) {
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++) {
pdu_session_to_setup_t *pdu = req->pduSession + i;
transport_layer_addr_t addr;
int size = sizeof(pdu->tlAddress_dl);
memcpy(addr.buffer,
&pdu->tlAddress_dl,
size);
addr.length = size * 8;
resp->pduSession[i].tlAddress = pdu->tlAddress;
resp->pduSession[i].teId = newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst,
ue_id,
pdu->DRBnGRanList[0].id,
pdu->DRBnGRanList[0].id,
0xFFFF, // We will set the right value from DU answer
-1, // no qfi
addr,
pdu->tl_port_dl,
cu_f1u_data_req,
NULL);
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,
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 rrc_gNB_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, instance_t instance) {
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0};
protocol_ctxt_t ctxt={0};
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, req->gNB_cu_cp_ue_id, 0, 0, 0);
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp_N3={0};
// GTP tunnel for UL
drb_config_gtpu_create_e1(req, &create_tunnel_req, &create_tunnel_resp, instance);
drb_config_N3gtpu_create_e1(req, &create_tunnel_resp_N3, instance);
MessageDef *message_p;
message_p = itti_alloc_new_message (TASK_RRC_GNB, instance, E1AP_BEARER_CONTEXT_SETUP_RESP);
e1ap_bearer_setup_resp_t *resp = &E1AP_BEARER_CONTEXT_SETUP_RESP(message_p);
gNB_CU_create_up_ul_tunnel(resp, req, instance, req->gNB_cu_cp_ue_id);
int remote_port = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd;
in_addr_t my_addr;
memcpy(&my_addr,
&getCxtE1(UPtype, instance)->setupReq.CUUP_e1_ip_address.ipv4_address,
sizeof(my_addr));
gNB_CU_create_up_ul_tunnel(resp, req, instance, 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;
......@@ -4109,30 +4188,11 @@ void rrc_gNB_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, i
pduSetup->id = pdu2Setup->sessionId;
memcpy(&pduSetup->tlAddress,
&create_tunnel_resp.gnb_addr.buffer,
&create_tunnel_resp_N3.gnb_addr.buffer,
sizeof(in_addr_t));
pduSetup->teId = create_tunnel_resp.gnb_NGu_teid[i];
pduSetup->teId = create_tunnel_resp_N3.gnb_NGu_teid[i];
pduSetup->numDRBSetup = pdu2Setup->numDRB2Setup;
for (int j=0; j < pdu2Setup->numDRB2Setup; j++) {
DRB_nGRAN_setup_t *drbSetup = pduSetup->DRBnGRanList + j;
DRB_nGRAN_to_setup_t *drb2Setup = pdu2Setup->DRBnGRanList + j;
drbSetup->id = drb2Setup->id;
/* TODO: Set dummy values for UP Parameters for now */
drbSetup->numUpParam = 1;
for (int k=0; k < drbSetup->numUpParam; k++) {
drbSetup->UpParamList[k].tlAddress = 0;
drbSetup->UpParamList[k].teId = 0;
}
drbSetup->numQosFlowSetup = drb2Setup->numQosFlow2Setup;
for (int k=0; k < drbSetup->numQosFlowSetup; k++) {
drbSetup->qosFlows[k].id = drb2Setup->qosFlows[k].id;
}
}
// At this point we don't have a way to know the DRBs that failed to setup
// We assume all DRBs to setup have are setup successfully so we always send successful outcome in response
// TODO: Modify nr_pdcp_add_drbs() to return DRB list that failed to setup to support E1AP
......@@ -4143,8 +4203,7 @@ void rrc_gNB_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, i
}
void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p,
e1ap_bearer_setup_resp_t *e1ap_resp,
e1ap_bearer_setup_req_t *e1ap_req) {
e1ap_bearer_setup_resp_t *e1ap_resp) {
/*Generate a UE context modification request message towards the DU to instruct the DU
*for SRB2 and DRB configuration and get the updates on master cell group config from the DU*/
......@@ -4169,19 +4228,16 @@ void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_contex
SRBs[0].lcid = 2;
/*Instruction towards the DU for DRB configuration and tunnel creation*/
req->drbs_to_be_setup_length = e1ap_req->numPDUSessions;
req->drbs_to_be_setup_length = e1ap_resp->pduSession[0].numDRBSetup;
req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t)*req->drbs_to_be_setup_length);
for (int i=0; i < e1ap_req->numPDUSessions; i++) {
for (int i=0; i < e1ap_resp->pduSession[0].numDRBSetup; i++) {
f1ap_drb_to_be_setup_t *DRBs = req->drbs_to_be_setup + i;
DRBs[i].drb_id = e1ap_req->pduSession[i].DRBnGRanList[0].id;
DRBs[i].drb_id = e1ap_resp->pduSession[0].DRBnGRanList[i].id;
DRBs[i].rlc_mode = RLC_MODE_AM;
DRBs[i].up_ul_tnl[0].tl_address = e1ap_req->pduSession[i].tlAddress;
DRBs[i].up_ul_tnl[0].port = e1ap_req->pduSession[i].tl_port;
DRBs[i].up_ul_tnl[0].teid = e1ap_resp->pduSession[i].teId;
DRBs[i].up_ul_tnl[0].tl_address = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].tlAddress;
DRBs[i].up_ul_tnl[0].port = RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd;
DRBs[i].up_ul_tnl[0].teid = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].teId;
DRBs[i].up_ul_tnl_length = 1;
DRBs[i].up_dl_tnl[0].tl_address = e1ap_req->pduSession[i].tlAddress_dl;
DRBs[i].up_dl_tnl[0].port = e1ap_req->pduSession[i].tl_port_dl;
DRBs[i].up_dl_tnl_length = 1;
}
itti_send_msg_to_task (TASK_CU_F1, ctxt.module_id, message_p);
......@@ -4189,8 +4245,7 @@ void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_contex
void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req, instance_t instance) {
uint16_t ue_initial_id = 0; // Making an invalid UE initial ID
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, req->gNB_cu_cp_ue_id);
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);
......@@ -4205,22 +4260,16 @@ void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req, instance_t instan
instance);
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)){
if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)) {
rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, NULL);
} else {
for (int i=0; i < req->numPDUSessions; i++) {
pdu_session_to_setup_t *pdu = req->pduSession + i;
pdu->tlAddress = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr);
pdu->tl_port = RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd;
pdu->tlAddress_dl = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.remote_addr);
pdu->tl_port_dl = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd;
}
e1ap_bearer_setup_resp_t resp; // Used to store teids
gNB_CU_create_up_ul_tunnel(&resp, req, instance, ue_context_p->ue_context.rnti);
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, req);
prepare_and_send_ue_context_modification_f1(ue_context_p, &resp);
}
// call the code that sends UE context modification message to DU
}
......@@ -4229,17 +4278,12 @@ 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
uint16_t ue_initial_id = 0; // Making an invalid UE initial ID
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, req->gNB_cu_cp_ue_id);
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);
MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_SETUP_REQ);
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));
free(req);
itti_send_msg_to_task (TASK_CUCP_E1, ctxt.module_id, msg_p);
itti_send_msg_to_task (TASK_CUCP_E1, instance, msg_p);
}
......@@ -4267,20 +4311,7 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp
ue_context_p->ue_context.setup_pdu_sessions += resp->numPDUSessions;
// TODO: SV: combine e1ap_bearer_setup_req_t and e1ap_bearer_setup_resp_t and minimize assignments
e1ap_bearer_setup_req_t req;
req.numPDUSessions = resp->numPDUSessions;
for (int i=0; i < resp->numPDUSessions; i++) {
pdu_session_to_setup_t *pdu = req.pduSession + i;
pdu->DRBnGRanList[0].id = resp->pduSession[i].DRBnGRanList[0].id;
pdu->tlAddress = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr);
pdu->tl_port = RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd;
pdu->tlAddress_dl = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.remote_addr);
pdu->tl_port_dl = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd;
}
prepare_and_send_ue_context_modification_f1(ue_context_p, resp, &req);
prepare_and_send_ue_context_modification_f1(ue_context_p, resp);
}
///---------------------------------------------------------------------------------------------------------------///
......
......@@ -497,12 +497,14 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
return (-1);
} else {
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
ue_context_p->ue_context.gNB_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).gNB_ue_ngap_id;
ue_context_p->ue_context.amf_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).amf_ue_ngap_id;
ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nas_pdu_flag;
uint8_t nb_pdusessions_tosetup = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions;
if (nb_pdusessions_tosetup != 0) {
AssertFatal(rrc->node_type != ngran_gNB_CUCP, "PDU sessions in Initial context setup request not handled by E1 yet\n");
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
for (int i = 0; i < NR_NB_RB_MAX - 3; i++) {
if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE)
......@@ -992,6 +994,7 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
e1ap_bearer_setup_req_t *bearer_req = calloc(1, sizeof(e1ap_bearer_setup_req_t));
bearer_req->gNB_cu_cp_ue_id = gNB_ue_ngap_id;
bearer_req->rnti = ue_context_p->ue_context.rnti;
bearer_req->cipheringAlgorithm = ue_context_p->ue_context.ciphering_algorithm;
memcpy(bearer_req->encryptionKey, ue_context_p->ue_context.kgnb, sizeof(ue_context_p->ue_context.kgnb));
bearer_req->integrityProtectionAlgorithm = ue_context_p->ue_context.integrity_algorithm;
......
......@@ -546,7 +546,11 @@ instance_t gtpv1Init(openAddr_t context) {
return id;
}
void GtpuUpdateTunnelOutgoingTeid(instance_t instance, ue_id_t ue_id, ebi_t bearer_id, teid_t newOutgoingTeid) {
void GtpuUpdateTunnelOutgoingPair(instance_t instance,
ue_id_t ue_id,
ebi_t bearer_id,
teid_t newOutgoingTeid,
transport_layer_addr_t newRemoteAddr) {
pthread_mutex_lock(&globGtp.gtp_lock);
getInstRetVoid(compatInst(instance));
getRntiRetVoid(inst, ue_id);
......@@ -560,7 +564,36 @@ void GtpuUpdateTunnelOutgoingTeid(instance_t instance, ue_id_t ue_id, ebi_t bear
}
ptr2->second.teid_outgoing = newOutgoingTeid;
LOG_I(GTPU, "[%ld] Tunnel Outgoing TEID updated to %x \n", instance, ptr2->second.teid_outgoing);
int addrs_length_in_bytes = newRemoteAddr.length / 8;
switch (addrs_length_in_bytes) {
case 4:
memcpy(&ptr2->second.outgoing_ip_addr,newRemoteAddr.buffer,4);
break;
case 16:
memcpy(ptr2->second.outgoing_ip6_addr.s6_addr,newRemoteAddr.buffer,
16);
break;
case 20:
memcpy(&ptr2->second.outgoing_ip_addr,newRemoteAddr.buffer,4);
memcpy(ptr2->second.outgoing_ip6_addr.s6_addr,
newRemoteAddr.buffer+4,
16);
default:
AssertFatal(false, "SGW Address size impossible");
}
char ip4[INET_ADDRSTRLEN];
char ip6[INET6_ADDRSTRLEN];
LOG_I(GTPU, "[%ld] Tunnel Outgoing TEID updated to %x, remote IPv4 to: %s, IPv6 to: %s\n",
instance,
ptr2->second.teid_outgoing,
inet_ntop(AF_INET,(void *)&ptr2->second.outgoing_ip_addr, ip4,INET_ADDRSTRLEN ),
inet_ntop(AF_INET6,(void *)ptr2->second.outgoing_ip6_addr.s6_addr, ip6, INET6_ADDRSTRLEN));
pthread_mutex_unlock(&globGtp.gtp_lock);
return;
}
......@@ -619,7 +652,7 @@ teid_t newGtpuCreateTunnel(instance_t instance,
case 20:
memcpy(&tmp->outgoing_ip_addr,remoteAddr.buffer,4);
memcpy(&tmp->outgoing_ip6_addr.s6_addr,
memcpy(tmp->outgoing_ip6_addr.s6_addr,
remoteAddr.buffer+4,
16);
......
......@@ -91,7 +91,13 @@ extern "C" {
int port,
gtpCallback callBack,
gtpCallbackSDAP callBackSDAP);
void GtpuUpdateTunnelOutgoingTeid(instance_t instance, ue_id_t ue_id, ebi_t bearer_id, teid_t newOutgoingTeid);
void GtpuUpdateTunnelOutgoingPair(instance_t instance,
ue_id_t ue_id,
ebi_t bearer_id,
teid_t newOutgoingTeid,
transport_layer_addr_t newRemoteAddr);
int newGtpuDeleteAllTunnels(instance_t instance, ue_id_t ue_id);
int newGtpuDeleteTunnels(instance_t instance, ue_id_t ue_id, int nbTunnels, pdusessionid_t *pdusession_id);
instance_t gtpv1Init(openAddr_t context);
......
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