diff --git a/lib/include/srsran/interfaces/enb_x2_interfaces.h b/lib/include/srsran/interfaces/enb_x2_interfaces.h index 88b17f821..5d3b871dc 100644 --- a/lib/include/srsran/interfaces/enb_x2_interfaces.h +++ b/lib/include/srsran/interfaces/enb_x2_interfaces.h @@ -95,7 +95,10 @@ class x2_interface : public rrc_nr_interface_rrc, public rrc_eutra_interface_rrc_nr, public pdcp_interface_gtpu, // allow GTPU to access PDCP in DL direction public gtpu_interface_pdcp // allow PDCP to access GTPU in UL direction -{}; +{ +public: + virtual ~x2_interface() = default; +}; } // namespace srsenb diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index a47828f2d..0edb56925 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -24,7 +24,6 @@ #include #include "phy/phy.h" -#include "x2_adapter.h" #include "srsran/radio/radio.h" @@ -32,6 +31,7 @@ #include "srsenb/hdr/stack/enb_stack_base.h" #include "srsenb/hdr/stack/rrc/rrc_config.h" +#include "srsenb/hdr/stack/gnb_stack_nr.h" #include "srsenb/hdr/stack/mac/sched_interface.h" #include "srsran/common/bcd_helpers.h" #include "srsran/common/buffer_pool.h" @@ -41,6 +41,7 @@ #include "srsran/interfaces/enb_command_interface.h" #include "srsran/interfaces/enb_metrics_interface.h" #include "srsran/interfaces/enb_time_interface.h" +#include "srsran/interfaces/enb_x2_interfaces.h" #include "srsran/interfaces/ue_interfaces.h" #include "srsran/srslog/srslog.h" #include "srsran/system/sys_metrics_processor.h" @@ -161,7 +162,7 @@ private: rrc_nr_cfg_t rrc_nr_cfg = {}; // eNB components - x2_adapter x2; + std::unique_ptr x2; std::unique_ptr eutra_stack = nullptr; std::unique_ptr nr_stack = nullptr; std::unique_ptr radio = nullptr; diff --git a/srsenb/hdr/x2_adapter.h b/srsenb/hdr/x2_adapter.h index 4f795fb41..df5d0f8c8 100644 --- a/srsenb/hdr/x2_adapter.h +++ b/srsenb/hdr/x2_adapter.h @@ -39,22 +39,17 @@ namespace srsenb { class x2_adapter final : public x2_interface { public: - x2_adapter() = default; - - // init functions to set handle to stacks - void set_eutra_stack(enb_stack_lte* eutra_stack_) { eutra_stack = eutra_stack_; } - - void set_nr_stack(gnb_stack_nr* nr_stack_) { nr_stack = nr_stack_; } + x2_adapter(enb_stack_lte* eutra_stack_, gnb_stack_nr* nr_stack_) : nr_stack(nr_stack_), eutra_stack(eutra_stack_) {} /// rrc_nr_interface_rrc - int sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params) + int sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params) override { if (nr_stack == nullptr) { return SRSRAN_ERROR; } return nr_stack->sgnb_addition_request(eutra_rnti, params); } - int sgnb_reconfiguration_complete(uint16_t eutra_rnti, asn1::dyn_octstring reconfig_response) + int sgnb_reconfiguration_complete(uint16_t eutra_rnti, asn1::dyn_octstring reconfig_response) override { if (nr_stack == nullptr) { return SRSRAN_ERROR; @@ -63,21 +58,21 @@ public: } /// rrc_eutra_interface_rrc_nr - void sgnb_addition_ack(uint16_t eutra_rnti, sgnb_addition_ack_params_t params) + void sgnb_addition_ack(uint16_t eutra_rnti, sgnb_addition_ack_params_t params) override { if (eutra_stack == nullptr) { return; } eutra_stack->sgnb_addition_ack(eutra_rnti, params); } - void sgnb_addition_reject(uint16_t eutra_rnti) + void sgnb_addition_reject(uint16_t eutra_rnti) override { if (eutra_stack == nullptr) { return; } eutra_stack->sgnb_addition_reject(eutra_rnti); } - void sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_rnti) + void sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_rnti) override { if (eutra_stack == nullptr) { return; @@ -85,7 +80,7 @@ public: eutra_stack->sgnb_addition_complete(eutra_rnti, nr_rnti); } - void set_activity_user(uint16_t eutra_rnti) + void set_activity_user(uint16_t eutra_rnti) override { if (eutra_stack == nullptr) { return; @@ -94,14 +89,14 @@ public: } // pdcp_interface_gtpu - void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu, int pdcp_sn = -1) + void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu, int pdcp_sn = -1) override { if (nr_stack == nullptr) { return; } nr_stack->write_sdu(rnti, lcid, std::move(sdu), pdcp_sn); } - std::map get_buffered_pdus(uint16_t rnti, uint32_t lcid) + std::map get_buffered_pdus(uint16_t rnti, uint32_t lcid) override { if (nr_stack == nullptr) { return {}; @@ -110,7 +105,7 @@ public: } // gtpu_interface_pdcp - void write_pdu(uint16_t rnti, uint32_t bearer_id, srsran::unique_byte_buffer_t pdu) + void write_pdu(uint16_t rnti, uint32_t bearer_id, srsran::unique_byte_buffer_t pdu) override { if (eutra_stack == nullptr) { return; diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index a096a9adf..e11281191 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -13,6 +13,7 @@ #include "srsenb/hdr/enb.h" #include "srsenb/hdr/stack/enb_stack_lte.h" #include "srsenb/hdr/stack/gnb_stack_nr.h" +#include "srsenb/hdr/x2_adapter.h" #include "srsenb/src/enb_cfg_parser.h" #include "srsran/build_info.h" #include "srsran/common/enb_events.h" @@ -59,7 +60,6 @@ int enb::init(const all_args_t& args_) srsran::console("Error creating EUTRA stack.\n"); return SRSRAN_ERROR; } - x2.set_eutra_stack(tmp_eutra_stack.get()); } std::unique_ptr tmp_nr_stack; @@ -70,7 +70,11 @@ int enb::init(const all_args_t& args_) srsran::console("Error creating NR stack.\n"); return SRSRAN_ERROR; } - x2.set_nr_stack(tmp_nr_stack.get()); + } + + // If NR and EUTRA stacks were initiated, create an X2 adapter between the two. + if (tmp_nr_stack != nullptr and tmp_eutra_stack != nullptr) { + x2.reset(new x2_adapter(tmp_eutra_stack.get(), tmp_nr_stack.get())); } // Radio and PHY are RAT agnostic @@ -88,14 +92,14 @@ int enb::init(const all_args_t& args_) // initialize layers, if they exist if (tmp_eutra_stack) { - if (tmp_eutra_stack->init(args.stack, rrc_cfg, tmp_phy.get(), &x2) != SRSRAN_SUCCESS) { + if (tmp_eutra_stack->init(args.stack, rrc_cfg, tmp_phy.get(), x2.get()) != SRSRAN_SUCCESS) { srsran::console("Error initializing EUTRA stack.\n"); ret = SRSRAN_ERROR; } } if (tmp_nr_stack) { - if (tmp_nr_stack->init(args.nr_stack, rrc_nr_cfg, tmp_phy.get(), &x2) != SRSRAN_SUCCESS) { + if (tmp_nr_stack->init(args.nr_stack, rrc_nr_cfg, tmp_phy.get(), x2.get()) != SRSRAN_SUCCESS) { srsran::console("Error initializing NR stack.\n"); ret = SRSRAN_ERROR; }