From dab6e8bdcdddbfb9cf7c49471784b64bcdaf0bcd Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 3 Nov 2021 15:46:28 +0000 Subject: [PATCH] nr,gnb: updates in parsing and phy files to allow the splitting of NR and LTE stacks --- lib/include/srsran/common/network_utils.h | 6 ++ srsenb/hdr/stack/enb_stack_lte.h | 2 - srsenb/hdr/stack/gnb_stack_nr.h | 18 +++-- srsenb/hdr/stack/ngap/ngap.h | 6 +- srsenb/src/enb_cfg_parser.cc | 80 +++++++++++++---------- srsenb/src/phy/phy.cc | 4 +- srsenb/src/stack/enb_stack_lte.cc | 6 +- srsenb/src/stack/gnb_stack_nr.cc | 32 +++++++-- 8 files changed, 99 insertions(+), 55 deletions(-) diff --git a/lib/include/srsran/common/network_utils.h b/lib/include/srsran/common/network_utils.h index 9ec7a19c9..8e3de4ac1 100644 --- a/lib/include/srsran/common/network_utils.h +++ b/lib/include/srsran/common/network_utils.h @@ -187,6 +187,12 @@ make_sctp_sdu_handler(srslog::basic_logger& logger, srsran::task_queue_handle& q socket_manager_itf::recv_callback_t make_sdu_handler(srslog::basic_logger& logger, srsran::task_queue_handle& queue, recvfrom_callback_t rx_callback); +inline socket_manager& get_rx_io_manager() +{ + static socket_manager io; + return io; +} + } // namespace srsran #endif // SRSRAN_RX_SOCKET_HANDLER_H diff --git a/srsenb/hdr/stack/enb_stack_lte.h b/srsenb/hdr/stack/enb_stack_lte.h index 1f3cb8e34..45893891c 100644 --- a/srsenb/hdr/stack/enb_stack_lte.h +++ b/srsenb/hdr/stack/enb_stack_lte.h @@ -149,8 +149,6 @@ private: stack_args_t args = {}; rrc_cfg_t rrc_cfg = {}; - srsran::socket_manager rx_sockets; - srslog::basic_logger& mac_logger; srslog::basic_logger& rlc_logger; srslog::basic_logger& pdcp_logger; diff --git a/srsenb/hdr/stack/gnb_stack_nr.h b/srsenb/hdr/stack/gnb_stack_nr.h index 426046b45..b35e20bbc 100644 --- a/srsenb/hdr/stack/gnb_stack_nr.h +++ b/srsenb/hdr/stack/gnb_stack_nr.h @@ -29,9 +29,13 @@ namespace srsenb { +class ngap; +class gtpu; + struct gnb_stack_args_t { stack_log_args_t log; mac_nr_args_t mac; + ngap_args_t ngap; }; class gnb_stack_nr final : public srsenb::enb_stack_base, @@ -121,6 +125,8 @@ private: srslog::basic_logger& mac_logger; srslog::basic_logger& rlc_logger; srslog::basic_logger& pdcp_logger; + srslog::basic_logger& ngap_logger; + srslog::basic_logger& gtpu_logger; srslog::basic_logger& stack_logger; // task scheduling @@ -133,11 +139,13 @@ private: std::mutex metrics_mutex; std::condition_variable metrics_cvar; - // derived - srsenb::mac_nr mac; - srsenb::rlc rlc; - srsenb::pdcp pdcp; - srsenb::rrc_nr rrc; + // layers + srsenb::mac_nr mac; + srsenb::rlc rlc; + srsenb::pdcp pdcp; + srsenb::rrc_nr rrc; + std::unique_ptr ngap; + std::unique_ptr gtpu; // std::unique_ptr m_sdap; // state diff --git a/srsenb/hdr/stack/ngap/ngap.h b/srsenb/hdr/stack/ngap/ngap.h index 7fb014e28..63bd0e423 100644 --- a/srsenb/hdr/stack/ngap/ngap.h +++ b/srsenb/hdr/stack/ngap/ngap.h @@ -26,16 +26,16 @@ #include "srsran/common/standard_streams.h" #include "srsran/common/task_scheduler.h" #include "srsran/common/threads.h" +#include "srsran/interfaces/enb_gtpu_interfaces.h" #include "srsran/interfaces/gnb_ngap_interfaces.h" #include "srsran/interfaces/gnb_rrc_nr_interfaces.h" -#include "srsran/interfaces/enb_gtpu_interfaces.h" #include "srsran/srslog/srslog.h" #include #include namespace srsenb { -class ngap : public ngap_interface_rrc_nr +class ngap final : public ngap_interface_rrc_nr { public: class ue; @@ -70,7 +70,7 @@ public: // Stack interface bool - handle_amf_rx_msg(srsran::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags); + handle_amf_rx_msg(srsran::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags); void get_metrics(ngap_metrics_t& m); void get_args(ngap_args_t& args_); diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 863fac877..e74763497 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -1176,15 +1176,24 @@ int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, rrc_nr_cfg_t* rrc_nr // update number of NR cells rrc_cfg_->num_nr_cells = rrc_nr_cfg_->cell_list.size(); args_->rf.nof_carriers = rrc_cfg_->cell_list.size() + rrc_nr_cfg_->cell_list.size(); - - // update EUTRA RRC params for ENDC - if (rrc_nr_cfg_->cell_list.size() == 1) { - rrc_cfg_->endc_cfg.abs_frequency_ssb = rrc_nr_cfg_->cell_list.at(0).ssb_absolute_freq_point; - rrc_cfg_->endc_cfg.nr_band = rrc_nr_cfg_->cell_list.at(0).band; - rrc_cfg_->endc_cfg.ssb_period_offset.set_sf10_r15(); - rrc_cfg_->endc_cfg.ssb_duration = asn1::rrc::mtc_ssb_nr_r15_s::ssb_dur_r15_opts::sf1; - rrc_cfg_->endc_cfg.ssb_ssc = asn1::rrc::rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r15_opts::khz15; - rrc_cfg_->endc_cfg.act_from_b1_event = true; // ENDC will only be activated from B1 measurment + ASSERT_VALID_CFG(args_->rf.nof_carriers > 0, "There must be at least one NR or LTE cell"); + if (rrc_nr_cfg_->cell_list.size() > 0) { + // NR cells available. + if (rrc_cfg_->cell_list.size() == 0) { + // SA mode. Update NGAP args + args_->nr_stack.ngap.gnb_id = args_->enb.enb_id; + args_->nr_stack.ngap.cell_id = rrc_nr_cfg_->cell_list[0].phy_cell.cell_id; + args_->nr_stack.ngap.tac = rrc_nr_cfg_->cell_list[0].tac; + } else { + // NSA mode. + // update EUTRA RRC params for ENDC + rrc_cfg_->endc_cfg.abs_frequency_ssb = rrc_nr_cfg_->cell_list.at(0).ssb_absolute_freq_point; + rrc_cfg_->endc_cfg.nr_band = rrc_nr_cfg_->cell_list.at(0).band; + rrc_cfg_->endc_cfg.ssb_period_offset.set_sf10_r15(); + rrc_cfg_->endc_cfg.ssb_duration = asn1::rrc::mtc_ssb_nr_r15_s::ssb_dur_r15_opts::sf1; + rrc_cfg_->endc_cfg.ssb_ssc = asn1::rrc::rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r15_opts::khz15; + rrc_cfg_->endc_cfg.act_from_b1_event = true; // ENDC will only be activated from B1 measurment + } } return SRSRAN_SUCCESS; @@ -1193,41 +1202,42 @@ int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, rrc_nr_cfg_t* rrc_nr int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_, const srsran_cell_t& cell_cfg_) { // Sanity checks - ASSERT_VALID_CFG(not rrc_cfg_->cell_list.empty(), "No cell specified in rr.conf."); ASSERT_VALID_CFG(args_->stack.mac.nof_prealloc_ues <= SRSENB_MAX_UES, "mac.nof_prealloc_ues=%d must be within [0, %d]", args_->stack.mac.nof_prealloc_ues, SRSENB_MAX_UES); // Check for a forced DL EARFCN or frequency (only valid for a single cell config (Xico's favorite feature)) - if (rrc_cfg_->cell_list.size() == 1) { - auto& cfg = rrc_cfg_->cell_list.at(0); - if (args_->enb.dl_earfcn > 0 and args_->enb.dl_earfcn != cfg.dl_earfcn) { - cfg.dl_earfcn = args_->enb.dl_earfcn; - ERROR("Force DL EARFCN for cell PCI=%d to %d", cfg.pci, cfg.dl_earfcn); - } - if (args_->rf.dl_freq > 0) { - cfg.dl_freq_hz = args_->rf.dl_freq; - ERROR("Force DL freq for cell PCI=%d to %f MHz", cfg.pci, cfg.dl_freq_hz / 1e6f); - } - if (args_->rf.ul_freq > 0) { - cfg.ul_freq_hz = args_->rf.ul_freq; - ERROR("Force UL freq for cell PCI=%d to %f MHz", cfg.pci, cfg.ul_freq_hz / 1e6f); - } - } else { - // If more than one cell is defined, single EARFCN or DL freq will be ignored - if (args_->enb.dl_earfcn > 0 || args_->rf.dl_freq > 0) { - INFO("Multiple cells defined in rr.conf. Ignoring single EARFCN and/or frequency config."); + if (rrc_cfg_->cell_list.size() > 1) { + if (rrc_cfg_->cell_list.size() == 1) { + auto& cfg = rrc_cfg_->cell_list.at(0); + if (args_->enb.dl_earfcn > 0 and args_->enb.dl_earfcn != cfg.dl_earfcn) { + cfg.dl_earfcn = args_->enb.dl_earfcn; + ERROR("Force DL EARFCN for cell PCI=%d to %d", cfg.pci, cfg.dl_earfcn); + } + if (args_->rf.dl_freq > 0) { + cfg.dl_freq_hz = args_->rf.dl_freq; + ERROR("Force DL freq for cell PCI=%d to %f MHz", cfg.pci, cfg.dl_freq_hz / 1e6f); + } + if (args_->rf.ul_freq > 0) { + cfg.ul_freq_hz = args_->rf.ul_freq; + ERROR("Force UL freq for cell PCI=%d to %f MHz", cfg.pci, cfg.ul_freq_hz / 1e6f); + } + } else { + // If more than one cell is defined, single EARFCN or DL freq will be ignored + if (args_->enb.dl_earfcn > 0 || args_->rf.dl_freq > 0) { + INFO("Multiple cells defined in rr.conf. Ignoring single EARFCN and/or frequency config."); + } } - } - // set config for RRC's base cell - rrc_cfg_->cell = cell_cfg_; + // set config for RRC's base cell + rrc_cfg_->cell = cell_cfg_; - // Set S1AP related params from cell list - args_->stack.s1ap.enb_id = args_->enb.enb_id; - args_->stack.s1ap.cell_id = rrc_cfg_->cell_list.at(0).cell_id; - args_->stack.s1ap.tac = rrc_cfg_->cell_list.at(0).tac; + // Set S1AP related params from cell list + args_->stack.s1ap.enb_id = args_->enb.enb_id; + args_->stack.s1ap.cell_id = rrc_cfg_->cell_list.at(0).cell_id; + args_->stack.s1ap.tac = rrc_cfg_->cell_list.at(0).tac; + } // Create dedicated cell configuration from RRC configuration for (auto it = rrc_cfg_->cell_list.begin(); it != rrc_cfg_->cell_list.end(); ++it) { diff --git a/srsenb/src/phy/phy.cc b/srsenb/src/phy/phy.cc index d3d5ec8be..aba1cfa30 100644 --- a/srsenb/src/phy/phy.cc +++ b/srsenb/src/phy/phy.cc @@ -85,7 +85,7 @@ void phy::parse_common_config(const phy_cfg_t& cfg) prach_cfg.root_seq_idx = cfg.prach_cnfg.root_seq_idx; prach_cfg.zero_corr_zone = cfg.prach_cnfg.prach_cfg_info.zero_correlation_zone_cfg; prach_cfg.freq_offset = cfg.prach_cnfg.prach_cfg_info.prach_freq_offset; - prach_cfg.num_ra_preambles = cfg.phy_cell_cfg.at(0).num_ra_preambles; + prach_cfg.num_ra_preambles = cfg.phy_cell_cfg.empty() ? 0 : cfg.phy_cell_cfg.at(0).num_ra_preambles; // DMRS workers_common.dmrs_pusch_cfg.cyclic_shift = cfg.pusch_cnfg.ul_ref_sigs_pusch.cyclic_shift; workers_common.dmrs_pusch_cfg.delta_ss = cfg.pusch_cnfg.ul_ref_sigs_pusch.group_assign_pusch; @@ -160,7 +160,7 @@ int phy::init_lte(const phy_args_t& args, phy_log.set_hex_dump_max_size(args.log.phy_hex_limit); radio = radio_; - nof_workers = args.nof_phy_threads; + nof_workers = cfg.phy_cell_cfg.empty() ? 0 : args.nof_phy_threads; workers_common.params = args; diff --git a/srsenb/src/stack/enb_stack_lte.cc b/srsenb/src/stack/enb_stack_lte.cc index 7b698831d..eb4a90c2f 100644 --- a/srsenb/src/stack/enb_stack_lte.cc +++ b/srsenb/src/stack/enb_stack_lte.cc @@ -89,8 +89,8 @@ enb_stack_lte::enb_stack_lte(srslog::sink& log_sink) : pdcp(&task_sched, pdcp_logger), mac(&task_sched, mac_logger), rlc(rlc_logger), - gtpu(&task_sched, gtpu_logger, &rx_sockets), - s1ap(&task_sched, s1ap_logger, &rx_sockets), + gtpu(&task_sched, gtpu_logger, &get_rx_io_manager()), + s1ap(&task_sched, s1ap_logger, &get_rx_io_manager()), rrc(&task_sched, bearers), mac_pcap(), pending_stack_metrics(64) @@ -229,7 +229,7 @@ void enb_stack_lte::stop() void enb_stack_lte::stop_impl() { - rx_sockets.stop(); + get_rx_io_manager().stop(); s1ap.stop(); gtpu.stop(); diff --git a/srsenb/src/stack/gnb_stack_nr.cc b/srsenb/src/stack/gnb_stack_nr.cc index c228abac2..d325d4b5b 100644 --- a/srsenb/src/stack/gnb_stack_nr.cc +++ b/srsenb/src/stack/gnb_stack_nr.cc @@ -11,6 +11,9 @@ */ #include "srsenb/hdr/stack/gnb_stack_nr.h" +#include "srsenb/hdr/stack/ngap/ngap.h" +#include "srsenb/hdr/stack/upper/gtpu.h" +#include "srsran/common/network_utils.h" #include "srsran/common/standard_streams.h" #include "srsran/srsran.h" #include @@ -25,6 +28,8 @@ gnb_stack_nr::gnb_stack_nr(srslog::sink& log_sink) : pdcp_logger(srslog::fetch_basic_logger("PDCP-NR", log_sink, false)), rrc_logger(srslog::fetch_basic_logger("RRC-NR", log_sink, false)), stack_logger(srslog::fetch_basic_logger("STCK-NR", log_sink, false)), + gtpu_logger(srslog::fetch_basic_logger("GTPU", log_sink, false)), + ngap_logger(srslog::fetch_basic_logger("NGAP", log_sink, false)), mac(&task_sched), rrc(&task_sched), pdcp(&task_sched, pdcp_logger), @@ -61,12 +66,21 @@ int gnb_stack_nr::init(const gnb_stack_args_t& args_, pdcp_logger.set_level(srslog::str_to_basic_level(args.log.pdcp_level)); rrc_logger.set_level(srslog::str_to_basic_level(args.log.rrc_level)); stack_logger.set_level(srslog::str_to_basic_level(args.log.stack_level)); + ngap_logger.set_level(srslog::str_to_basic_level(args.log.s1ap_level)); + gtpu_logger.set_level(srslog::str_to_basic_level(args.log.gtpu_level)); mac_logger.set_hex_dump_max_size(args.log.mac_hex_limit); rlc_logger.set_hex_dump_max_size(args.log.rlc_hex_limit); pdcp_logger.set_hex_dump_max_size(args.log.pdcp_hex_limit); rrc_logger.set_hex_dump_max_size(args.log.rrc_hex_limit); stack_logger.set_hex_dump_max_size(args.log.stack_hex_limit); + ngap_logger.set_hex_dump_max_size(args.log.s1ap_hex_limit); + gtpu_logger.set_hex_dump_max_size(args.log.gtpu_hex_limit); + + if (x2_ != nullptr) { + 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())); + } // Init all layers if (mac.init(args.mac, phy, nullptr, &rlc, &rrc) != SRSRAN_SUCCESS) { @@ -77,15 +91,21 @@ 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, nullptr, nullptr, x2_) != SRSRAN_SUCCESS) { + if (rrc.init(rrc_cfg_, phy, &mac, &rlc, &pdcp, ngap.get(), nullptr, x2_) != SRSRAN_SUCCESS) { stack_logger.error("Couldn't initialize RRC"); return SRSRAN_ERROR; } - // TODO: add SDAP, NGAP - // m_gtpu->init(args.s1ap.gtp_bind_addr, args.s1ap.mme_addr, - // args.expert.m1u_multiaddr, args.expert.m1u_if_addr, nullptr, >pu_log, - // args.expert.enable_mbsfn); + if (ngap != nullptr) { + ngap->init(args.ngap, &rrc, nullptr); + gtpu_args_t gtpu_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); + } + + // TODO: add SDAP running = true; @@ -104,6 +124,8 @@ void gnb_stack_nr::stop() void gnb_stack_nr::stop_impl() { + srsran::get_rx_io_manager().stop(); + rrc.stop(); pdcp.stop(); mac.stop();