NGAP GTP Bearer Establishment

master
Bedran Karakoc 3 years ago committed by David Rupprecht
parent 3712983308
commit 43915550cc

@ -21,8 +21,12 @@ class rrc_interface_ngap_nr
public:
virtual int ue_set_security_cfg_key(uint16_t rnti, const asn1::fixed_bitstring<256, false, true>& key) = 0;
virtual int ue_set_bitrates(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates) = 0;
virtual int set_aggregate_max_bitrate(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates) = 0;
virtual int ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps) = 0;
virtual int start_security_mode_procedure(uint16_t rnti) = 0;
virtual int
establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid) = 0;
virtual int allocate_lcid(uint16_t rnti) = 0;
virtual void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) = 0;
};

@ -28,6 +28,7 @@
#include "srsran/common/threads.h"
#include "srsran/interfaces/gnb_ngap_interfaces.h"
#include "srsran/interfaces/gnb_rrc_nr_interfaces.h"
#include "srsran/interfaces/enb_gtpu_interfaces.h"
#include "srsran/srslog/srslog.h"
#include <iostream>
#include <unordered_map>
@ -42,7 +43,7 @@ public:
srslog::basic_logger& logger,
srsran::socket_manager_itf* rx_socket_handler);
~ngap();
int init(const ngap_args_t& args_, rrc_interface_ngap_nr* rrc_);
int init(const ngap_args_t& args_, rrc_interface_ngap_nr* rrc_, gtpu_interface_rrc* gtpu_);
void stop();
// RRC NR interface
@ -84,6 +85,7 @@ private:
// args
rrc_interface_ngap_nr* rrc = nullptr;
gtpu_interface_rrc* gtpu = nullptr;
ngap_args_t args = {};
srslog::basic_logger& logger;
srsran::task_sched_handle task_sched;

@ -13,11 +13,17 @@
#ifndef SRSENB_NGAP_INTERFACES_H
#define SRSENB_NGAP_INTERFACES_H
#include "srsran/asn1/ngap_utils.h"
namespace srsenb {
class ngap_interface_ngap_proc
{
public:
virtual bool send_initial_ctxt_setup_response() = 0;
virtual bool
send_pdu_session_resource_setup_response(uint16_t pdu_session_id,
uint32_t teid_out,
asn1::bounded_bitstring<1, 160, true, true> transport_layer_address) = 0;
};
} // namespace srsenb

