diff --git a/srsenb/hdr/stack/enb_stack_lte.h b/srsenb/hdr/stack/enb_stack_lte.h index 94d970b63..53edd3ab8 100644 --- a/srsenb/hdr/stack/enb_stack_lte.h +++ b/srsenb/hdr/stack/enb_stack_lte.h @@ -29,6 +29,7 @@ #include "upper/rlc.h" #include "enb_stack_base.h" +#include "srsran/common/bearer_manager.h" #include "srsran/common/mac_pcap_net.h" #include "srsran/interfaces/enb_interfaces.h" #include "srsran/srslog/srslog.h" @@ -38,6 +39,7 @@ namespace srsenb { class enb_stack_lte final : public enb_stack_base, public stack_interface_phy_lte, public stack_interface_phy_nr, + public stack_interface_rrc, public pdcp_interface_gtpu, public srsran::thread { @@ -137,6 +139,11 @@ public: void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu, int pdcp_sn = -1) override; std::map get_buffered_pdus(uint16_t rnti, uint32_t lcid) override; + // interface for bearer manager + void add_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id, srsran::srsran_rat_t rat, uint32_t lcid) override; + void remove_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id) override; + void reset_eps_bearers(uint16_t rnti) override; + private: static const int STACK_MAIN_THREAD_PRIO = 4; // thread loop @@ -184,6 +191,8 @@ private: srsenb::pdcp pdcp_nr; srsenb::rrc_nr rrc_nr; + srsran::bearer_manager bearers; // helper to manage mapping between EPS and radio bearers + // RAT-specific interfaces phy_interface_stack_lte* phy = nullptr; phy_interface_stack_nr* phy_nr = nullptr; diff --git a/srsenb/hdr/stack/rrc/rrc.h b/srsenb/hdr/stack/rrc/rrc.h index c0aec7310..0e5245a31 100644 --- a/srsenb/hdr/stack/rrc/rrc.h +++ b/srsenb/hdr/stack/rrc/rrc.h @@ -53,7 +53,7 @@ class rrc final : public rrc_interface_pdcp, public rrc_eutra_interface_rrc_nr { public: - explicit rrc(srsran::task_sched_handle task_sched_); + explicit rrc(stack_interface_rrc* stack_, srsran::task_sched_handle task_sched_); ~rrc(); int32_t init(const rrc_cfg_t& cfg_, @@ -166,6 +166,7 @@ public: private: // args srsran::task_sched_handle task_sched; + stack_interface_rrc* stack = nullptr; phy_interface_rrc_lte* phy = nullptr; mac_interface_rrc* mac = nullptr; rlc_interface_rrc* rlc = nullptr; diff --git a/srsenb/src/stack/enb_stack_lte.cc b/srsenb/src/stack/enb_stack_lte.cc index 14e231dcb..92f360b56 100644 --- a/srsenb/src/stack/enb_stack_lte.cc +++ b/srsenb/src/stack/enb_stack_lte.cc @@ -44,7 +44,7 @@ enb_stack_lte::enb_stack_lte(srslog::sink& log_sink) : rlc_nr(rlc_nr_logger), gtpu(&task_sched, gtpu_logger, &rx_sockets), s1ap(&task_sched, s1ap_logger, &rx_sockets), - rrc(&task_sched), + rrc(this, &task_sched), rrc_nr(&task_sched), mac_pcap(), pending_stack_metrics(64) @@ -278,17 +278,40 @@ void enb_stack_lte::run_thread() } } -void enb_stack_lte::write_sdu(uint16_t rnti, - uint32_t lcid /* to be replaced with eps_bearer_id */, - srsran::unique_byte_buffer_t sdu, - int pdcp_sn) +void enb_stack_lte::write_sdu(uint16_t rnti, uint32_t eps_bearer_id, srsran::unique_byte_buffer_t sdu, int pdcp_sn) { - pdcp.write_sdu(rnti, lcid, std::move(sdu), pdcp_sn); + auto bearer = bearers.get_radio_bearer(rnti, eps_bearer_id); + auto task = [this, rnti, eps_bearer_id, bearer, pdcp_sn](srsran::unique_byte_buffer_t& sdu) { + // route SDU to PDCP entity + if (bearer.rat == srsran_rat_t::lte) { + pdcp.write_sdu(rnti, bearer.lcid, std::move(sdu), pdcp_sn); + } else if (bearer.rat == srsran_rat_t::nr) { + pdcp_nr.write_sdu(rnti, bearer.lcid, std::move(sdu), pdcp_sn); + } else { + stack_logger.warning("Can't deliver SDU for EPS bearer %d. Dropping it.", eps_bearer_id); + } + }; } std::map enb_stack_lte::get_buffered_pdus(uint16_t rnti, uint32_t lcid) { + // TODO: use eps_bearer_id as lookup too return pdcp.get_buffered_pdus(rnti, lcid); } +void enb_stack_lte::add_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id, srsran::srsran_rat_t rat, uint32_t lcid) +{ + bearers.add_eps_bearer(rnti, eps_bearer_id, rat, lcid); +} + +void enb_stack_lte::remove_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id) +{ + bearers.remove_eps_bearer(rnti, eps_bearer_id); +} + +void enb_stack_lte::reset_eps_bearers(uint16_t rnti) +{ + bearers.reset(rnti); +} + } // namespace srsenb diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index c74506a07..600fb1988 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -32,8 +32,8 @@ using namespace asn1::rrc; namespace srsenb { -rrc::rrc(srsran::task_sched_handle task_sched_) : - logger(srslog::fetch_basic_logger("RRC")), task_sched(task_sched_), rx_pdu_queue(128) +rrc::rrc(stack_interface_rrc* stack_, srsran::task_sched_handle task_sched_) : + logger(srslog::fetch_basic_logger("RRC")), stack(stack_), task_sched(task_sched_), rx_pdu_queue(128) {} rrc::~rrc() {} diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 81fad3b40..f02b64a30 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -1441,6 +1441,10 @@ void rrc::ue::apply_rlc_rb_updates(const rr_cfg_ded_s& pending_rr_cfg) if (pending_rr_cfg.drb_to_release_list.size() > 0) { for (uint8_t drb_id : pending_rr_cfg.drb_to_release_list) { parent->rlc->del_bearer(rnti, drb_to_lcid((lte_drb)drb_id)); + + // deregister EPS bearer + uint8_t eps_bearer_id = 0; // FIXME: lookup EPS bearer ID for drb_id + parent->stack->remove_eps_bearer(rnti, eps_bearer_id); } } for (const drb_to_add_mod_s& drb : pending_rr_cfg.drb_to_add_mod_list) { @@ -1454,6 +1458,9 @@ void rrc::ue::apply_rlc_rb_updates(const rr_cfg_ded_s& pending_rr_cfg) rlc_cfg.am.max_retx_thresh = parent->cfg.qci_cfg.at(erab.qos_params.qci).enb_dl_max_retx_thres; } parent->rlc->add_bearer(rnti, drb.lc_ch_id, rlc_cfg); + + // register EPS bearer over LTE PDCP + parent->stack->add_eps_bearer(rnti, drb.eps_bearer_id, srsran::srsran_rat_t::lte, drb.lc_ch_id); } } diff --git a/srsenb/test/rrc/erab_setup_test.cc b/srsenb/test/rrc/erab_setup_test.cc index 1c96eac72..b0412f1a9 100644 --- a/srsenb/test/rrc/erab_setup_test.cc +++ b/srsenb/test/rrc/erab_setup_test.cc @@ -33,7 +33,8 @@ int test_erab_setup(srsran::log_sink_spy& spy, bool qci_exists) logger.set_hex_dump_max_size(1024); logger.set_level(srslog::basic_levels::info); - srsenb::rrc rrc{&task_sched}; + test_dummies::enb_stack_dummy stack; + srsenb::rrc rrc{&stack, &task_sched}; mac_dummy mac; rlc_dummy rlc; test_dummies::pdcp_mobility_dummy pdcp; diff --git a/srsenb/test/rrc/rrc_mobility_test.cc b/srsenb/test/rrc/rrc_mobility_test.cc index 15739a1f7..6e596ceb4 100644 --- a/srsenb/test/rrc/rrc_mobility_test.cc +++ b/srsenb/test/rrc/rrc_mobility_test.cc @@ -57,7 +57,7 @@ const char* to_string(test_event event) struct mobility_tester { explicit mobility_tester(const test_event& args_) : - args(args_), logger(srslog::fetch_basic_logger("RRC")), rrc(&task_sched) + args(args_), logger(srslog::fetch_basic_logger("RRC")), rrc(&stack, &task_sched) { logger.set_level(srslog::basic_levels::info); logger.set_hex_dump_max_size(1024); @@ -93,6 +93,7 @@ struct mobility_tester { test_dummies::pdcp_mobility_dummy pdcp; test_dummies::phy_mobility_dummy phy; test_dummies::s1ap_mobility_dummy s1ap; + test_dummies::enb_stack_dummy stack; gtpu_dummy gtpu; void tic() diff --git a/srsenb/test/rrc/test_helpers.h b/srsenb/test/rrc/test_helpers.h index 44d652a96..5f1c2b8fb 100644 --- a/srsenb/test/rrc/test_helpers.h +++ b/srsenb/test/rrc/test_helpers.h @@ -201,6 +201,13 @@ public: phy_rrc_cfg_list_t last_cfg; }; +class enb_stack_dummy : public stack_interface_rrc +{ + void add_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id, srsran::srsran_rat_t rat, uint32_t lcid) {} + void remove_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id) {} + void reset_eps_bearers(uint16_t rnti){}; +}; + } // namespace test_dummies namespace test_helpers {