nr,gnb,stack: add bearer manager to gNB stack to correctly map between eps bearer ids and lcids

master
Francisco 3 years ago committed by Francisco Paisana
parent 6513520211
commit b27c184d2f

@ -18,8 +18,8 @@
#include "srsran/common/rwlock_guard.h" #include "srsran/common/rwlock_guard.h"
#include "srsran/srslog/srslog.h" #include "srsran/srslog/srslog.h"
#include <map> #include <map>
#include <unordered_map>
#include <stdint.h> #include <stdint.h>
#include <unordered_map>
namespace srsran { namespace srsran {
@ -139,6 +139,7 @@ public:
using radio_bearer_t = srsran::detail::ue_bearer_manager_impl::radio_bearer_t; using radio_bearer_t = srsran::detail::ue_bearer_manager_impl::radio_bearer_t;
enb_bearer_manager(); enb_bearer_manager();
~enb_bearer_manager();
/// Multi-user interface (see comments above) /// Multi-user interface (see comments above)
void add_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id, srsran::srsran_rat_t rat, uint32_t lcid); void add_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id, srsran::srsran_rat_t rat, uint32_t lcid);

@ -113,13 +113,15 @@ namespace srsenb {
enb_bearer_manager::enb_bearer_manager() : logger(srslog::fetch_basic_logger("STCK", false)) {} enb_bearer_manager::enb_bearer_manager() : logger(srslog::fetch_basic_logger("STCK", false)) {}
enb_bearer_manager::~enb_bearer_manager() {}
void enb_bearer_manager::add_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id, srsran::srsran_rat_t rat, uint32_t lcid) void enb_bearer_manager::add_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id, srsran::srsran_rat_t rat, uint32_t lcid)
{ {
auto user_it = users_map.find(rnti); auto user_it = users_map.find(rnti);
if (user_it == users_map.end()) { if (user_it == users_map.end()) {
// add empty bearer map // add empty bearer map
// users_map.emplace( ) returns pair<iterator,bool> // users_map.emplace( ) returns pair<iterator,bool>
auto p = users_map.emplace( rnti, srsran::detail::ue_bearer_manager_impl{}); auto p = users_map.emplace(rnti, srsran::detail::ue_bearer_manager_impl{});
if (!p.second) { if (!p.second) {
logger.error("Bearers: Unable to add a new bearer map for rnti=0x%x", rnti); logger.error("Bearers: Unable to add a new bearer map for rnti=0x%x", rnti);
return; return;

@ -33,6 +33,8 @@ namespace srsenb {
class ngap; class ngap;
class gtpu; class gtpu;
class enb_bearer_manager;
class gtpu_pdcp_adapter_nr;
struct gnb_stack_args_t { struct gnb_stack_args_t {
stack_log_args_t log; stack_log_args_t log;
@ -153,6 +155,9 @@ private:
std::unique_ptr<srsenb::gtpu> gtpu; std::unique_ptr<srsenb::gtpu> gtpu;
// std::unique_ptr<sdap> m_sdap; // std::unique_ptr<sdap> m_sdap;
std::unique_ptr<enb_bearer_manager> bearer_manager;
std::unique_ptr<gtpu_pdcp_adapter_nr> gtpu_adapter;
// state // state
std::atomic<bool> running = {false}; std::atomic<bool> running = {false};
}; };

@ -37,6 +37,8 @@
namespace srsenb { namespace srsenb {
class enb_bearer_manager;
enum class rrc_nr_state_t { RRC_IDLE, RRC_INACTIVE, RRC_CONNECTED }; enum class rrc_nr_state_t { RRC_IDLE, RRC_INACTIVE, RRC_CONNECTED };
class rrc_nr final : public rrc_interface_pdcp_nr, class rrc_nr final : public rrc_interface_pdcp_nr,
@ -55,7 +57,7 @@ public:
rlc_interface_rrc* rlc, rlc_interface_rrc* rlc,
pdcp_interface_rrc* pdcp, pdcp_interface_rrc* pdcp,
ngap_interface_rrc_nr* ngap_, ngap_interface_rrc_nr* ngap_,
gtpu_interface_rrc_nr* gtpu, enb_bearer_manager& bearer_mapper_,
rrc_eutra_interface_rrc_nr* rrc_eutra_); rrc_eutra_interface_rrc_nr* rrc_eutra_);
void stop(); void stop();
@ -121,13 +123,13 @@ private:
rrc_nr_cfg_t cfg = {}; rrc_nr_cfg_t cfg = {};
// interfaces // interfaces
phy_interface_stack_nr* phy = nullptr; phy_interface_stack_nr* phy = nullptr;
mac_interface_rrc_nr* mac = nullptr; mac_interface_rrc_nr* mac = nullptr;
rlc_interface_rrc* rlc = nullptr; rlc_interface_rrc* rlc = nullptr;
pdcp_interface_rrc* pdcp = nullptr; pdcp_interface_rrc* pdcp = nullptr;
gtpu_interface_rrc_nr* gtpu = nullptr; ngap_interface_rrc_nr* ngap = nullptr;
ngap_interface_rrc_nr* ngap = nullptr; rrc_eutra_interface_rrc_nr* rrc_eutra = nullptr;
rrc_eutra_interface_rrc_nr* rrc_eutra = nullptr; enb_bearer_manager* bearer_mapper = nullptr;
// args // args
srsran::task_sched_handle task_sched; srsran::task_sched_handle task_sched;

@ -13,6 +13,7 @@
#include "srsgnb/hdr/stack/gnb_stack_nr.h" #include "srsgnb/hdr/stack/gnb_stack_nr.h"
#include "srsenb/hdr/stack/upper/gtpu.h" #include "srsenb/hdr/stack/upper/gtpu.h"
#include "srsgnb/hdr/stack/ngap/ngap.h" #include "srsgnb/hdr/stack/ngap/ngap.h"
#include "srsran/common/bearer_manager.h"
#include "srsran/common/network_utils.h" #include "srsran/common/network_utils.h"
#include "srsran/common/standard_streams.h" #include "srsran/common/standard_streams.h"
#include "srsran/srsran.h" #include "srsran/srsran.h"
@ -20,6 +21,46 @@
namespace srsenb { namespace srsenb {
class gtpu_pdcp_adapter_nr final : public gtpu_interface_pdcp, public pdcp_interface_gtpu
{
public:
gtpu_pdcp_adapter_nr(srslog::basic_logger& logger_,
pdcp_interface_gtpu* pdcp_,
gtpu* gtpu_,
enb_bearer_manager& bearers_) :
logger(logger_), pdcp_obj(pdcp_), gtpu_obj(gtpu_), bearers(&bearers_)
{}
/// Converts LCID to EPS-BearerID and sends corresponding PDU to GTPU
void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) override
{
auto bearer = bearers->get_lcid_bearer(rnti, lcid);
if (not bearer.is_valid()) {
logger.error("Bearer rnti=0x%x, lcid=%d not found", rnti, lcid);
return;
}
gtpu_obj->write_pdu(rnti, bearer.eps_bearer_id, std::move(pdu));
}
void write_sdu(uint16_t rnti, uint32_t eps_bearer_id, srsran::unique_byte_buffer_t sdu, int pdcp_sn = -1) override
{
auto bearer = bearers->get_radio_bearer(rnti, eps_bearer_id);
// route SDU to PDCP entity
pdcp_obj->write_sdu(rnti, bearer.lcid, std::move(sdu), pdcp_sn);
}
std::map<uint32_t, srsran::unique_byte_buffer_t> get_buffered_pdus(uint16_t rnti, uint32_t eps_bearer_id) override
{
auto bearer = bearers->get_radio_bearer(rnti, eps_bearer_id);
// route SDU to PDCP entity
return pdcp_obj->get_buffered_pdus(rnti, bearer.lcid);
}
private:
srslog::basic_logger& logger;
gtpu* gtpu_obj = nullptr;
pdcp_interface_gtpu* pdcp_obj = nullptr;
enb_bearer_manager* bearers = nullptr;
};
gnb_stack_nr::gnb_stack_nr(srslog::sink& log_sink) : gnb_stack_nr::gnb_stack_nr(srslog::sink& log_sink) :
task_sched{512, 128}, task_sched{512, 128},
thread("gNB"), thread("gNB"),
@ -33,6 +74,7 @@ gnb_stack_nr::gnb_stack_nr(srslog::sink& log_sink) :
mac(&task_sched), mac(&task_sched),
rrc(&task_sched), rrc(&task_sched),
pdcp(&task_sched, pdcp_logger), pdcp(&task_sched, pdcp_logger),
bearer_manager(new srsenb::enb_bearer_manager()),
rlc(rlc_logger) rlc(rlc_logger)
{ {
sync_task_queue = task_sched.make_task_queue(); sync_task_queue = task_sched.make_task_queue();
@ -81,6 +123,7 @@ int gnb_stack_nr::init(const gnb_stack_args_t& args_,
// SA mode // SA mode
ngap.reset(new srsenb::ngap(&task_sched, ngap_logger, &srsran::get_rx_io_manager())); ngap.reset(new srsenb::ngap(&task_sched, ngap_logger, &srsran::get_rx_io_manager()));
gtpu.reset(new srsenb::gtpu(&task_sched, gtpu_logger, &srsran::get_rx_io_manager())); gtpu.reset(new srsenb::gtpu(&task_sched, gtpu_logger, &srsran::get_rx_io_manager()));
gtpu_adapter.reset(new gtpu_pdcp_adapter_nr(gtpu_logger, &pdcp, gtpu.get(), *bearer_manager));
} }
// Init all layers // Init all layers
@ -90,14 +133,15 @@ int gnb_stack_nr::init(const gnb_stack_args_t& args_,
} }
rlc.init(&pdcp, &rrc, &mac, task_sched.get_timer_handler()); rlc.init(&pdcp, &rrc, &mac, task_sched.get_timer_handler());
pdcp.init(&rlc, &rrc, x2_);
if (rrc.init(rrc_cfg_, phy, &mac, &rlc, &pdcp, ngap.get(), nullptr, x2_) != SRSRAN_SUCCESS) { if (rrc.init(rrc_cfg_, phy, &mac, &rlc, &pdcp, ngap.get(), *bearer_manager, x2_) != SRSRAN_SUCCESS) {
stack_logger.error("Couldn't initialize RRC"); stack_logger.error("Couldn't initialize RRC");
return SRSRAN_ERROR; return SRSRAN_ERROR;
} }
if (ngap != nullptr) { if (ngap != nullptr) {
pdcp.init(&rlc, &rrc, gtpu_adapter.get());
if (args.ngap_pcap.enable) { if (args.ngap_pcap.enable) {
ngap_pcap.open(args.ngap_pcap.filename.c_str()); ngap_pcap.open(args.ngap_pcap.filename.c_str());
ngap->start_pcap(&ngap_pcap); ngap->start_pcap(&ngap_pcap);
@ -108,7 +152,9 @@ int gnb_stack_nr::init(const gnb_stack_args_t& args_,
gtpu_args.embms_enable = false; gtpu_args.embms_enable = false;
gtpu_args.mme_addr = args.ngap.amf_addr; gtpu_args.mme_addr = args.ngap.amf_addr;
gtpu_args.gtp_bind_addr = args.ngap.gtp_bind_addr; gtpu_args.gtp_bind_addr = args.ngap.gtp_bind_addr;
gtpu->init(gtpu_args, &pdcp); gtpu->init(gtpu_args, gtpu_adapter.get());
} else {
pdcp.init(&rlc, &rrc, x2_);
} }
// TODO: add SDAP // TODO: add SDAP

@ -17,6 +17,7 @@
#include "srsgnb/hdr/stack/rrc/rrc_nr_ue.h" #include "srsgnb/hdr/stack/rrc/rrc_nr_ue.h"
#include "srsgnb/src/stack/mac/test/sched_nr_cfg_generators.h" #include "srsgnb/src/stack/mac/test/sched_nr_cfg_generators.h"
#include "srsran/asn1/rrc_nr_utils.h" #include "srsran/asn1/rrc_nr_utils.h"
#include "srsran/common/bearer_manager.h"
#include "srsran/common/common_nr.h" #include "srsran/common/common_nr.h"
#include "srsran/common/phy_cfg_nr_default.h" #include "srsran/common/phy_cfg_nr_default.h"
#include "srsran/common/standard_streams.h" #include "srsran/common/standard_streams.h"
@ -38,16 +39,16 @@ int rrc_nr::init(const rrc_nr_cfg_t& cfg_,
rlc_interface_rrc* rlc_, rlc_interface_rrc* rlc_,
pdcp_interface_rrc* pdcp_, pdcp_interface_rrc* pdcp_,
ngap_interface_rrc_nr* ngap_, ngap_interface_rrc_nr* ngap_,
gtpu_interface_rrc_nr* gtpu_, enb_bearer_manager& bearer_mapper_,
rrc_eutra_interface_rrc_nr* rrc_eutra_) rrc_eutra_interface_rrc_nr* rrc_eutra_)
{ {
phy = phy_; phy = phy_;
mac = mac_; mac = mac_;
rlc = rlc_; rlc = rlc_;
pdcp = pdcp_; pdcp = pdcp_;
ngap = ngap_; ngap = ngap_;
gtpu = gtpu_; bearer_mapper = &bearer_mapper_;
rrc_eutra = rrc_eutra_; rrc_eutra = rrc_eutra_;
cfg = cfg_; cfg = cfg_;

@ -14,6 +14,7 @@
#include "srsgnb/hdr/stack/rrc/cell_asn1_config.h" #include "srsgnb/hdr/stack/rrc/cell_asn1_config.h"
#include "srsgnb/hdr/stack/rrc/rrc_nr_config_utils.h" #include "srsgnb/hdr/stack/rrc/rrc_nr_config_utils.h"
#include "srsran/asn1/rrc_nr_utils.h" #include "srsran/asn1/rrc_nr_utils.h"
#include "srsran/common/bearer_manager.h"
#include "srsran/common/string_helpers.h" #include "srsran/common/string_helpers.h"
using namespace asn1::rrc_nr; using namespace asn1::rrc_nr;
@ -1180,6 +1181,9 @@ void rrc_nr::ue::establish_eps_bearer(uint32_t pdu_session_id, srsran::const_byt
next_radio_bearer_cfg.drb_to_add_mod_list_present = true; next_radio_bearer_cfg.drb_to_add_mod_list_present = true;
next_radio_bearer_cfg.drb_to_add_mod_list.push_back(drb); next_radio_bearer_cfg.drb_to_add_mod_list.push_back(drb);
parent->bearer_mapper->add_eps_bearer(
rnti, lcid - 3, srsran::srsran_rat_t::nr, lcid); // TODO: configurable bearer id <-> lcid mapping
logger.info("Established EPS bearer for LCID %u and RNTI 0x%x", lcid, rnti); logger.info("Established EPS bearer for LCID %u and RNTI 0x%x", lcid, rnti);
} }

@ -13,6 +13,7 @@
#include "rrc_nr_test_helpers.h" #include "rrc_nr_test_helpers.h"
#include "srsgnb/hdr/stack/rrc/rrc_nr_config_utils.h" #include "srsgnb/hdr/stack/rrc/rrc_nr_config_utils.h"
#include "srsgnb/src/stack/mac/test/sched_nr_cfg_generators.h" #include "srsgnb/src/stack/mac/test/sched_nr_cfg_generators.h"
#include "srsran/common/bearer_manager.h"
#include "srsran/common/test_common.h" #include "srsran/common/test_common.h"
#include "srsran/interfaces/gnb_rrc_nr_interfaces.h" #include "srsran/interfaces/gnb_rrc_nr_interfaces.h"
#include <iostream> #include <iostream>
@ -45,6 +46,7 @@ void test_sib_generation()
rlc_dummy rlc_obj; rlc_dummy rlc_obj;
pdcp_dummy pdcp_obj; pdcp_dummy pdcp_obj;
rrc_nr rrc_obj(&task_sched); rrc_nr rrc_obj(&task_sched);
enb_bearer_manager bearer_mapper;
// set cfg // set cfg
rrc_nr_cfg_t rrc_cfg_nr = {}; rrc_nr_cfg_t rrc_cfg_nr = {};
@ -59,7 +61,7 @@ void test_sib_generation()
set_derived_nr_cell_params(rrc_cfg_nr.is_standalone, rrc_cfg_nr.cell_list[0]); set_derived_nr_cell_params(rrc_cfg_nr.is_standalone, rrc_cfg_nr.cell_list[0]);
srsran_assert(check_rrc_nr_cfg_valid(rrc_cfg_nr) == SRSRAN_SUCCESS, "Invalid RRC NR configuration"); srsran_assert(check_rrc_nr_cfg_valid(rrc_cfg_nr) == SRSRAN_SUCCESS, "Invalid RRC NR configuration");
TESTASSERT(rrc_obj.init(rrc_cfg_nr, &phy_obj, &mac_obj, &rlc_obj, &pdcp_obj, nullptr, nullptr, nullptr) == TESTASSERT(rrc_obj.init(rrc_cfg_nr, &phy_obj, &mac_obj, &rlc_obj, &pdcp_obj, nullptr, bearer_mapper, nullptr) ==
SRSRAN_SUCCESS); SRSRAN_SUCCESS);
const sched_nr_interface::cell_cfg_t& nrcell = mac_obj.nr_cells.at(0); const sched_nr_interface::cell_cfg_t& nrcell = mac_obj.nr_cells.at(0);
@ -97,6 +99,7 @@ int test_rrc_setup()
mac_nr_dummy mac_obj; mac_nr_dummy mac_obj;
rlc_dummy rlc_obj; rlc_dummy rlc_obj;
pdcp_dummy pdcp_obj; pdcp_dummy pdcp_obj;
enb_bearer_manager bearer_mapper;
rrc_nr rrc_obj(&task_sched); rrc_nr rrc_obj(&task_sched);
// set cfg // set cfg
@ -110,7 +113,7 @@ int test_rrc_setup()
rrc_cfg_nr.is_standalone = false; rrc_cfg_nr.is_standalone = false;
set_derived_nr_cell_params(rrc_cfg_nr.is_standalone, rrc_cfg_nr.cell_list[0]); set_derived_nr_cell_params(rrc_cfg_nr.is_standalone, rrc_cfg_nr.cell_list[0]);
srsran_assert(check_rrc_nr_cfg_valid(rrc_cfg_nr) == SRSRAN_SUCCESS, "Invalid RRC NR configuration"); srsran_assert(check_rrc_nr_cfg_valid(rrc_cfg_nr) == SRSRAN_SUCCESS, "Invalid RRC NR configuration");
TESTASSERT(rrc_obj.init(rrc_cfg_nr, &phy_obj, &mac_obj, &rlc_obj, &pdcp_obj, nullptr, nullptr, nullptr) == TESTASSERT(rrc_obj.init(rrc_cfg_nr, &phy_obj, &mac_obj, &rlc_obj, &pdcp_obj, nullptr, bearer_mapper, nullptr) ==
SRSRAN_SUCCESS); SRSRAN_SUCCESS);
for (uint32_t n = 0; n < 2; ++n) { for (uint32_t n = 0; n < 2; ++n) {
@ -134,6 +137,7 @@ void test_rrc_sa_connection()
rlc_nr_rrc_tester rlc_obj; rlc_nr_rrc_tester rlc_obj;
pdcp_nr_rrc_tester pdcp_obj; pdcp_nr_rrc_tester pdcp_obj;
ngap_rrc_tester ngap_obj; ngap_rrc_tester ngap_obj;
enb_bearer_manager bearer_mapper;
rrc_nr rrc_obj(&task_sched); rrc_nr rrc_obj(&task_sched);
@ -150,7 +154,7 @@ void test_rrc_sa_connection()
set_derived_nr_cell_params(rrc_cfg_nr.is_standalone, rrc_cfg_nr.cell_list[0]); set_derived_nr_cell_params(rrc_cfg_nr.is_standalone, rrc_cfg_nr.cell_list[0]);
srsran_assert(check_rrc_nr_cfg_valid(rrc_cfg_nr) == SRSRAN_SUCCESS, "Invalid RRC NR configuration"); srsran_assert(check_rrc_nr_cfg_valid(rrc_cfg_nr) == SRSRAN_SUCCESS, "Invalid RRC NR configuration");
TESTASSERT(rrc_obj.init(rrc_cfg_nr, &phy_obj, &mac_obj, &rlc_obj, &pdcp_obj, &ngap_obj, nullptr, nullptr) == TESTASSERT(rrc_obj.init(rrc_cfg_nr, &phy_obj, &mac_obj, &rlc_obj, &pdcp_obj, &ngap_obj, bearer_mapper, nullptr) ==
SRSRAN_SUCCESS); SRSRAN_SUCCESS);
sched_nr_ue_cfg_t uecfg = get_default_ue_cfg(1); sched_nr_ue_cfg_t uecfg = get_default_ue_cfg(1);
@ -158,7 +162,7 @@ void test_rrc_sa_connection()
uecfg.phy_cfg.pdcch.search_space_present[2] = false; uecfg.phy_cfg.pdcch.search_space_present[2] = false;
TESTASSERT_SUCCESS(rrc_obj.add_user(0x4601, uecfg)); TESTASSERT_SUCCESS(rrc_obj.add_user(0x4601, uecfg));
test_rrc_nr_connection_establishment(task_sched, rrc_obj, rlc_obj, mac_obj, ngap_obj,0x4601); test_rrc_nr_connection_establishment(task_sched, rrc_obj, rlc_obj, mac_obj, ngap_obj, 0x4601);
test_rrc_nr_info_transfer(task_sched, rrc_obj, pdcp_obj, ngap_obj, 0x4601); test_rrc_nr_info_transfer(task_sched, rrc_obj, pdcp_obj, ngap_obj, 0x4601);
test_rrc_nr_security_mode_cmd(task_sched, rrc_obj, pdcp_obj, 0x4601); test_rrc_nr_security_mode_cmd(task_sched, rrc_obj, pdcp_obj, 0x4601);
test_rrc_nr_reconfiguration(task_sched, rrc_obj, pdcp_obj, ngap_obj, 0x4601); test_rrc_nr_reconfiguration(task_sched, rrc_obj, pdcp_obj, ngap_obj, 0x4601);
@ -191,9 +195,8 @@ int main(int argc, char** argv)
srsenb::test_sib_generation(); srsenb::test_sib_generation();
TESTASSERT(srsenb::test_rrc_setup() == SRSRAN_SUCCESS); TESTASSERT(srsenb::test_rrc_setup() == SRSRAN_SUCCESS);
srsenb::test_rrc_sa_connection(); srsenb::test_rrc_sa_connection();
TESTASSERT_EQ( 0, spy->get_warning_counter()); TESTASSERT_EQ(0, spy->get_warning_counter());
TESTASSERT_EQ( 0, spy->get_error_counter()); TESTASSERT_EQ(0, spy->get_error_counter());
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
} }

Loading…
Cancel
Save