@ -13,16 +13,21 @@
#define SRSENB_NGAP_UE_H
#include "ngap.h"
#include "ngap_ue_bearer_manager.h"
#include "ngap_ue_proc.h"
#include "ngap_ue_utils.h"
#include "srsran/asn1/asn1_utils.h"
#include "srsran/asn1/ngap.h"
#include "srsran/interfaces/enb_gtpu_interfaces.h"
namespace srsenb {
class ngap::ue : public ngap_interface_ngap_proc
{
public:
explicit ue(ngap* ngap_ptr_, rrc_interface_ngap_nr* rrc_ptr_, srslog::basic_logger& logger_);
explicit ue(ngap* ngap_ptr_,
rrc_interface_ngap_nr* rrc_ptr_,
gtpu_interface_rrc* gtpu_ptr_,
srslog::basic_logger& logger_);
virtual ~ue();
// TS 38.413 - Section 9.2.5.1 - Initial UE Message
bool send_initial_ue_message(asn1::ngap_nr::rrcestablishment_cause_e cause,
@ -35,6 +40,10 @@ public:
bool send_initial_ctxt_setup_response();
// TS 38.413 - Section 9.2.2.3 - Initial Context Setup Failure
bool send_initial_ctxt_setup_failure(asn1::ngap_nr::cause_c cause);
// TS 38.413 - Section 9.2.1.2 - PDU Session Resource Setup Response
bool send_pdu_session_resource_setup_response(uint16_t pdu_session_id,
uint32_t teid_out,
asn1::bounded_bitstring<1, 160, true, true> transport_layer_address);
// TS 38.413 - Section 9.2.2.1 - Initial Context Setup Request
bool handle_initial_ctxt_setup_request(const asn1::ngap_nr::init_context_setup_request_s& msg);
// TS 38.413 - Section 9.2.2.5 - UE Context Release Command
@ -55,6 +64,7 @@ private:
// state
bool release_requested = false;
ngap_ue_bearer_manager bearer_manager;
// logger
srslog::basic_logger& logger;

@ -0,0 +1,69 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2021 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#ifndef SRSENB_NGAP_UE_BEARER_MANAGER_H
#define SRSENB_NGAP_UE_BEARER_MANAGER_H
#include "srsran/asn1/asn1_utils.h"
#include "srsran/asn1/ngap.h"
#include "srsran/config.h"
#include "srsran/interfaces/enb_gtpu_interfaces.h"
#include "srsran/interfaces/gnb_rrc_nr_interfaces.h"
namespace srsenb {
/**
* @brief Manages the GTPU bearers as part of the NGAP session procedures
* */
class ngap_ue_bearer_manager
{
public:
struct pdu_session_t {
struct gtpu_tunnel {
uint32_t teid_out = 0;
uint32_t teid_in = 0;
asn1::bounded_bitstring<1, 160, true, true> address;
};
uint8_t id = 0;
uint8_t lcid = 0;
asn1::ngap_nr::qos_flow_level_qos_params_s qos_params;
std::vector<gtpu_tunnel> tunnels;
};
ngap_ue_bearer_manager(rrc_interface_ngap_nr* rrc_, gtpu_interface_rrc* gtpu_, srslog::basic_logger& logger_);
~ngap_ue_bearer_manager();
int add_pdu_session(uint16_t rnti,
uint8_t pdu_session_id,
const asn1::ngap_nr::qos_flow_level_qos_params_s& qos,
const asn1::bounded_bitstring<1, 160, true, true>& addr,
uint32_t teid_out,
asn1::ngap_nr::cause_c& cause);
private:
gtpu_interface_rrc* gtpu = nullptr;
rrc_interface_ngap_nr* rrc = nullptr;
std::map<uint8_t, pdu_session_t> pdu_session_list;
srslog::basic_logger& logger;
int add_gtpu_bearer(uint16_t rnti,
uint32_t lcid,
uint32_t pdu_session_id,
uint32_t teid_out,
asn1::bounded_bitstring<1, 160, true, true> address,
pdu_session_t::gtpu_tunnel& tunnel, // out parameter
const gtpu_interface_rrc::bearer_props* props = nullptr);
void rem_gtpu_bearer(uint16_t rnti, uint32_t pdu_session_id);
};
} // namespace srsenb
#endif // SRSENB_NGAP_UE_BEARER_MANAGER_H

@ -21,6 +21,7 @@
#include "srsran/common/buffer_pool.h"
#include "srsran/common/stack_procedure.h"
#include "srsran/interfaces/gnb_rrc_nr_interfaces.h"
#include "srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h"
#include <map>
#include <string>
@ -35,7 +36,8 @@ class ngap_ue_initial_context_setup_proc
public:
explicit ngap_ue_initial_context_setup_proc(ngap_interface_ngap_proc* parent_,
rrc_interface_ngap_nr* rrc_,
ngap_ue_ctxt_t* ue_ctxt);
ngap_ue_ctxt_t* ue_ctxt,
srslog::basic_logger& logger_);
srsran::proc_outcome_t init(const asn1::ngap_nr::init_context_setup_request_s& msg);
srsran::proc_outcome_t react(const bool rrc_reconf_outcome);
srsran::proc_outcome_t step();
@ -54,7 +56,8 @@ class ngap_ue_ue_context_release_proc
public:
explicit ngap_ue_ue_context_release_proc(ngap_interface_ngap_proc* parent_,
rrc_interface_ngap_nr* rrc_,
ngap_ue_ctxt_t* ue_ctxt);
ngap_ue_ctxt_t* ue_ctxt,
srslog::basic_logger& logger_);
srsran::proc_outcome_t init(const asn1::ngap_nr::ue_context_release_cmd_s& msg);
srsran::proc_outcome_t step();
static const char* name() { return "UE Context Release"; }
@ -70,7 +73,7 @@ private:
class ngap_ue_ue_context_modification_proc
{
public:
explicit ngap_ue_ue_context_modification_proc(ngap_interface_ngap_proc* parent_);
explicit ngap_ue_ue_context_modification_proc(ngap_interface_ngap_proc* parent_, srslog::basic_logger& logger_);
srsran::proc_outcome_t init();
srsran::proc_outcome_t step();
static const char* name() { return "UE Context Modification"; }
@ -84,7 +87,9 @@ class ngap_ue_pdu_session_res_setup_proc
public:
explicit ngap_ue_pdu_session_res_setup_proc(ngap_interface_ngap_proc* parent_,
rrc_interface_ngap_nr* rrc_,
ngap_ue_ctxt_t* ue_ctxt);
ngap_ue_ctxt_t* ue_ctxt,
ngap_ue_bearer_manager* bearer_manager,
srslog::basic_logger& logger_);
srsran::proc_outcome_t init(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg);
srsran::proc_outcome_t step();
static const char* name() { return "UE PDU Session Resource Setup"; }
@ -92,6 +97,7 @@ public:
private:
ngap_ue_ctxt_t* ue_ctxt;
ngap_interface_ngap_proc* parent;
ngap_ue_bearer_manager* bearer_manager;
rrc_interface_ngap_nr* rrc = nullptr;
srslog::basic_logger& logger;
};

