From b27c184d2f6185d1b46bcc2a57288370a4195837 Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 26 Nov 2021 18:38:21 +0000 Subject: [PATCH] nr,gnb,stack: add bearer manager to gNB stack to correctly map between eps bearer ids and lcids --- lib/include/srsran/common/bearer_manager.h | 3 +- lib/src/common/bearer_manager.cc | 4 +- srsgnb/hdr/stack/gnb_stack_nr.h | 5 +++ srsgnb/hdr/stack/rrc/rrc_nr.h | 18 ++++---- srsgnb/src/stack/gnb_stack_nr.cc | 52 ++++++++++++++++++++-- srsgnb/src/stack/rrc/rrc_nr.cc | 17 +++---- srsgnb/src/stack/rrc/rrc_nr_ue.cc | 4 ++ srsgnb/src/stack/rrc/test/rrc_nr_test.cc | 17 ++++--- 8 files changed, 92 insertions(+), 28 deletions(-) diff --git a/lib/include/srsran/common/bearer_manager.h b/lib/include/srsran/common/bearer_manager.h index 4ec7bff81..0e525408c 100644 --- a/lib/include/srsran/common/bearer_manager.h +++ b/lib/include/srsran/common/bearer_manager.h @@ -18,8 +18,8 @@ #include "srsran/common/rwlock_guard.h" #include "srsran/srslog/srslog.h" #include -#include #include +#include namespace srsran { @@ -139,6 +139,7 @@ public: using radio_bearer_t = srsran::detail::ue_bearer_manager_impl::radio_bearer_t; enb_bearer_manager(); + ~enb_bearer_manager(); /// 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); diff --git a/lib/src/common/bearer_manager.cc b/lib/src/common/bearer_manager.cc index 3114a0c5e..c4ecf960b 100644 --- a/lib/src/common/bearer_manager.cc +++ b/lib/src/common/bearer_manager.cc @@ -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() {} + 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); if (user_it == users_map.end()) { // add empty bearer map // users_map.emplace( ) returns pair - 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) { logger.error("Bearers: Unable to add a new bearer map for rnti=0x%x", rnti); return; diff --git a/srsgnb/hdr/stack/gnb_stack_nr.h b/srsgnb/hdr/stack/gnb_stack_nr.h index 57bebcc1e..9528f9e86 100644 --- a/srsgnb/hdr/stack/gnb_stack_nr.h +++ b/srsgnb/hdr/stack/gnb_stack_nr.h @@ -33,6 +33,8 @@ namespace srsenb { class ngap; class gtpu; +class enb_bearer_manager; +class gtpu_pdcp_adapter_nr; struct gnb_stack_args_t { stack_log_args_t log; @@ -153,6 +155,9 @@ private: std::unique_ptr gtpu; // std::unique_ptr m_sdap; + std::unique_ptr bearer_manager; + std::unique_ptr gtpu_adapter; + // state std::atomic running = {false}; }; diff --git a/srsgnb/hdr/stack/rrc/rrc_nr.h b/srsgnb/hdr/stack/rrc/rrc_nr.h index a82e5fb16..afe3e00c0 100644 --- a/srsgnb/hdr/stack/rrc/rrc_nr.h +++ b/srsgnb/hdr/stack/rrc/rrc_nr.h @@ -37,6 +37,8 @@ namespace srsenb { +class enb_bearer_manager; + enum class rrc_nr_state_t { RRC_IDLE, RRC_INACTIVE, RRC_CONNECTED }; class rrc_nr final : public rrc_interface_pdcp_nr, @@ -55,7 +57,7 @@ public: rlc_interface_rrc* rlc, pdcp_interface_rrc* pdcp, ngap_interface_rrc_nr* ngap_, - gtpu_interface_rrc_nr* gtpu, + enb_bearer_manager& bearer_mapper_, rrc_eutra_interface_rrc_nr* rrc_eutra_); void stop(); @@ -121,13 +123,13 @@ private: rrc_nr_cfg_t cfg = {}; // interfaces - phy_interface_stack_nr* phy = nullptr; - mac_interface_rrc_nr* mac = nullptr; - rlc_interface_rrc* rlc = nullptr; - pdcp_interface_rrc* pdcp = nullptr; - gtpu_interface_rrc_nr* gtpu = nullptr; - ngap_interface_rrc_nr* ngap = nullptr; - rrc_eutra_interface_rrc_nr* rrc_eutra = nullptr; + phy_interface_stack_nr* phy = nullptr; + mac_interface_rrc_nr* mac = nullptr; + rlc_interface_rrc* rlc = nullptr; + pdcp_interface_rrc* pdcp = nullptr; + ngap_interface_rrc_nr* ngap = nullptr; + rrc_eutra_interface_rrc_nr* rrc_eutra = nullptr; + enb_bearer_manager* bearer_mapper = nullptr; // args srsran::task_sched_handle task_sched; diff --git a/srsgnb/src/stack/gnb_stack_nr.cc b/srsgnb/src/stack/gnb_stack_nr.cc index 9bfd1a3f0..8dd4adae4 100644 --- a/srsgnb/src/stack/gnb_stack_nr.cc +++ b/srsgnb/src/stack/gnb_stack_nr.cc @@ -13,6 +13,7 @@ #include "srsgnb/hdr/stack/gnb_stack_nr.h" #include "srsenb/hdr/stack/upper/gtpu.h" #include "srsgnb/hdr/stack/ngap/ngap.h" +#include "srsran/common/bearer_manager.h" #include "srsran/common/network_utils.h" #include "srsran/common/standard_streams.h" #include "srsran/srsran.h" @@ -20,6 +21,46 @@ 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 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) : task_sched{512, 128}, thread("gNB"), @@ -33,6 +74,7 @@ gnb_stack_nr::gnb_stack_nr(srslog::sink& log_sink) : mac(&task_sched), rrc(&task_sched), pdcp(&task_sched, pdcp_logger), + bearer_manager(new srsenb::enb_bearer_manager()), rlc(rlc_logger) { 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 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_adapter.reset(new gtpu_pdcp_adapter_nr(gtpu_logger, &pdcp, gtpu.get(), *bearer_manager)); } // 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()); - 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"); return SRSRAN_ERROR; } if (ngap != nullptr) { + pdcp.init(&rlc, &rrc, gtpu_adapter.get()); + if (args.ngap_pcap.enable) { ngap_pcap.open(args.ngap_pcap.filename.c_str()); 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.mme_addr = args.ngap.amf_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 diff --git a/srsgnb/src/stack/rrc/rrc_nr.cc b/srsgnb/src/stack/rrc/rrc_nr.cc index fdb97a6bb..28ba94bcd 100644 --- a/srsgnb/src/stack/rrc/rrc_nr.cc +++ b/srsgnb/src/stack/rrc/rrc_nr.cc @@ -17,6 +17,7 @@ #include "srsgnb/hdr/stack/rrc/rrc_nr_ue.h" #include "srsgnb/src/stack/mac/test/sched_nr_cfg_generators.h" #include "srsran/asn1/rrc_nr_utils.h" +#include "srsran/common/bearer_manager.h" #include "srsran/common/common_nr.h" #include "srsran/common/phy_cfg_nr_default.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_, pdcp_interface_rrc* pdcp_, ngap_interface_rrc_nr* ngap_, - gtpu_interface_rrc_nr* gtpu_, + enb_bearer_manager& bearer_mapper_, rrc_eutra_interface_rrc_nr* rrc_eutra_) { - phy = phy_; - mac = mac_; - rlc = rlc_; - pdcp = pdcp_; - ngap = ngap_; - gtpu = gtpu_; - rrc_eutra = rrc_eutra_; + phy = phy_; + mac = mac_; + rlc = rlc_; + pdcp = pdcp_; + ngap = ngap_; + bearer_mapper = &bearer_mapper_; + rrc_eutra = rrc_eutra_; cfg = cfg_; diff --git a/srsgnb/src/stack/rrc/rrc_nr_ue.cc b/srsgnb/src/stack/rrc/rrc_nr_ue.cc index 33dc64ac2..2ab0007b4 100644 --- a/srsgnb/src/stack/rrc/rrc_nr_ue.cc +++ b/srsgnb/src/stack/rrc/rrc_nr_ue.cc @@ -14,6 +14,7 @@ #include "srsgnb/hdr/stack/rrc/cell_asn1_config.h" #include "srsgnb/hdr/stack/rrc/rrc_nr_config_utils.h" #include "srsran/asn1/rrc_nr_utils.h" +#include "srsran/common/bearer_manager.h" #include "srsran/common/string_helpers.h" 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.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); } diff --git a/srsgnb/src/stack/rrc/test/rrc_nr_test.cc b/srsgnb/src/stack/rrc/test/rrc_nr_test.cc index 2e28dcc35..5d757517c 100644 --- a/srsgnb/src/stack/rrc/test/rrc_nr_test.cc +++ b/srsgnb/src/stack/rrc/test/rrc_nr_test.cc @@ -13,6 +13,7 @@ #include "rrc_nr_test_helpers.h" #include "srsgnb/hdr/stack/rrc/rrc_nr_config_utils.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/interfaces/gnb_rrc_nr_interfaces.h" #include @@ -45,6 +46,7 @@ void test_sib_generation() rlc_dummy rlc_obj; pdcp_dummy pdcp_obj; rrc_nr rrc_obj(&task_sched); + enb_bearer_manager bearer_mapper; // set cfg 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]); 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); 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; rlc_dummy rlc_obj; pdcp_dummy pdcp_obj; + enb_bearer_manager bearer_mapper; rrc_nr rrc_obj(&task_sched); // set cfg @@ -110,7 +113,7 @@ int test_rrc_setup() rrc_cfg_nr.is_standalone = false; 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"); - 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); for (uint32_t n = 0; n < 2; ++n) { @@ -134,6 +137,7 @@ void test_rrc_sa_connection() rlc_nr_rrc_tester rlc_obj; pdcp_nr_rrc_tester pdcp_obj; ngap_rrc_tester ngap_obj; + enb_bearer_manager bearer_mapper; 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]); 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); 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; 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_security_mode_cmd(task_sched, rrc_obj, pdcp_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(); TESTASSERT(srsenb::test_rrc_setup() == SRSRAN_SUCCESS); srsenb::test_rrc_sa_connection(); - TESTASSERT_EQ( 0, spy->get_warning_counter()); - TESTASSERT_EQ( 0, spy->get_error_counter()); - + TESTASSERT_EQ(0, spy->get_warning_counter()); + TESTASSERT_EQ(0, spy->get_error_counter()); return SRSRAN_SUCCESS; }