From 0b51848ddab6391a113ed1004890f4df9b21d2ec Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 19 Oct 2021 11:36:25 +0100 Subject: [PATCH] nr,gnb,rrc: use multiqueue to forward x2 tasks to NR stack --- .../srsran/interfaces/enb_x2_interfaces.h | 6 +- srsenb/hdr/stack/enb_stack_lte.h | 5 +- srsenb/hdr/stack/gnb_stack_nr.h | 18 ++-- srsenb/hdr/stack/rrc/rrc_nr.h | 6 +- srsenb/hdr/x2_adapter.h | 30 +++--- srsenb/src/stack/gnb_stack_nr.cc | 3 +- srsenb/src/stack/rrc/rrc.cc | 2 +- srsenb/src/stack/rrc/rrc_nr.cc | 91 +++++++++---------- 8 files changed, 82 insertions(+), 79 deletions(-) diff --git a/lib/include/srsran/interfaces/enb_x2_interfaces.h b/lib/include/srsran/interfaces/enb_x2_interfaces.h index 367fa7d9a..e8d5b133c 100644 --- a/lib/include/srsran/interfaces/enb_x2_interfaces.h +++ b/lib/include/srsran/interfaces/enb_x2_interfaces.h @@ -36,13 +36,13 @@ public: }; /// Request addition of NR carrier for UE - virtual int sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params) = 0; + virtual void sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params) = 0; /// Provide information whether the requested configuration was applied successfully by the UE - virtual int sgnb_reconfiguration_complete(uint16_t eutra_rnti, asn1::dyn_octstring reconfig_response) = 0; + virtual void sgnb_reconfiguration_complete(uint16_t eutra_rnti, const asn1::dyn_octstring& reconfig_response) = 0; /// Trigger release for specific UE - virtual int sgnb_release_request(uint16_t nr_rnti) = 0; + virtual void sgnb_release_request(uint16_t nr_rnti) = 0; }; /// X2AP inspired interface for response from NR RRC to EUTRA RRC diff --git a/srsenb/hdr/stack/enb_stack_lte.h b/srsenb/hdr/stack/enb_stack_lte.h index ef7544697..0a21eeab3 100644 --- a/srsenb/hdr/stack/enb_stack_lte.h +++ b/srsenb/hdr/stack/enb_stack_lte.h @@ -126,7 +126,10 @@ public: // Note: RRC processes activity asynchronously, so there is no need to use x2_task_queue rrc.set_activity_user(eutra_rnti); } - void sgnb_release_ack(uint16_t eutra_rnti) final { rrc.sgnb_release_ack(eutra_rnti); } + void sgnb_release_ack(uint16_t eutra_rnti) final + { + x2_task_queue.push([this, eutra_rnti]() { rrc.sgnb_release_ack(eutra_rnti); }); + } // gtpu_interface_pdcp void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu); diff --git a/srsenb/hdr/stack/gnb_stack_nr.h b/srsenb/hdr/stack/gnb_stack_nr.h index 3ae39545f..5ce059630 100644 --- a/srsenb/hdr/stack/gnb_stack_nr.h +++ b/srsenb/hdr/stack/gnb_stack_nr.h @@ -81,15 +81,19 @@ public: // X2 interface // control plane, i.e. rrc_nr_interface_rrc - int sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params) final + void sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params) final { - return rrc.sgnb_addition_request(eutra_rnti, params); + x2_task_queue.push([this, eutra_rnti, params]() { rrc.sgnb_addition_request(eutra_rnti, params); }); }; - int sgnb_reconfiguration_complete(uint16_t eutra_rnti, asn1::dyn_octstring reconfig_response) final + void sgnb_reconfiguration_complete(uint16_t eutra_rnti, const asn1::dyn_octstring& reconfig_response) final { - return rrc.sgnb_reconfiguration_complete(eutra_rnti, reconfig_response); + x2_task_queue.push( + [this, eutra_rnti, reconfig_response]() { rrc.sgnb_reconfiguration_complete(eutra_rnti, reconfig_response); }); }; - int sgnb_release_request(uint16_t nr_rnti) final { return rrc.sgnb_release_request(nr_rnti); }; + void sgnb_release_request(uint16_t nr_rnti) final + { + x2_task_queue.push([this, nr_rnti]() { return rrc.sgnb_release_request(nr_rnti); }); + } // X2 data interface void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu, int pdcp_sn = -1) final { @@ -122,8 +126,8 @@ private: // task scheduling static const int STACK_MAIN_THREAD_PRIO = 4; srsran::task_scheduler task_sched; - srsran::task_multiqueue::queue_handle sync_task_queue, ue_task_queue, gtpu_task_queue, mac_task_queue, - metrics_task_queue, gnb_task_queue; + srsran::task_multiqueue::queue_handle sync_task_queue, gtpu_task_queue, metrics_task_queue, gnb_task_queue, + x2_task_queue; // metrics waiting condition std::mutex metrics_mutex; diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 6ab39d282..4935e0cbb 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -86,9 +86,9 @@ public: void notify_pdcp_integrity_error(uint16_t rnti, uint32_t lcid) final; // Interface for EUTRA RRC - int sgnb_addition_request(uint16_t rnti, const sgnb_addition_req_params_t& params); - int sgnb_reconfiguration_complete(uint16_t rnti, asn1::dyn_octstring reconfig_response); - int sgnb_release_request(uint16_t nr_rnti); + void sgnb_addition_request(uint16_t rnti, const sgnb_addition_req_params_t& params); + void sgnb_reconfiguration_complete(uint16_t rnti, const asn1::dyn_octstring& reconfig_response) final; + void sgnb_release_request(uint16_t nr_rnti) final; // Interfaces for NGAP int ue_set_security_cfg_key(uint16_t rnti, const asn1::fixed_bitstring<256, false, true>& key); diff --git a/srsenb/hdr/x2_adapter.h b/srsenb/hdr/x2_adapter.h index 30c619dee..c603e89fa 100644 --- a/srsenb/hdr/x2_adapter.h +++ b/srsenb/hdr/x2_adapter.h @@ -39,22 +39,26 @@ namespace srsenb { class x2_adapter final : public x2_interface { public: - x2_adapter(enb_stack_lte* eutra_stack_, gnb_stack_nr* nr_stack_) : nr_stack(nr_stack_), eutra_stack(eutra_stack_) {} + x2_adapter(enb_stack_lte* eutra_stack_, gnb_stack_nr* nr_stack_) : + nr_stack(nr_stack_), eutra_stack(eutra_stack_), logger(srslog::fetch_basic_logger("X2")) + {} /// rrc_nr_interface_rrc - int sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params) override + void sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params) override { if (nr_stack == nullptr) { - return SRSRAN_ERROR; + logger.error("SgNB Addition Requested for inexistent NR stack"); + return; } - return nr_stack->sgnb_addition_request(eutra_rnti, params); + nr_stack->sgnb_addition_request(eutra_rnti, params); } - int sgnb_reconfiguration_complete(uint16_t eutra_rnti, asn1::dyn_octstring reconfig_response) override + void sgnb_reconfiguration_complete(uint16_t eutra_rnti, const asn1::dyn_octstring& reconfig_response) override { if (nr_stack == nullptr) { - return SRSRAN_ERROR; + logger.error("SgNB Addition Requested for inexistent NR stack"); + return; } - return nr_stack->sgnb_reconfiguration_complete(eutra_rnti, reconfig_response); + nr_stack->sgnb_reconfiguration_complete(eutra_rnti, reconfig_response); } /// rrc_eutra_interface_rrc_nr @@ -96,12 +100,13 @@ public: eutra_stack->set_activity_user(eutra_rnti); } - int sgnb_release_request(uint16_t nr_rnti) override + void sgnb_release_request(uint16_t nr_rnti) override { if (nr_stack == nullptr) { - return SRSRAN_ERROR; + logger.error("SgNB Addition Requested for inexistent NR stack"); + return; } - return nr_stack->sgnb_release_request(nr_rnti); + nr_stack->sgnb_release_request(nr_rnti); } // pdcp_interface_gtpu @@ -130,8 +135,9 @@ public: } private: - enb_stack_lte* eutra_stack = nullptr; - gnb_stack_nr* nr_stack = nullptr; + enb_stack_lte* eutra_stack = nullptr; + gnb_stack_nr* nr_stack = nullptr; + srslog::basic_logger& logger; }; } // namespace srsenb diff --git a/srsenb/src/stack/gnb_stack_nr.cc b/srsenb/src/stack/gnb_stack_nr.cc index da21498fd..35d0f2c3a 100644 --- a/srsenb/src/stack/gnb_stack_nr.cc +++ b/srsenb/src/stack/gnb_stack_nr.cc @@ -30,12 +30,11 @@ gnb_stack_nr::gnb_stack_nr(srslog::sink& log_sink) : pdcp(&task_sched, pdcp_logger), rlc(rlc_logger) { - ue_task_queue = task_sched.make_task_queue(); sync_task_queue = task_sched.make_task_queue(); gtpu_task_queue = task_sched.make_task_queue(); - mac_task_queue = task_sched.make_task_queue(); metrics_task_queue = task_sched.make_task_queue(); gnb_task_queue = task_sched.make_task_queue(); + x2_task_queue = task_sched.make_task_queue(); } gnb_stack_nr::~gnb_stack_nr() diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index 31cbae59e..4213f8d1a 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -605,7 +605,7 @@ void rrc::sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_rnti) void rrc::sgnb_release_ack(uint16_t eutra_rnti) { - logger.info("Received SgNB release acknowledgement for rnti=%d", eutra_rnti); + logger.info("Received SgNB release acknowledgement for rnti=0x%x", eutra_rnti); auto ue_it = users.find(eutra_rnti); if (ue_it == users.end()) { logger.warning("rnti=0x%x does not exist", eutra_rnti); diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index d03968ee1..f89ee463b 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -485,67 +485,58 @@ void rrc_nr::write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) {} Interface for EUTRA RRC *******************************************************************************/ -int rrc_nr::sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params) +void rrc_nr::sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params) { - task_sched.defer_task([this, eutra_rnti, params]() { - // try to allocate new user - sched_nr_ue_cfg_t uecfg{}; - uecfg.carriers.resize(1); - uecfg.carriers[0].active = true; - uecfg.carriers[0].cc = 0; - uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; - srsran::phy_cfg_nr_default_t::reference_cfg_t ref_args{}; - ref_args.duplex = cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_TDD - ? srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_TDD_CUSTOM_6_4 - : srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_FDD; - uecfg.phy_cfg = srsran::phy_cfg_nr_default_t{ref_args}; - uecfg.phy_cfg.csi = {}; // disable CSI until RA is complete - - uint16_t nr_rnti = mac->reserve_rnti(0, uecfg); - if (nr_rnti == SRSRAN_INVALID_RNTI) { - logger.error("Failed to allocate RNTI at MAC"); - rrc_eutra->sgnb_addition_reject(eutra_rnti); - return; - } - - if (add_user(nr_rnti, uecfg) != SRSRAN_SUCCESS) { - logger.error("Failed to allocate RNTI at RRC"); - rrc_eutra->sgnb_addition_reject(eutra_rnti); - return; - } + // try to allocate new user + sched_nr_ue_cfg_t uecfg{}; + uecfg.carriers.resize(1); + uecfg.carriers[0].active = true; + uecfg.carriers[0].cc = 0; + uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; + srsran::phy_cfg_nr_default_t::reference_cfg_t ref_args{}; + ref_args.duplex = cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_TDD + ? srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_TDD_CUSTOM_6_4 + : srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_FDD; + uecfg.phy_cfg = srsran::phy_cfg_nr_default_t{ref_args}; + uecfg.phy_cfg.csi = {}; // disable CSI until RA is complete + + uint16_t nr_rnti = mac->reserve_rnti(0, uecfg); + if (nr_rnti == SRSRAN_INVALID_RNTI) { + logger.error("Failed to allocate RNTI at MAC"); + rrc_eutra->sgnb_addition_reject(eutra_rnti); + return; + } - // new RNTI is now registered at MAC and RRC - auto user_it = users.find(nr_rnti); - if (user_it == users.end()) { - logger.warning("Unrecognised rnti: 0x%x", nr_rnti); - return; - } - user_it->second->handle_sgnb_addition_request(eutra_rnti, params); - }); + if (add_user(nr_rnti, uecfg) != SRSRAN_SUCCESS) { + logger.error("Failed to allocate RNTI at RRC"); + rrc_eutra->sgnb_addition_reject(eutra_rnti); + return; + } - // return straight away - return SRSRAN_SUCCESS; + // new RNTI is now registered at MAC and RRC + auto user_it = users.find(nr_rnti); + if (user_it == users.end()) { + logger.warning("Unrecognised rnti: 0x%x", nr_rnti); + return; + } + user_it->second->handle_sgnb_addition_request(eutra_rnti, params); } -int rrc_nr::sgnb_reconfiguration_complete(uint16_t eutra_rnti, asn1::dyn_octstring reconfig_response) +void rrc_nr::sgnb_reconfiguration_complete(uint16_t eutra_rnti, const asn1::dyn_octstring& reconfig_response) { // user has completeted the reconfiguration and has acked on 4G side, wait until RA on NR logger.info("Received Reconfiguration complete for RNTI=0x%x", eutra_rnti); - return SRSRAN_SUCCESS; } -int rrc_nr::sgnb_release_request(uint16_t nr_rnti) +void rrc_nr::sgnb_release_request(uint16_t nr_rnti) { - task_sched.defer_task([this, nr_rnti]() { - // remove user - auto it = users.find(nr_rnti); - uint16_t eutra_rnti = it != users.end() ? it->second->get_eutra_rnti() : SRSRAN_INVALID_RNTI; - rem_user(nr_rnti); - if (eutra_rnti != SRSRAN_INVALID_RNTI) { - rrc_eutra->sgnb_release_ack(eutra_rnti); - } - }); - return SRSRAN_SUCCESS; + // remove user + auto it = users.find(nr_rnti); + uint16_t eutra_rnti = it != users.end() ? it->second->get_eutra_rnti() : SRSRAN_INVALID_RNTI; + rem_user(nr_rnti); + if (eutra_rnti != SRSRAN_INVALID_RNTI) { + rrc_eutra->sgnb_release_ack(eutra_rnti); + } } /*******************************************************************************