@ -90,7 +90,10 @@ public:
int ue_set_bitrates(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates);
int ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps);
int start_security_mode_procedure(uint16_t rnti);
int establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid);
void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu);
int set_aggregate_max_bitrate(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates);
int allocate_lcid(uint16_t rnti);
class ue
{

@ -6,5 +6,5 @@
# the distribution.
#
set(SOURCES ngap.cc ngap_ue.cc ngap_ue_proc.cc)
set(SOURCES ngap.cc ngap_ue.cc ngap_ue_proc.cc ngap_ue_bearer_manager.cc)
add_library(srsgnb_ngap STATIC ${SOURCES})

@ -21,6 +21,13 @@ using srsran::uint32_to_uint8;
#define procWarning(fmt, ...) ngap_ptr->logger.warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__)
#define procInfo(fmt, ...) ngap_ptr->logger.info("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__)
#define WarnUnsupportFeature(cond, featurename) \
do { \
if (cond) { \
logger.warning("Not handling feature - %s", featurename); \
} \
} while (0)
using namespace asn1::ngap_nr;
namespace srsenb {
@ -105,10 +112,11 @@ ngap::ngap(srsran::task_sched_handle task_sched_,
ngap::~ngap() {}
int ngap::init(const ngap_args_t& args_, rrc_interface_ngap_nr* rrc_)
int ngap::init(const ngap_args_t& args_, rrc_interface_ngap_nr* rrc_, gtpu_interface_rrc * gtpu_)
{
rrc = rrc_;
args = args_;
gtpu = gtpu_;
build_tai_cgi();
@ -207,7 +215,7 @@ void ngap::initial_ue(uint16_t rnti,
asn1::ngap_nr::rrcestablishment_cause_e cause,
srsran::unique_byte_buffer_t pdu)
{
std::unique_ptr<ue> ue_ptr{new ue{this, rrc, logger}};
std::unique_ptr<ue> ue_ptr{new ue{this, rrc, gtpu, logger}};
ue_ptr->ctxt.rnti = rnti;
ue_ptr->ctxt.gnb_cc_idx = gnb_cc_idx;
ue* u = users.add_user(std::move(ue_ptr));
@ -224,7 +232,7 @@ void ngap::initial_ue(uint16_t rnti,
srsran::unique_byte_buffer_t pdu,
uint32_t s_tmsi)
{
std::unique_ptr<ue> ue_ptr{new ue{this, rrc, logger}};
std::unique_ptr<ue> ue_ptr{new ue{this, rrc, gtpu, logger}};
ue_ptr->ctxt.rnti = rnti;
ue_ptr->ctxt.gnb_cc_idx = gnb_cc_idx;
ue* u = users.add_user(std::move(ue_ptr));
@ -536,6 +544,7 @@ bool ngap::handle_ue_ctxt_release_cmd(const asn1::ngap_nr::ue_context_release_cm
bool ngap::handle_ue_pdu_session_res_setup_request(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg)
{
ue* u =
handle_ngapmsg_ue_id(msg.protocol_ies.ran_ue_ngap_id.value.value, msg.protocol_ies.amf_ue_ngap_id.value.value);
if (u == nullptr) {
@ -543,7 +552,11 @@ bool ngap::handle_ue_pdu_session_res_setup_request(const asn1::ngap_nr::pdu_sess
return false;
}
if (msg.protocol_ies.ue_aggregate_maximum_bit_rate_present) {
rrc->set_aggregate_max_bitrate(u->ctxt.rnti, msg.protocol_ies.ue_aggregate_maximum_bit_rate.value);
}
u->handle_pdu_session_res_setup_request(msg);
return true;
}

@ -23,12 +23,16 @@ namespace srsenb {
/* ngap_ptr::ue Class
********************************************************************************/
ngap::ue::ue(ngap* ngap_ptr_, rrc_interface_ngap_nr* rrc_ptr_, srslog::basic_logger& logger_) :
ngap::ue::ue(ngap* ngap_ptr_,
rrc_interface_ngap_nr* rrc_ptr_,
gtpu_interface_rrc* gtpu_ptr_,
srslog::basic_logger& logger_) :
logger(logger_),
ngap_ptr(ngap_ptr_),
initial_context_setup_proc(this, rrc_ptr_, &ctxt),
ue_context_release_proc(this, rrc_ptr_, &ctxt),
ue_pdu_session_res_setup_proc(this, rrc_ptr_, &ctxt)
bearer_manager(rrc_ptr_, gtpu_ptr_, logger_),
initial_context_setup_proc(this, rrc_ptr_, &ctxt, logger_),
ue_context_release_proc(this, rrc_ptr_, &ctxt, logger_),
ue_pdu_session_res_setup_proc(this, rrc_ptr_, &ctxt, &bearer_manager, logger_)
{
ctxt.ran_ue_ngap_id = ngap_ptr->next_gnb_ue_ngap_id++;
gettimeofday(&ctxt.init_timestamp, nullptr);
@ -180,6 +184,46 @@ bool ngap::ue::send_initial_ctxt_setup_failure(cause_c cause)
return true;
}
bool ngap::ue::send_pdu_session_resource_setup_response(
uint16_t pdu_session_id,
uint32_t teid_out,
asn1::bounded_bitstring<1, 160, true, true> transport_layer_address)
{
if (not ngap_ptr->amf_connected) {
logger.warning("AMF not connected");
return false;
}
// TODO: QOS Params
ngap_pdu_c tx_pdu;
tx_pdu.set_successful_outcome().load_info_obj(ASN1_NGAP_NR_ID_PDU_SESSION_RES_SETUP);
pdu_session_res_setup_resp_s& container = tx_pdu.successful_outcome().value.pdu_session_res_setup_resp();
container.protocol_ies.amf_ue_ngap_id.value = ctxt.amf_ue_ngap_id.value();
container.protocol_ies.ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id;
container.protocol_ies.pdu_session_res_setup_list_su_res_present = true;
pdu_session_res_setup_item_su_res_s su_res;
su_res.pdu_session_res_setup_resp_transfer.resize(512);
su_res.pdu_session_id = pdu_session_id;
pdu_session_res_setup_resp_transfer_s resp_transfer;
gtp_tunnel_s& gtp_tunnel = resp_transfer.dlqos_flow_per_tnl_info.uptransport_layer_info.set_gtp_tunnel();
gtp_tunnel.gtp_teid.from_number(teid_out);
gtp_tunnel.transport_layer_address = transport_layer_address;
asn1::ngap_nr::associated_qos_flow_list_l qos_flow_list;
asn1::ngap_nr::associated_qos_flow_item_s qos_flow_item;
qos_flow_item.qos_flow_id = 1;
qos_flow_list.push_back(qos_flow_item);
resp_transfer.dlqos_flow_per_tnl_info.associated_qos_flow_list = qos_flow_list;
asn1::bit_ref bref(su_res.pdu_session_res_setup_resp_transfer.data(),
su_res.pdu_session_res_setup_resp_transfer.size());
resp_transfer.pack(bref);
su_res.pdu_session_res_setup_resp_transfer.resize(bref.distance_bytes());
container.protocol_ies.pdu_session_res_setup_list_su_res.value.push_back(su_res);
return ngap_ptr->sctp_send_ngap_pdu(tx_pdu, ctxt.rnti, "PDUSessionResourceSetupResponse");
}
/*******************************************************************************
/* NGAP message handler
********************************************************************************/

@ -0,0 +1,93 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2021 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#include "srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h"
namespace srsenb {
ngap_ue_bearer_manager::ngap_ue_bearer_manager(rrc_interface_ngap_nr* rrc_,
gtpu_interface_rrc* gtpu_,
srslog::basic_logger& logger_) :
gtpu(gtpu_), rrc(rrc_), logger(logger_)
{}
ngap_ue_bearer_manager::~ngap_ue_bearer_manager(){};
int ngap_ue_bearer_manager::add_pdu_session(uint16_t rnti,
uint8_t pdu_session_id,
const asn1::ngap_nr::qos_flow_level_qos_params_s& qos,
const asn1::bounded_bitstring<1, 160, true, true>& addr,
uint32_t teid_out,
asn1::ngap_nr::cause_c& cause)
{
// RRC call for QoS parameter and lcid <-> ID mapping
int lcid = rrc->allocate_lcid(rnti);
// Only add session if gtpu was successful
pdu_session_t::gtpu_tunnel tunnel;
if (addr.length() > 32) {
logger.error("Only addresses with length <= 32 (IPv4) are supported");
cause.set_radio_network().value = asn1::ngap_nr::cause_radio_network_opts::invalid_qos_combination;
return SRSRAN_ERROR;
}
// TODO long term remove lcid and just use pdu_session_id and rnti as id for GTP tunnel
int rtn = add_gtpu_bearer(rnti, lcid, pdu_session_id, teid_out, addr, tunnel);
if (rtn != SRSRAN_SUCCESS) {
logger.error("Adding PDU Session ID=%d to GTPU", pdu_session_id);
return SRSRAN_ERROR;
}
pdu_session_list[pdu_session_id].id = pdu_session_id;
pdu_session_list[pdu_session_id].lcid = lcid;
pdu_session_list[pdu_session_id].qos_params = qos;
pdu_session_list[pdu_session_id].tunnels.push_back(tunnel);
return SRSRAN_SUCCESS;
}
int ngap_ue_bearer_manager::add_gtpu_bearer(uint16_t rnti,
uint32_t lcid,
uint32_t pdu_session_id,
uint32_t teid_out,
asn1::bounded_bitstring<1, 160, true, true> address,
pdu_session_t::gtpu_tunnel& tunnel,
const gtpu_interface_rrc::bearer_props* props)
{
// Initialize ERAB tunnel in GTPU right-away. DRBs are only created during RRC setup/reconf
srsran::expected<uint32_t> rtn = gtpu->add_bearer(rnti, lcid, address.to_number(), teid_out, props);
if (rtn.is_error()) {
logger.error("Failed adding pdu_session_id=%d to GTPU", pdu_session_id);
return SRSRAN_ERROR;
}
tunnel.teid_out = teid_out;
tunnel.address = address;
tunnel.teid_in = rtn.value();
logger.info("Added GTPU tunnel for rnti %x, lcid %d, pdu_session_id=%d, address %s",
rnti,
lcid,
pdu_session_id,
address.to_string());
return SRSRAN_SUCCESS;
}
void ngap_ue_bearer_manager::rem_gtpu_bearer(uint16_t rnti, uint32_t pdu_session_id)
{
auto it = pdu_session_list.find(pdu_session_id);
if (it == pdu_session_list.end()) {
logger.warning("Removing pdu_session=%d from GTPU", pdu_session_id);
return;
}
gtpu->rem_bearer(rnti, it->second.lcid);
}
} // namespace srsenb

@ -18,13 +18,9 @@ namespace srsenb {
ngap_ue_initial_context_setup_proc::ngap_ue_initial_context_setup_proc(ngap_interface_ngap_proc* parent_,
rrc_interface_ngap_nr* rrc_,
ngap_ue_ctxt_t* ue_ctxt_) :
logger(srslog::fetch_basic_logger("NGAP UE"))
{
parent = parent_;
rrc = rrc_;
ue_ctxt = ue_ctxt_;
};
ngap_ue_ctxt_t* ue_ctxt_,
srslog::basic_logger& logger_) :
logger(logger_), parent(parent_), rrc(rrc_), ue_ctxt(ue_ctxt_){};
proc_outcome_t ngap_ue_initial_context_setup_proc::init(const asn1::ngap_nr::init_context_setup_request_s& msg)
{
@ -69,8 +65,9 @@ proc_outcome_t ngap_ue_initial_context_setup_proc::step()
ngap_ue_ue_context_release_proc::ngap_ue_ue_context_release_proc(ngap_interface_ngap_proc* parent_,
rrc_interface_ngap_nr* rrc_,
ngap_ue_ctxt_t* ue_ctxt_) :
logger(srslog::fetch_basic_logger("NGAP UE"))
ngap_ue_ctxt_t* ue_ctxt_,
srslog::basic_logger& logger_) :
logger(logger_)
{
parent = parent_;
rrc = rrc_;
@ -81,6 +78,7 @@ proc_outcome_t ngap_ue_ue_context_release_proc::init(const asn1::ngap_nr::ue_con
{
// ue_ngap_ids_c ue_ngap_ids = msg.protocol_ies.ue_ngap_ids.value;
// cause_c cause = msg.protocol_ies.cause.value;
logger.info("Started %s", name());
return proc_outcome_t::success;
}
@ -91,33 +89,81 @@ proc_outcome_t ngap_ue_ue_context_release_proc::step()
ngap_ue_pdu_session_res_setup_proc::ngap_ue_pdu_session_res_setup_proc(ngap_interface_ngap_proc* parent_,
rrc_interface_ngap_nr* rrc_,
ngap_ue_ctxt_t* ue_ctxt_) :
logger(srslog::fetch_basic_logger("NGAP UE"))
{
parent = parent_;
rrc = rrc_;
ue_ctxt = ue_ctxt_;
}
ngap_ue_ctxt_t* ue_ctxt_,
ngap_ue_bearer_manager* bearer_manager_,
srslog::basic_logger& logger_) :
parent(parent_), rrc(rrc_), ue_ctxt(ue_ctxt_), bearer_manager(bearer_manager_), logger(logger_)
{}
proc_outcome_t ngap_ue_pdu_session_res_setup_proc::init(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg)
{
if (msg.protocol_ies.pdu_session_res_setup_list_su_req.value.size() != 1) {
logger.error("Not handling multiple su requests");
logger.error("Not handling zero or multiple su requests");
return proc_outcome_t::error;
}
asn1::ngap_nr::pdu_session_res_setup_item_su_req_s su_req =
msg.protocol_ies.pdu_session_res_setup_list_su_req.value[0];
if (su_req.pdu_session_nas_pdu_present) {
srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer();
if (pdu == nullptr) {
logger.error("Fatal Error: Couldn't allocate buffer in ngap_ue_initial_context_setup_proc::init().");
asn1::cbit_ref pdu_session_bref(su_req.pdu_session_res_setup_request_transfer.data(),
su_req.pdu_session_res_setup_request_transfer.size());
asn1::ngap_nr::pdu_session_res_setup_request_transfer_s pdu_ses_res_setup_req_trans;
if (pdu_ses_res_setup_req_trans.unpack(pdu_session_bref) != SRSRAN_SUCCESS) {
logger.error("Unable to unpack PDU session response setup request");
return proc_outcome_t::error;
}
memcpy(pdu->msg, su_req.pdu_session_nas_pdu.data(), su_req.pdu_session_nas_pdu.size());
pdu->N_bytes = su_req.pdu_session_nas_pdu.size();
rrc->write_dl_info(ue_ctxt->rnti, std::move(pdu));
if (pdu_ses_res_setup_req_trans.protocol_ies.qos_flow_setup_request_list.value.size() != 1) {
logger.error("Expected one item in QoS flow setup request list");
return proc_outcome_t::error;
}
if (pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.type() !=
asn1::ngap_nr::up_transport_layer_info_c::types::gtp_tunnel) {
logger.error("Expected GTP Tunnel");
return proc_outcome_t::error;
}
asn1::ngap_nr::qos_flow_setup_request_item_s qos_flow_setup =
pdu_ses_res_setup_req_trans.protocol_ies.qos_flow_setup_request_list.value[0];
srsran::const_span<uint8_t> nas_pdu_dummy;
asn1::ngap_nr::cause_c cause;
uint32_t teid_out = 0;
int lcid;
teid_out |= pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[0] << 24u;
teid_out |= pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[1] << 16u;
teid_out |= pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[2] << 8u;
teid_out |= pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[3];
// TODO: Check cause
if (bearer_manager->add_pdu_session(
ue_ctxt->rnti,
su_req.pdu_session_id,
qos_flow_setup.qos_flow_level_qos_params,
pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().transport_layer_address,
teid_out,
cause) != SRSRAN_SUCCESS) {
logger.warning("Failed to add pdu session\n");
return proc_outcome_t::error;
}
// QoS parameter mapping in config in LTE enb
// Transport Layer Address required by the procedure for the reponse
asn1::bounded_bitstring<1, 160, true, true> transport_layer_address;
transport_layer_address =
pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().transport_layer_address;
if (su_req.pdu_session_nas_pdu_present) {
lcid = rrc->allocate_lcid(ue_ctxt->rnti);
if (rrc->establish_rrc_bearer(ue_ctxt->rnti, su_req.pdu_session_id, su_req.pdu_session_nas_pdu, lcid) ==
SRSRAN_SUCCESS) {
parent->send_pdu_session_resource_setup_response(su_req.pdu_session_id, teid_out, transport_layer_address);
return proc_outcome_t::success;
}
}
return proc_outcome_t::yield;
}

@ -390,6 +390,10 @@ int rrc_nr::ue_set_bitrates(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_max
{
return SRSRAN_SUCCESS;
}
int rrc_nr::set_aggregate_max_bitrate(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates)
{
return SRSRAN_SUCCESS;
}
int rrc_nr::ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps)
{
return SRSRAN_SUCCESS;
@ -398,6 +402,16 @@ int rrc_nr::start_security_mode_procedure(uint16_t rnti)
{
return SRSRAN_SUCCESS;
}
int rrc_nr::establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid)
{
return SRSRAN_SUCCESS;
}
int rrc_nr::allocate_lcid(uint16_t rnti)
{
return SRSRAN_SUCCESS;
}
void rrc_nr::write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) {}
/*******************************************************************************

@ -73,11 +73,20 @@ public:
{
return SRSRAN_SUCCESS;
}
int set_aggregate_max_bitrate(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates)
{
return SRSRAN_SUCCESS;
}
int ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps)
{
return SRSRAN_SUCCESS;
}
int start_security_mode_procedure(uint16_t rnti) { return SRSRAN_SUCCESS; }
int establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid)
{
return SRSRAN_SUCCESS;
}
int allocate_lcid(uint16_t rnti) { return SRSRAN_SUCCESS; }
void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) {}
};
struct dummy_socket_manager : public srsran::socket_manager_itf {
@ -163,7 +172,8 @@ int main(int argc, char** argv)
args.gnb_name = "srsgnb01";
rrc_nr_dummy rrc;
ngap_obj.init(args, &rrc);
gtpu_interface_rrc* gtpu = nullptr;
ngap_obj.init(args, &rrc, gtpu);
// Start the log backend.
srsran::test_init(argc, argv);

@ -118,6 +118,9 @@ private:
srsran::proc_t<registration_procedure> registration_proc;
srsran::proc_t<pdu_session_establishment_procedure> pdu_session_establishment_proc;
// Network information
srsran::nas_5g::network_name_t full_network_name;
// Message sender
int send_registration_request();
int send_authentication_response(const uint8_t res[16]);
@ -146,6 +149,7 @@ private:
srsran::nas_5g::deregistration_accept_ue_terminated_t& deregistration_accept_ue_terminated);
int handle_deregistration_request_ue_terminated(
srsran::nas_5g::deregistration_request_ue_terminated_t& deregistration_request_ue_terminated);
int handle_configuration_update_command(srsran::nas_5g::configuration_update_command_t& configuration_update_command);
int handle_dl_nas_transport(srsran::nas_5g::dl_nas_transport_t& dl_nas_transport);
// message handler container

@ -581,7 +581,7 @@ int nas_5g::send_pdu_session_establishment_request(uint32_t tran
pdu->N_bytes - SEQ_5G_OFFSET,
&pdu->msg[MAC_5G_OFFSET]);
logger.info("Sending PDU Session Establishment Complete in UL NAS transport.");
logger.info("Sending PDU Session Establishment Request in UL NAS transport.");
rrc_nr->write_sdu(std::move(pdu));
return SRSRAN_SUCCESS;

Loading…
Cancel
Save