From 06fbb58d70ea5e88bb93d0dc17d5dc94a9ddfe80 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 5 Oct 2021 10:31:33 +0200 Subject: [PATCH 001/208] gnb,mac: add dedicated arguments struct for MAC-NR as the PCAP object is now only visible inside MAC-NR we can't share the PCAP file between EUTRA/NR (like we do in the UE). This patch removes the hard-coded filename for the NR PCAP file. --- srsenb/hdr/enb.h | 1 + srsenb/hdr/stack/gnb_stack_nr.h | 15 ++++++++++----- srsenb/src/enb.cc | 2 +- srsenb/src/enb_cfg_parser.cc | 4 ++++ srsenb/src/main.cc | 1 + srsenb/src/stack/gnb_stack_nr.cc | 14 +++++--------- 6 files changed, 22 insertions(+), 15 deletions(-) diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index 0a9fd55a8..3b72417e7 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -112,6 +112,7 @@ struct all_args_t { general_args_t general; phy_args_t phy; stack_args_t stack; + gnb_stack_args_t nr_stack; }; struct rrc_cfg_t; diff --git a/srsenb/hdr/stack/gnb_stack_nr.h b/srsenb/hdr/stack/gnb_stack_nr.h index f9ac6e7f5..cb0af14e9 100644 --- a/srsenb/hdr/stack/gnb_stack_nr.h +++ b/srsenb/hdr/stack/gnb_stack_nr.h @@ -29,6 +29,11 @@ namespace srsenb { +struct gnb_stack_args_t { + stack_log_args_t log; + mac_nr_args_t mac; +}; + class gnb_stack_nr final : public srsenb::enb_stack_base, public stack_interface_phy_nr, public stack_interface_mac, @@ -41,10 +46,10 @@ public: explicit gnb_stack_nr(srslog::sink& log_sink); ~gnb_stack_nr() final; - int init(const srsenb::stack_args_t& args_, - const rrc_nr_cfg_t& rrc_cfg_, - phy_interface_stack_nr* phy_, - x2_interface* x2_); + int init(const gnb_stack_args_t& args_, + const rrc_nr_cfg_t& rrc_cfg_, + phy_interface_stack_nr* phy_, + x2_interface* x2_); // eNB stack base interface void stop() final; @@ -103,7 +108,7 @@ private: void tti_clock_impl(); // args - srsenb::stack_args_t args = {}; + gnb_stack_args_t args = {}; phy_interface_stack_nr* phy = nullptr; srslog::basic_logger& rrc_logger; diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index b55dce228..a096a9adf 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -95,7 +95,7 @@ int enb::init(const all_args_t& args_) } if (tmp_nr_stack) { - if (tmp_nr_stack->init(args.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) != SRSRAN_SUCCESS) { srsran::console("Error initializing NR stack.\n"); ret = SRSRAN_ERROR; } diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 7bc0930dd..176ee1a67 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -1555,6 +1555,10 @@ int set_derived_args_nr(all_args_t* args_, rrc_nr_cfg_t* rrc_cfg_, phy_cfg_t* ph phy_cfg_->phy_cell_cfg_nr.push_back(cfg.phy_cell); } + // MAC-NR PCAP options + args_->nr_stack.mac.pcap.enable = args_->stack.mac_pcap.enable; + args_->nr_stack.log = args_->stack.log; + return SRSRAN_SUCCESS; } diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 6c80cb8a0..82dba6db6 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -131,6 +131,7 @@ void parse_args(all_args_t* args, int argc, char* argv[]) /* PCAP */ ("pcap.enable", bpo::value(&args->stack.mac_pcap.enable)->default_value(false), "Enable MAC packet captures for wireshark") ("pcap.filename", bpo::value(&args->stack.mac_pcap.filename)->default_value("enb_mac.pcap"), "MAC layer capture filename") + ("pcap.nr_filename", bpo::value(&args->nr_stack.mac.pcap.filename)->default_value("enb_mac_nr.pcap"), "NR MAC layer capture filename") ("pcap.s1ap_enable", bpo::value(&args->stack.s1ap_pcap.enable)->default_value(false), "Enable S1AP packet captures for wireshark") ("pcap.s1ap_filename", bpo::value(&args->stack.s1ap_pcap.filename)->default_value("enb_s1ap.pcap"), "S1AP layer capture filename") ("pcap.mac_net_enable", bpo::value(&args->stack.mac_pcap_net.enable)->default_value(false), "Enable MAC network captures") diff --git a/srsenb/src/stack/gnb_stack_nr.cc b/srsenb/src/stack/gnb_stack_nr.cc index 796eca164..ed973f3ba 100644 --- a/srsenb/src/stack/gnb_stack_nr.cc +++ b/srsenb/src/stack/gnb_stack_nr.cc @@ -46,13 +46,12 @@ std::string gnb_stack_nr::get_type() return "nr"; } -int gnb_stack_nr::init(const srsenb::stack_args_t& args_, - const rrc_nr_cfg_t& rrc_cfg_, - phy_interface_stack_nr* phy_, - x2_interface* x2_) +int gnb_stack_nr::init(const gnb_stack_args_t& args_, + const rrc_nr_cfg_t& rrc_cfg_, + phy_interface_stack_nr* phy_, + x2_interface* x2_) { args = args_; - // rrc_cfg = rrc_cfg_; phy = phy_; // setup logging @@ -69,10 +68,7 @@ int gnb_stack_nr::init(const srsenb::stack_args_t& args_, stack_logger.set_hex_dump_max_size(args.log.stack_hex_limit); // Init all layers - mac_nr_args_t mac_args = {}; - mac_args.pcap = args.mac_pcap; - mac_args.pcap.filename = "/tmp/enb_mac_nr.pcap"; - if (mac.init(mac_args, phy, nullptr, &rlc, &rrc) != SRSRAN_SUCCESS) { + if (mac.init(args.mac, phy, nullptr, &rlc, &rrc) != SRSRAN_SUCCESS) { stack_logger.error("Couldn't initialize MAC-NR"); return SRSRAN_ERROR; } From 00a6e71f50bb1a5e9388eb3ce43cdecb489543a9 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 5 Oct 2021 17:38:47 +0200 Subject: [PATCH 002/208] Fix UL/DL frequency compensation --- lib/src/common/phy_cfg_nr_default.cc | 2 ++ lib/src/phy/gnb/gnb_ul.c | 2 +- lib/src/phy/ue/ue_ul_nr.c | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/src/common/phy_cfg_nr_default.cc b/lib/src/common/phy_cfg_nr_default.cc index 3155b69a2..c3847f836 100644 --- a/lib/src/common/phy_cfg_nr_default.cc +++ b/lib/src/common/phy_cfg_nr_default.cc @@ -419,9 +419,11 @@ phy_cfg_nr_default_t::phy_cfg_nr_default_t(const reference_cfg_t& reference_cfg) if (duplex.mode == SRSRAN_DUPLEX_MODE_TDD) { carrier.dl_center_frequency_hz = 3513.6e6; + carrier.ul_center_frequency_hz = 3513.6e6; ssb.scs = srsran_subcarrier_spacing_30kHz; } else { carrier.dl_center_frequency_hz = 881.5e6; + carrier.ul_center_frequency_hz = 836.6e6; ssb.scs = srsran_subcarrier_spacing_15kHz; } carrier.ssb_center_freq_hz = carrier.dl_center_frequency_hz; diff --git a/lib/src/phy/gnb/gnb_ul.c b/lib/src/phy/gnb/gnb_ul.c index 1c5a0bf98..94259e69b 100644 --- a/lib/src/phy/gnb/gnb_ul.c +++ b/lib/src/phy/gnb/gnb_ul.c @@ -135,7 +135,7 @@ int srsran_gnb_ul_set_carrier(srsran_gnb_ul_t* q, const srsran_carrier_nr_t* car ofdm_cfg.rx_window_offset = GNB_UL_NR_FFT_WINDOW_OFFSET; ofdm_cfg.symbol_sz = srsran_min_symbol_sz_rb(carrier->nof_prb); ofdm_cfg.keep_dc = true; - ofdm_cfg.phase_compensation_hz = carrier->dl_center_frequency_hz; + ofdm_cfg.phase_compensation_hz = carrier->ul_center_frequency_hz; if (srsran_ofdm_rx_init_cfg(&q->fft, &ofdm_cfg) < SRSRAN_SUCCESS) { return SRSRAN_ERROR; diff --git a/lib/src/phy/ue/ue_ul_nr.c b/lib/src/phy/ue/ue_ul_nr.c index fdf295cb3..a93a2e5a2 100644 --- a/lib/src/phy/ue/ue_ul_nr.c +++ b/lib/src/phy/ue/ue_ul_nr.c @@ -72,7 +72,7 @@ int srsran_ue_ul_nr_set_carrier(srsran_ue_ul_nr_t* q, const srsran_carrier_nr_t* fft_cfg.nof_prb = carrier->nof_prb; fft_cfg.symbol_sz = srsran_min_symbol_sz_rb(carrier->nof_prb); fft_cfg.keep_dc = true; - fft_cfg.phase_compensation_hz = carrier->dl_center_frequency_hz; + fft_cfg.phase_compensation_hz = carrier->ul_center_frequency_hz; if (srsran_ofdm_tx_init_cfg(&q->ifft, &fft_cfg) < SRSRAN_SUCCESS) { ERROR("Initiating OFDM"); return SRSRAN_ERROR; From a70327997507bf852f9614903ea4af9ccc8a7ef3 Mon Sep 17 00:00:00 2001 From: faluco Date: Tue, 5 Oct 2021 12:02:41 +0200 Subject: [PATCH 003/208] Fix a data race when passing the nr_workers to the txrx worker. There was an unprotected access of the txrx reading this variable while being set from a different thread. Fix it by starting the txrx thread after all variables are ready. --- srsenb/hdr/phy/phy.h | 13 +++++++++---- srsenb/src/phy/phy.cc | 27 +++++++++++++++++++++------ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/srsenb/hdr/phy/phy.h b/srsenb/hdr/phy/phy.h index bfbbbcb9c..ade136bc3 100644 --- a/srsenb/hdr/phy/phy.h +++ b/srsenb/hdr/phy/phy.h @@ -38,13 +38,13 @@ public: int init(const phy_args_t& args, const phy_cfg_t& cfg, srsran::radio_interface_phy* radio_, - stack_interface_phy_lte* stack_, + stack_interface_phy_lte* stack_lte_, + stack_interface_phy_nr& stack_nr_, enb_time_interface* enb_); int init(const phy_args_t& args, const phy_cfg_t& cfg, srsran::radio_interface_phy* radio_, - stack_interface_phy_lte* stack_lte_, - stack_interface_phy_nr& stack_nr_, + stack_interface_phy_lte* stack_, enb_time_interface* enb_); void stop() override; @@ -72,7 +72,6 @@ public: void srsran_phy_logger(phy_logger_level_t log_level, char* str); - int init_nr(const phy_args_t& args, const phy_cfg_t& cfg, stack_interface_phy_nr& stack); int set_common_cfg(const common_cfg_t& common_cfg) override; private: @@ -103,6 +102,12 @@ private: common_cfg_t common_cfg = {}; void parse_common_config(const phy_cfg_t& cfg); + int init_lte(const phy_args_t& args, + const phy_cfg_t& cfg, + srsran::radio_interface_phy* radio_, + stack_interface_phy_lte* stack_, + enb_time_interface* enb_); + int init_nr(const phy_args_t& args, const phy_cfg_t& cfg, stack_interface_phy_nr& stack); }; } // namespace srsenb diff --git a/srsenb/src/phy/phy.cc b/srsenb/src/phy/phy.cc index 18b174416..47d59199c 100644 --- a/srsenb/src/phy/phy.cc +++ b/srsenb/src/phy/phy.cc @@ -100,7 +100,7 @@ int phy::init(const phy_args_t& args, stack_interface_phy_nr& stack_nr_, enb_time_interface* enb_) { - if (init(args, cfg, radio_, stack_lte_, enb_) != SRSRAN_SUCCESS) { + if (init_lte(args, cfg, radio_, stack_lte_, enb_) != SRSRAN_SUCCESS) { phy_log.error("Couldn't initialize LTE PHY"); return SRSRAN_ERROR; } @@ -110,6 +110,9 @@ int phy::init(const phy_args_t& args, return SRSRAN_ERROR; } + tx_rx.init(enb_, radio, <e_workers, &workers_common, &prach, SF_RECV_THREAD_PRIO); + initialized = true; + return SRSRAN_SUCCESS; } @@ -118,6 +121,23 @@ int phy::init(const phy_args_t& args, srsran::radio_interface_phy* radio_, stack_interface_phy_lte* stack_lte_, enb_time_interface* enb_) +{ + if (init_lte(args, cfg, radio_, stack_lte_, enb_) != SRSRAN_SUCCESS) { + phy_log.error("Couldn't initialize LTE PHY"); + return SRSRAN_ERROR; + } + + tx_rx.init(enb_, radio, <e_workers, &workers_common, &prach, SF_RECV_THREAD_PRIO); + initialized = true; + + return SRSRAN_SUCCESS; +} + +int phy::init_lte(const phy_args_t& args, + const phy_cfg_t& cfg, + srsran::radio_interface_phy* radio_, + stack_interface_phy_lte* stack_lte_, + enb_time_interface* enb_) { if (cfg.phy_cell_cfg.size() > SRSRAN_MAX_CARRIERS) { phy_log.error( @@ -166,11 +186,6 @@ int phy::init(const phy_args_t& args, } prach.set_max_prach_offset_us(args.max_prach_offset_us); - // Warning this must be initialized after all workers have been added to the pool - tx_rx.init(enb_, radio, <e_workers, &workers_common, &prach, SF_RECV_THREAD_PRIO); - - initialized = true; - return SRSRAN_SUCCESS; } From e0238f4092ef0ddc7b80ab978b367c76fe7385dc Mon Sep 17 00:00:00 2001 From: faluco Date: Tue, 5 Oct 2021 13:29:53 +0200 Subject: [PATCH 004/208] NR: Fix a race condition where we could remove a UE from the mac while still being accessed by the NR PHY worker. --- srsenb/src/stack/mac/nr/mac_nr.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 3a737730f..2e027338d 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -321,6 +321,8 @@ int mac_nr::get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched slot_point pusch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx}; ret = sched.get_ul_sched(pusch_slot, 0, ul_sched); + + srsran::rwlock_read_guard rw_lock(rwlock); for (auto& pusch : ul_sched.pusch) { if (ue_db.contains(pusch.sch.grant.rnti)) { ue_db[pusch.sch.grant.rnti]->metrics_ul_mcs(pusch.sch.grant.tb->mcs); @@ -345,6 +347,7 @@ bool mac_nr::handle_uci_data(const uint16_t rnti, const srsran_uci_cfg_nr_t& cfg const srsran_harq_ack_bit_t* ack_bit = &cfg_.ack.bits[i]; bool is_ok = (value.ack[i] == 1) and value.valid; sched.dl_ack_info(rnti, 0, ack_bit->pid, 0, is_ok); + srsran::rwlock_read_guard rw_lock(rwlock); if (ue_db.contains(rnti)) { ue_db[rnti]->metrics_tx(is_ok, 0 /*TODO get size of packet from scheduler somehow*/); } @@ -386,6 +389,7 @@ int mac_nr::pusch_info(const srsran_slot_cfg_t& slot_cfg, mac_interface_phy_nr:: }; stack_task_queue.try_push(std::bind(process_pdu_task, std::move(pusch_info.pdu))); } + srsran::rwlock_read_guard rw_lock(rwlock); if (ue_db.contains(rnti)) { ue_db[rnti]->metrics_rx(pusch_info.pusch_data.tb[0].crc, nof_bytes); ue_db[rnti]->metrics_dl_cqi(15); // TODO extract correct CQI measurments From dadd2f75244a26138ea29e573282a9cb902b79b8 Mon Sep 17 00:00:00 2001 From: faluco Date: Tue, 5 Oct 2021 14:12:45 +0200 Subject: [PATCH 005/208] Removed querying the NR scheduler user array from the metrics thread that caused a data race. --- srsenb/src/stack/mac/nr/mac_nr.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 2e027338d..f018cb9fe 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -81,9 +81,6 @@ void mac_nr::get_metrics(srsenb::mac_metrics_t& metrics) srsran::rwlock_read_guard lock(rwlock); metrics.ues.reserve(ue_db.size()); for (auto& u : ue_db) { - if (not sched.ue_exists(u.first)) { - continue; - } metrics.ues.emplace_back(); u.second->metrics_read(&metrics.ues.back()); } From 9058ee9a5bd758962ab7a67b641d87f1fd7d3453 Mon Sep 17 00:00:00 2001 From: faluco Date: Tue, 5 Oct 2021 14:19:49 +0200 Subject: [PATCH 006/208] Move gNB metrics processing to the stack thread avoiding concurrency issues in MAC and RRC. --- srsenb/hdr/stack/gnb_stack_nr.h | 5 ++++- srsenb/src/stack/gnb_stack_nr.cc | 33 ++++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/srsenb/hdr/stack/gnb_stack_nr.h b/srsenb/hdr/stack/gnb_stack_nr.h index cb0af14e9..0a48d1201 100644 --- a/srsenb/hdr/stack/gnb_stack_nr.h +++ b/srsenb/hdr/stack/gnb_stack_nr.h @@ -120,7 +120,10 @@ 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; + srsran::task_multiqueue::queue_handle sync_task_queue, ue_task_queue, gtpu_task_queue, mac_task_queue, + metrics_task_queue; + + srsran::dyn_blocking_queue pending_stack_metrics; // derived srsenb::mac_nr mac; diff --git a/srsenb/src/stack/gnb_stack_nr.cc b/srsenb/src/stack/gnb_stack_nr.cc index ed973f3ba..62016bd32 100644 --- a/srsenb/src/stack/gnb_stack_nr.cc +++ b/srsenb/src/stack/gnb_stack_nr.cc @@ -25,15 +25,17 @@ 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)), + pending_stack_metrics(64), mac(&task_sched), rrc(&task_sched), 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(); + 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_stack_nr::~gnb_stack_nr() @@ -129,9 +131,7 @@ void gnb_stack_nr::tti_clock_impl() task_sched.tic(); } -void gnb_stack_nr::process_pdus() -{ -} +void gnb_stack_nr::process_pdus() {} /******************************************************** * @@ -141,9 +141,22 @@ void gnb_stack_nr::process_pdus() bool gnb_stack_nr::get_metrics(srsenb::stack_metrics_t* metrics) { - mac.get_metrics(metrics->mac); - rrc.get_metrics(metrics->rrc); - return true; + // use stack thread to query metrics + auto ret = metrics_task_queue.try_push([this]() { + srsenb::stack_metrics_t metrics{}; + mac.get_metrics(metrics.mac); + rrc.get_metrics(metrics.rrc); + if (not pending_stack_metrics.try_push(std::move(metrics))) { + stack_logger.error("Unable to push metrics to queue"); + } + }); + + if (ret.has_value()) { + // wait for result + *metrics = pending_stack_metrics.pop_blocking(); + return true; + } + return false; } // Temporary GW interface From e5d48d1d2163811830c88ddc1dc431b490a14de1 Mon Sep 17 00:00:00 2001 From: faluco Date: Tue, 5 Oct 2021 14:40:30 +0200 Subject: [PATCH 007/208] Fix data race in MAC NR metrics. --- srsenb/src/stack/mac/nr/ue_nr.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc index e9f3c701a..623d5059d 100644 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ b/srsenb/src/stack/mac/nr/ue_nr.cc @@ -42,7 +42,10 @@ ue_nr::~ue_nr() {} void ue_nr::reset() { - ue_metrics = {}; + { + std::lock_guard lock(metrics_mutex); + ue_metrics = {}; + } nof_failures = 0; } @@ -222,12 +225,14 @@ void ue_nr::metrics_tx(bool crc, uint32_t tbs) void ue_nr::metrics_dl_mcs(uint32_t mcs) { + std::lock_guard lock(metrics_mutex); ue_metrics.dl_mcs = SRSRAN_VEC_CMA((float)mcs, ue_metrics.dl_mcs, ue_metrics.dl_mcs_samples); ue_metrics.dl_mcs_samples++; } void ue_nr::metrics_ul_mcs(uint32_t mcs) { + std::lock_guard lock(metrics_mutex); ue_metrics.ul_mcs = SRSRAN_VEC_CMA((float)mcs, ue_metrics.ul_mcs, ue_metrics.ul_mcs_samples); ue_metrics.ul_mcs_samples++; } From b7f40b2baf2407fe77fa3f850726e87cefeb2ec6 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 5 Oct 2021 11:04:48 +0100 Subject: [PATCH 008/208] rrc,nr: reenable CSI reporting in gNB --- lib/include/srsran/asn1/rrc_nr_utils.h | 1 + lib/src/asn1/rrc_nr_utils.cc | 23 +++++++++ srsenb/hdr/stack/mac/nr/sched_nr_interface.h | 1 + srsenb/hdr/stack/rrc/nr/rrc_config_nr.h | 1 + srsenb/src/stack/rrc/nr/cell_asn1_config.cc | 51 ++++++++++++++++++++ srsenb/src/stack/rrc/rrc_nr.cc | 8 +-- 6 files changed, 81 insertions(+), 4 deletions(-) diff --git a/lib/include/srsran/asn1/rrc_nr_utils.h b/lib/include/srsran/asn1/rrc_nr_utils.h index 6b9fc11f4..4a12bf14f 100644 --- a/lib/include/srsran/asn1/rrc_nr_utils.h +++ b/lib/include/srsran/asn1/rrc_nr_utils.h @@ -115,6 +115,7 @@ bool make_phy_ssb_cfg(const srsran_carrier_nr_t& carrier, const asn1::rrc_nr::serving_cell_cfg_common_s& serv_cell_cfg, phy_cfg_nr_t::ssb_cfg_t* ssb); bool make_pdsch_cfg_from_serv_cell(asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_sch_hl_cfg_nr_t* sch_hl); +bool make_csi_cfg_from_serv_cell(asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_csi_hl_cfg_t* csi_hl); /*************************** * MAC Config diff --git a/lib/src/asn1/rrc_nr_utils.cc b/lib/src/asn1/rrc_nr_utils.cc index 9e1014013..5aac53bbf 100644 --- a/lib/src/asn1/rrc_nr_utils.cc +++ b/lib/src/asn1/rrc_nr_utils.cc @@ -1481,6 +1481,8 @@ bool make_pdsch_cfg_from_serv_cell(asn1::rrc_nr::serving_cell_cfg_s& serv_cell, serv_cell.csi_meas_cfg.type().value == setup_release_c< ::asn1::rrc_nr::csi_meas_cfg_s>::types_opts::options::setup) { auto& setup = serv_cell.csi_meas_cfg.setup(); + + // Configure NZP-CSI if (setup.nzp_csi_rs_res_set_to_add_mod_list_present) { for (auto& nzp_set : setup.nzp_csi_rs_res_set_to_add_mod_list) { auto& uecfg_set = sch_hl->nzp_csi_rs_sets[nzp_set.nzp_csi_res_set_id]; @@ -1515,6 +1517,27 @@ bool make_pdsch_cfg_from_serv_cell(asn1::rrc_nr::serving_cell_cfg_s& serv_cell, return true; } +bool make_csi_cfg_from_serv_cell(asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_csi_hl_cfg_t* csi_hl) +{ + if (serv_cell.csi_meas_cfg_present and + serv_cell.csi_meas_cfg.type().value == + setup_release_c< ::asn1::rrc_nr::csi_meas_cfg_s>::types_opts::options::setup) { + auto& setup = serv_cell.csi_meas_cfg.setup(); + + // Configure CSI-Report + if (setup.csi_report_cfg_to_add_mod_list_present) { + for (uint32_t i = 0; i < setup.csi_report_cfg_to_add_mod_list.size(); ++i) { + const auto& csi_rep = setup.csi_report_cfg_to_add_mod_list[i]; + if (not make_phy_csi_report(csi_rep, &csi_hl->reports[i])) { + return false; + } + } + } + } + + return true; +} + } // namespace srsran namespace srsenb { diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index c0813aa5d..3f1788742 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -56,6 +56,7 @@ public: srsran_pdcch_cfg_nr_t pdcch = {}; srsran_sch_hl_cfg_nr_t pdsch = {}; srsran_sch_hl_cfg_nr_t pusch = {}; + srsran_csi_hl_cfg_t csi = {}; uint32_t rar_window_size = 10; // See TS 38.331, ra-ResponseWindow: {1, 2, 4, 8, 10, 20, 40, 80} uint32_t numerology_idx = 0; }; diff --git a/srsenb/hdr/stack/rrc/nr/rrc_config_nr.h b/srsenb/hdr/stack/rrc/nr/rrc_config_nr.h index 34712a5d8..6cac04fe8 100644 --- a/srsenb/hdr/stack/rrc/nr/rrc_config_nr.h +++ b/srsenb/hdr/stack/rrc/nr/rrc_config_nr.h @@ -38,6 +38,7 @@ struct rrc_nr_cfg_t { rrc_cfg_cqi_t cqi_cfg; rrc_cell_list_nr_t cell_list; + std::string log_name = "RRC-NR"; std::string log_level; uint32_t log_hex_limit; }; diff --git a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc index 28283351f..a6cb787e1 100644 --- a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc +++ b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc @@ -16,8 +16,59 @@ using namespace asn1::rrc_nr; namespace srsenb { +srslog::basic_logger& get_logger(const rrc_nr_cfg_t& cfg) +{ + static srslog::basic_logger& log_obj = srslog::fetch_basic_logger(cfg.log_name); + return log_obj; +} + +int fill_csi_report_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas_cfg) +{ + csi_meas_cfg.csi_report_cfg_to_add_mod_list_present = true; + csi_meas_cfg.csi_report_cfg_to_add_mod_list.resize(1); + + auto& csi_report = csi_meas_cfg.csi_report_cfg_to_add_mod_list[0]; + csi_report.report_cfg_id = 0; + csi_report.res_for_ch_meas = 0; + csi_report.csi_im_res_for_interference_present = true; + csi_report.csi_im_res_for_interference = 1; + csi_report.report_cfg_type.set_periodic(); + csi_report.report_cfg_type.periodic().report_slot_cfg.set_slots80(); + csi_report.report_cfg_type.periodic().pucch_csi_res_list.resize(1); + csi_report.report_cfg_type.periodic().pucch_csi_res_list[0].ul_bw_part_id = 0; + csi_report.report_cfg_type.periodic().pucch_csi_res_list[0].pucch_res = 1; // was 17 in orig PCAP + csi_report.report_quant.set_cri_ri_pmi_cqi(); + // Report freq config (optional) + csi_report.report_freq_cfg_present = true; + csi_report.report_freq_cfg.cqi_format_ind_present = true; + csi_report.report_freq_cfg.cqi_format_ind = + asn1::rrc_nr::csi_report_cfg_s::report_freq_cfg_s_::cqi_format_ind_opts::wideband_cqi; + csi_report.time_restrict_for_ch_meass = asn1::rrc_nr::csi_report_cfg_s::time_restrict_for_ch_meass_opts::not_cfgured; + csi_report.time_restrict_for_interference_meass = + asn1::rrc_nr::csi_report_cfg_s::time_restrict_for_interference_meass_opts::not_cfgured; + csi_report.group_based_beam_report.set_disabled(); + // Skip CQI table (optional) + csi_report.cqi_table_present = true; + csi_report.cqi_table = asn1::rrc_nr::csi_report_cfg_s::cqi_table_opts::table2; + csi_report.subband_size = asn1::rrc_nr::csi_report_cfg_s::subband_size_opts::value1; + + if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { + csi_report.report_cfg_type.periodic().report_slot_cfg.slots80() = 5; + } else { + csi_report.report_cfg_type.periodic().report_slot_cfg.slots80() = 7; + } + + return SRSRAN_SUCCESS; +} + int fill_csi_meas_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas_cfg) { + // Fill CSI Report + if (fill_csi_report_from_enb_cfg(cfg, csi_meas_cfg) != SRSRAN_SUCCESS) { + get_logger(cfg).error("Failed to configure eNB CSI Report"); + return SRSRAN_ERROR; + } + // Fill NZP-CSI Resources csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list_present = true; if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 835531fd1..cb74c399e 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -247,7 +247,9 @@ void rrc_nr::config_mac() int ret = fill_serv_cell_from_enb_cfg(cfg, serv_cell); srsran_assert(ret == SRSRAN_SUCCESS, "Failed to configure cell"); bool ret2 = srsran::make_pdsch_cfg_from_serv_cell(serv_cell, &cell.bwps[0].pdsch); - srsran_assert(ret2, "Failed to configure cell"); + srsran_assert(ret2, "Invalid NR cell configuration."); + ret2 = srsran::make_csi_cfg_from_serv_cell(serv_cell, &cell.bwps[0].csi); + srsran_assert(ret2, "Invalid NR cell configuration."); // FIXME: entire SI configuration, etc needs to be ported to NR sched_interface::cell_cfg_t cell_cfg; @@ -929,9 +931,6 @@ int rrc_nr::ue::pack_sp_cell_cfg_ded_csi_meas_cfg(asn1::rrc_nr::cell_group_cfg_s cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg_present = true; cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.set_setup(); - // NOTE: Disable CQI configuration until srsENB NR PHY supports it - // pack_sp_cell_cfg_ded_csi_meas_cfg_csi_report_cfg(cell_group_cfg_pack); - // nzp-CSI-RS Resource and ResourceSet fill_serv_cell_from_enb_cfg(parent->cfg, cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded); @@ -1437,6 +1436,7 @@ void rrc_nr::ue::crnti_ce_received() } srsran::make_pdsch_cfg_from_serv_cell(cell_group_cfg.sp_cell_cfg.sp_cell_cfg_ded, &uecfg.phy_cfg.pdsch); + srsran::make_csi_cfg_from_serv_cell(cell_group_cfg.sp_cell_cfg.sp_cell_cfg_ded, &uecfg.phy_cfg.csi); parent->mac->ue_cfg(rnti, uecfg); } From 51f1c0d6ef06628345b227da074072e7244d65bf Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 5 Oct 2021 16:59:53 +0100 Subject: [PATCH 009/208] rrc,nr: refactor csi report asn1 configuration --- srsenb/hdr/stack/rrc/rrc_nr.h | 3 - srsenb/src/stack/rrc/nr/cell_asn1_config.cc | 40 ++++-- srsenb/src/stack/rrc/rrc_nr.cc | 145 ++++++-------------- 3 files changed, 75 insertions(+), 113 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 5c80945bb..a680068be 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -146,9 +146,6 @@ public: int pack_sp_cell_cfg_ded_pdcch_serving_cell_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_sp_cell_cfg_ded_csi_meas_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_sp_cell_cfg_ded_csi_meas_cfg_csi_report_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_recfg_with_sync(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); int pack_recfg_with_sync_sp_cell_cfg_common(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); int pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_common(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); diff --git a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc index a6cb787e1..e54cfee2f 100644 --- a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc +++ b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc @@ -22,6 +22,7 @@ srslog::basic_logger& get_logger(const rrc_nr_cfg_t& cfg) return log_obj; } +/// Fill list of CSI-ReportConfig with gNB config int fill_csi_report_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas_cfg) { csi_meas_cfg.csi_report_cfg_to_add_mod_list_present = true; @@ -61,15 +62,9 @@ int fill_csi_report_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_me return SRSRAN_SUCCESS; } -int fill_csi_meas_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas_cfg) +/// Fill lists of NZP-CSI-RS-Resource and NZP-CSI-RS-ResourceSet with gNB config +void fill_nzp_csi_rs_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas_cfg) { - // Fill CSI Report - if (fill_csi_report_from_enb_cfg(cfg, csi_meas_cfg) != SRSRAN_SUCCESS) { - get_logger(cfg).error("Failed to configure eNB CSI Report"); - return SRSRAN_ERROR; - } - - // Fill NZP-CSI Resources csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list_present = true; if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list.resize(5); @@ -215,13 +210,40 @@ int fill_csi_meas_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas nzp_csi_res_set[0].nzp_csi_rs_res[0] = 0; // Skip TRS info } +} + +/// Fill CSI-MeasConfig with gNB config +int fill_csi_meas_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas_cfg) +{ + // // Fill CSI Report + // if (fill_csi_report_from_enb_cfg(cfg, csi_meas_cfg) != SRSRAN_SUCCESS) { + // get_logger(cfg).error("Failed to configure eNB CSI Report"); + // return SRSRAN_ERROR; + // } + + // Fill NZP-CSI Resources + fill_nzp_csi_rs_from_enb_cfg(cfg, csi_meas_cfg); + + // CSI IM config + // TODO: add csi im config + + // CSI resource config + // TODO: add csi resource config + return SRSRAN_SUCCESS; } +/// Fill ServingCellConfig with gNB config int fill_serv_cell_from_enb_cfg(const rrc_nr_cfg_t& cfg, serving_cell_cfg_s& serv_cell) { serv_cell.csi_meas_cfg_present = true; - return fill_csi_meas_from_enb_cfg(cfg, serv_cell.csi_meas_cfg.set_setup()); + if (fill_csi_meas_from_enb_cfg(cfg, serv_cell.csi_meas_cfg.set_setup()) != SRSRAN_SUCCESS) { + return SRSRAN_ERROR; + } + + // TODO: remaining fields + + return SRSRAN_SUCCESS; } } // namespace srsenb diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index cb74c399e..2e022f8d3 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -555,31 +555,31 @@ int rrc_nr::ue::pack_secondary_cell_group_rlc_cfg(asn1::rrc_nr::cell_group_cfg_s // RLC for DRB1 (with fixed LCID) cell_group_cfg_pack.rlc_bearer_to_add_mod_list_present = true; cell_group_cfg_pack.rlc_bearer_to_add_mod_list.resize(1); - auto& rlc = cell_group_cfg_pack.rlc_bearer_to_add_mod_list[0]; - rlc.lc_ch_id = drb1_lcid; - rlc.served_radio_bearer_present = true; - rlc.served_radio_bearer.set_drb_id(); - rlc.served_radio_bearer.drb_id() = 1; - rlc.rlc_cfg_present = true; - rlc.rlc_cfg.set_um_bi_dir(); - rlc.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len_present = true; - rlc.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len = sn_field_len_um_opts::size12; - rlc.rlc_cfg.um_bi_dir().dl_um_rlc.sn_field_len_present = true; - rlc.rlc_cfg.um_bi_dir().dl_um_rlc.sn_field_len = sn_field_len_um_opts::size12; - rlc.rlc_cfg.um_bi_dir().dl_um_rlc.t_reassembly = t_reassembly_opts::ms50; + auto& rlc_bearer = cell_group_cfg_pack.rlc_bearer_to_add_mod_list[0]; + rlc_bearer.lc_ch_id = drb1_lcid; + rlc_bearer.served_radio_bearer_present = true; + rlc_bearer.served_radio_bearer.set_drb_id(); + rlc_bearer.served_radio_bearer.drb_id() = 1; + rlc_bearer.rlc_cfg_present = true; + rlc_bearer.rlc_cfg.set_um_bi_dir(); + rlc_bearer.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len_present = true; + rlc_bearer.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len = sn_field_len_um_opts::size12; + rlc_bearer.rlc_cfg.um_bi_dir().dl_um_rlc.sn_field_len_present = true; + rlc_bearer.rlc_cfg.um_bi_dir().dl_um_rlc.sn_field_len = sn_field_len_um_opts::size12; + rlc_bearer.rlc_cfg.um_bi_dir().dl_um_rlc.t_reassembly = t_reassembly_opts::ms50; // MAC logical channel config - rlc.mac_lc_ch_cfg_present = true; - rlc.mac_lc_ch_cfg.ul_specific_params_present = true; - rlc.mac_lc_ch_cfg.ul_specific_params.prio = 11; - rlc.mac_lc_ch_cfg.ul_specific_params.prioritised_bit_rate = + rlc_bearer.mac_lc_ch_cfg_present = true; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params_present = true; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.prio = 11; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.prioritised_bit_rate = asn1::rrc_nr::lc_ch_cfg_s::ul_specific_params_s_::prioritised_bit_rate_opts::kbps0; - rlc.mac_lc_ch_cfg.ul_specific_params.bucket_size_dur = + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.bucket_size_dur = asn1::rrc_nr::lc_ch_cfg_s::ul_specific_params_s_::bucket_size_dur_opts::ms100; - rlc.mac_lc_ch_cfg.ul_specific_params.lc_ch_group_present = true; - rlc.mac_lc_ch_cfg.ul_specific_params.lc_ch_group = 6; - rlc.mac_lc_ch_cfg.ul_specific_params.sched_request_id_present = true; - rlc.mac_lc_ch_cfg.ul_specific_params.sched_request_id = 0; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.lc_ch_group_present = true; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.lc_ch_group = 6; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.sched_request_id_present = true; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.sched_request_id = 0; return SRSRAN_SUCCESS; } @@ -886,63 +886,6 @@ int rrc_nr::ue::pack_sp_cell_cfg_ded_pdcch_serving_cell_cfg(asn1::rrc_nr::cell_g return SRSRAN_SUCCESS; } -int rrc_nr::ue::pack_sp_cell_cfg_ded_csi_meas_cfg_csi_report_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - // CSI report config - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list_present = true; - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list.resize(1); - auto& csi_report = - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list[0]; - csi_report.report_cfg_id = 0; - csi_report.res_for_ch_meas = 0; - csi_report.csi_im_res_for_interference_present = true; - csi_report.csi_im_res_for_interference = 1; - csi_report.report_cfg_type.set_periodic(); - csi_report.report_cfg_type.periodic().report_slot_cfg.set_slots80(); - csi_report.report_cfg_type.periodic().pucch_csi_res_list.resize(1); - csi_report.report_cfg_type.periodic().pucch_csi_res_list[0].ul_bw_part_id = 0; - csi_report.report_cfg_type.periodic().pucch_csi_res_list[0].pucch_res = 1; // was 17 in orig PCAP - csi_report.report_quant.set_cri_ri_pmi_cqi(); - // Report freq config (optional) - csi_report.report_freq_cfg_present = true; - csi_report.report_freq_cfg.cqi_format_ind_present = true; - csi_report.report_freq_cfg.cqi_format_ind = - asn1::rrc_nr::csi_report_cfg_s::report_freq_cfg_s_::cqi_format_ind_opts::wideband_cqi; - csi_report.time_restrict_for_ch_meass = asn1::rrc_nr::csi_report_cfg_s::time_restrict_for_ch_meass_opts::not_cfgured; - csi_report.time_restrict_for_interference_meass = - asn1::rrc_nr::csi_report_cfg_s::time_restrict_for_interference_meass_opts::not_cfgured; - csi_report.group_based_beam_report.set_disabled(); - // Skip CQI table (optional) - csi_report.cqi_table_present = true; - csi_report.cqi_table = asn1::rrc_nr::csi_report_cfg_s::cqi_table_opts::table2; - csi_report.subband_size = asn1::rrc_nr::csi_report_cfg_s::subband_size_opts::value1; - - if (parent->cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { - csi_report.report_cfg_type.periodic().report_slot_cfg.slots80() = 5; - } else { - csi_report.report_cfg_type.periodic().report_slot_cfg.slots80() = 7; - } - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_sp_cell_cfg_ded_csi_meas_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg_present = true; - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.set_setup(); - - // nzp-CSI-RS Resource and ResourceSet - fill_serv_cell_from_enb_cfg(parent->cfg, cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded); - - // CSI IM config - // TODO: add csi im config - - // CSI resource config - // TODO: add csi resource config - - return SRSRAN_SUCCESS; -} - int rrc_nr::ue::pack_sp_cell_cfg_ded(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) { // SP Cell Dedicated config @@ -962,7 +905,7 @@ int rrc_nr::ue::pack_sp_cell_cfg_ded(asn1::rrc_nr::cell_group_cfg_s& cell_group_ pack_sp_cell_cfg_ded_pdcch_serving_cell_cfg(cell_group_cfg_pack); // CSI meas config - pack_sp_cell_cfg_ded_csi_meas_cfg(cell_group_cfg_pack); + fill_serv_cell_from_enb_cfg(parent->cfg, cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded); return SRSRAN_SUCCESS; } @@ -1457,18 +1400,18 @@ int rrc_nr::ue::add_drb() cell_group_cfg_pack.rlc_bearer_to_add_mod_list_present = true; cell_group_cfg_pack.rlc_bearer_to_add_mod_list.resize(1); - auto& rlc = cell_group_cfg_pack.rlc_bearer_to_add_mod_list[0]; - rlc.lc_ch_id = drb1_lcid; - rlc.served_radio_bearer_present = true; - rlc.served_radio_bearer.set_drb_id(); - rlc.served_radio_bearer.drb_id() = 1; - rlc.rlc_cfg_present = true; - rlc.rlc_cfg.set_um_bi_dir(); - rlc.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len_present = true; - rlc.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len = sn_field_len_um_opts::size12; - rlc.rlc_cfg.um_bi_dir().dl_um_rlc.sn_field_len_present = true; - rlc.rlc_cfg.um_bi_dir().dl_um_rlc.sn_field_len = sn_field_len_um_opts::size12; - rlc.rlc_cfg.um_bi_dir().dl_um_rlc.t_reassembly = t_reassembly_opts::ms50; + auto& rlc_bearer = cell_group_cfg_pack.rlc_bearer_to_add_mod_list[0]; + rlc_bearer.lc_ch_id = drb1_lcid; + rlc_bearer.served_radio_bearer_present = true; + rlc_bearer.served_radio_bearer.set_drb_id(); + rlc_bearer.served_radio_bearer.drb_id() = 1; + rlc_bearer.rlc_cfg_present = true; + rlc_bearer.rlc_cfg.set_um_bi_dir(); + rlc_bearer.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len_present = true; + rlc_bearer.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len = sn_field_len_um_opts::size12; + rlc_bearer.rlc_cfg.um_bi_dir().dl_um_rlc.sn_field_len_present = true; + rlc_bearer.rlc_cfg.um_bi_dir().dl_um_rlc.sn_field_len = sn_field_len_um_opts::size12; + rlc_bearer.rlc_cfg.um_bi_dir().dl_um_rlc.t_reassembly = t_reassembly_opts::ms50; // add RLC bearer srsran::rlc_config_t rlc_cfg; @@ -1479,17 +1422,17 @@ int rrc_nr::ue::add_drb() parent->rlc->add_bearer(rnti, drb1_lcid, rlc_cfg); // MAC logical channel config - rlc.mac_lc_ch_cfg_present = true; - rlc.mac_lc_ch_cfg.ul_specific_params_present = true; - rlc.mac_lc_ch_cfg.ul_specific_params.prio = 11; - rlc.mac_lc_ch_cfg.ul_specific_params.prioritised_bit_rate = + rlc_bearer.mac_lc_ch_cfg_present = true; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params_present = true; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.prio = 11; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.prioritised_bit_rate = asn1::rrc_nr::lc_ch_cfg_s::ul_specific_params_s_::prioritised_bit_rate_opts::kbps0; - rlc.mac_lc_ch_cfg.ul_specific_params.bucket_size_dur = + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.bucket_size_dur = asn1::rrc_nr::lc_ch_cfg_s::ul_specific_params_s_::bucket_size_dur_opts::ms100; - rlc.mac_lc_ch_cfg.ul_specific_params.lc_ch_group_present = true; - rlc.mac_lc_ch_cfg.ul_specific_params.lc_ch_group = 3; - rlc.mac_lc_ch_cfg.ul_specific_params.sched_request_id_present = true; - rlc.mac_lc_ch_cfg.ul_specific_params.sched_request_id = 0; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.lc_ch_group_present = true; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.lc_ch_group = 3; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.sched_request_id_present = true; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.sched_request_id = 0; // TODO: add LC config to MAC // PDCP config goes into radio_bearer_cfg @@ -1517,7 +1460,7 @@ int rrc_nr::ue::add_drb() // Add DRB1 to PDCP srsran::pdcp_config_t pdcp_cnfg = srsran::make_drb_pdcp_config_t(drb_item.drb_id, false, drb_item.pdcp_cfg); - parent->pdcp->add_bearer(rnti, rlc.lc_ch_id, pdcp_cnfg); + parent->pdcp->add_bearer(rnti, rlc_bearer.lc_ch_id, pdcp_cnfg); // Note: DRB1 is only activated in the MAC when the C-RNTI CE is received From efa2026a70dcbdaad8094e0fcfc38eb993959d9d Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 5 Oct 2021 17:33:35 +0100 Subject: [PATCH 010/208] sched,nr: erase uneeded parameters from sched_nr_interface bwp_cft_t --- srsenb/hdr/stack/mac/nr/sched_nr_interface.h | 1 - srsenb/src/stack/rrc/rrc_nr.cc | 2 -- 2 files changed, 3 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index 3f1788742..c0813aa5d 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -56,7 +56,6 @@ public: srsran_pdcch_cfg_nr_t pdcch = {}; srsran_sch_hl_cfg_nr_t pdsch = {}; srsran_sch_hl_cfg_nr_t pusch = {}; - srsran_csi_hl_cfg_t csi = {}; uint32_t rar_window_size = 10; // See TS 38.331, ra-ResponseWindow: {1, 2, 4, 8, 10, 20, 40, 80} uint32_t numerology_idx = 0; }; diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 2e022f8d3..a6ea27f79 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -248,8 +248,6 @@ void rrc_nr::config_mac() srsran_assert(ret == SRSRAN_SUCCESS, "Failed to configure cell"); bool ret2 = srsran::make_pdsch_cfg_from_serv_cell(serv_cell, &cell.bwps[0].pdsch); srsran_assert(ret2, "Invalid NR cell configuration."); - ret2 = srsran::make_csi_cfg_from_serv_cell(serv_cell, &cell.bwps[0].csi); - srsran_assert(ret2, "Invalid NR cell configuration."); // FIXME: entire SI configuration, etc needs to be ported to NR sched_interface::cell_cfg_t cell_cfg; From 7b0b76d58ec6db470f1c638672c2812ababc65f7 Mon Sep 17 00:00:00 2001 From: faluco Date: Fri, 1 Oct 2021 13:35:34 +0200 Subject: [PATCH 011/208] Whitelist two lock order inversion TSAN issues that acquire a readlock. --- lib/include/srsran/common/tsan_options.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/include/srsran/common/tsan_options.h b/lib/include/srsran/common/tsan_options.h index 397b40277..bac732021 100644 --- a/lib/include/srsran/common/tsan_options.h +++ b/lib/include/srsran/common/tsan_options.h @@ -41,8 +41,10 @@ const char* __tsan_default_suppressions() // External uninstrumented libraries "called_from_lib:libzmq.so\n" "called_from_lib:libpgm-5.2.so\n" - // Lock order inversion issue in this function, ignore it as it uses rw locks in read mode - "deadlock:srsenb::mac::rlc_buffer_state\n"; + // Lock order inversion issues in these functions, ignore it as it uses rw locks in read mode + "deadlock:srsenb::mac::rlc_buffer_state\n" + "deadlock:srsenb::mac::snr_info\n" + "deadlock:srsenb::mac::ack_info\n"; } #ifdef __cplusplus From 83b9777220a1b954273b61a2acc03e7f09761798 Mon Sep 17 00:00:00 2001 From: faluco Date: Fri, 1 Oct 2021 13:46:13 +0200 Subject: [PATCH 012/208] Fix data races in cell_list array members inside enb::phy_common. --- srsenb/hdr/phy/phy_common.h | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/srsenb/hdr/phy/phy_common.h b/srsenb/hdr/phy/phy_common.h index 1bc0b7a66..07e81fde3 100644 --- a/srsenb/hdr/phy/phy_common.h +++ b/srsenb/hdr/phy/phy_common.h @@ -62,9 +62,9 @@ public: // Common objects phy_args_t params = {}; - uint32_t get_nof_carriers_lte() { return static_cast(cell_list_lte.size()); }; - uint32_t get_nof_carriers_nr() { return static_cast(cell_list_nr.size()); }; - uint32_t get_nof_carriers() { return static_cast(cell_list_lte.size() + cell_list_nr.size()); }; + uint32_t get_nof_carriers_lte() { return static_cast(cell_list_lte.size()); } + uint32_t get_nof_carriers_nr() { return static_cast(cell_list_nr.size()); } + uint32_t get_nof_carriers() { return static_cast(cell_list_lte.size() + cell_list_nr.size()); } uint32_t get_nof_prb(uint32_t cc_idx) { uint32_t ret = 0; @@ -84,7 +84,7 @@ public: } } return ret; - }; + } uint32_t get_nof_ports(uint32_t cc_idx) { uint32_t ret = 0; @@ -97,7 +97,7 @@ public: } return ret; - }; + } uint32_t get_nof_rf_channels() { uint32_t count = 0; @@ -126,7 +126,7 @@ public: } return ret; - }; + } double get_dl_freq_hz(uint32_t cc_idx) { double ret = 0.0; @@ -141,7 +141,7 @@ public: } return ret; - }; + } uint32_t get_rf_port(uint32_t cc_idx) { uint32_t ret = 0; @@ -156,7 +156,7 @@ public: } return ret; - }; + } srsran_cell_t get_cell(uint32_t cc_idx) { srsran_cell_t c = {}; @@ -164,7 +164,7 @@ public: c = cell_list_lte[cc_idx].cell; } return c; - }; + } void set_cell_gain(uint32_t cell_id, float gain_db) { @@ -174,6 +174,7 @@ public: // Check if the lte cell was found; if (it_lte != cell_list_lte.end()) { + std::lock_guard lock(cell_gain_mutex); it_lte->gain_db = gain_db; return; } @@ -184,6 +185,7 @@ public: // Check if the nr cell was found; if (it_nr != cell_list_nr.end()) { + std::lock_guard lock(cell_gain_mutex); it_nr->gain_db = gain_db; return; } @@ -193,6 +195,7 @@ public: float get_cell_gain(uint32_t cc_idx) { + std::lock_guard lock(cell_gain_mutex); if (cc_idx < cell_list_lte.size()) { return cell_list_lte.at(cc_idx).gain_db; } @@ -235,6 +238,7 @@ private: phy_cell_cfg_list_t cell_list_lte; phy_cell_cfg_list_nr_t cell_list_nr; + std::mutex cell_gain_mutex; bool have_mtch_stop = false; pthread_mutex_t mtch_mutex = {}; From a2c433b2287b581ae2754433030008f7f276a54a Mon Sep 17 00:00:00 2001 From: faluco Date: Fri, 1 Oct 2021 13:49:14 +0200 Subject: [PATCH 013/208] Fix data race in the enb::mac::ue metrics object. --- srsenb/src/stack/mac/ue.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/srsenb/src/stack/mac/ue.cc b/srsenb/src/stack/mac/ue.cc index 791b08725..719760bf9 100644 --- a/srsenb/src/stack/mac/ue.cc +++ b/srsenb/src/stack/mac/ue.cc @@ -108,7 +108,7 @@ uint8_t* cc_used_buffers_map::request_pdu(tti_point tti, uint32_t len) void cc_used_buffers_map::clear_old_pdus(tti_point current_tti) { std::unique_lock lock(mutex); - static const uint32_t old_tti_threshold = SRSRAN_FDD_NOF_HARQ + 4; + static const uint32_t old_tti_threshold = SRSRAN_FDD_NOF_HARQ + 4; tti_point max_tti{current_tti - old_tti_threshold}; for (auto& pdu_pair : pdu_map) { @@ -205,7 +205,10 @@ ue::~ue() {} void ue::reset() { - ue_metrics = {}; + { + std::lock_guard lock(metrics_mutex); + ue_metrics = {}; + } nof_failures = 0; for (auto& cc : cc_buffers) { From 388b1e5d9246d4cc24b8537fabf2017269b29ffc Mon Sep 17 00:00:00 2001 From: faluco Date: Mon, 4 Oct 2021 12:01:19 +0200 Subject: [PATCH 014/208] Fix data race in radio::is_start_of_burst. --- lib/include/srsran/radio/radio.h | 40 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/include/srsran/radio/radio.h b/lib/include/srsran/radio/radio.h index 0c206f1d6..ca1e7bcab 100644 --- a/lib/include/srsran/radio/radio.h +++ b/lib/include/srsran/radio/radio.h @@ -91,9 +91,9 @@ private: std::vector rx_offset_n = {}; rf_metrics_t rf_metrics = {}; std::mutex metrics_mutex; - srslog::basic_logger& logger = srslog::fetch_basic_logger("RF", false); - phy_interface_radio* phy = nullptr; - cf_t* zeros = nullptr; + srslog::basic_logger& logger = srslog::fetch_basic_logger("RF", false); + phy_interface_radio* phy = nullptr; + cf_t* zeros = nullptr; std::array dummy_buffers; std::mutex tx_mutex; std::mutex rx_mutex; @@ -103,23 +103,23 @@ private: std::array decimators = {}; bool decimator_busy = false; ///< Indicates the decimator is changing the rate - rf_timestamp_t end_of_burst_time = {}; - bool is_start_of_burst = false; - uint32_t tx_adv_nsamples = 0; - double tx_adv_sec = 0.0; // Transmission time advance to compensate for antenna->timestamp delay - bool tx_adv_auto = false; - bool tx_adv_negative = false; - bool is_initialized = false; - bool radio_is_streaming = false; - bool continuous_tx = false; - double freq_offset = 0.0; - double cur_tx_srate = 0.0; - double cur_rx_srate = 0.0; - double fix_srate_hz = 0.0; - uint32_t nof_antennas = 0; - uint32_t nof_channels = 0; - uint32_t nof_channels_x_dev = 0; - uint32_t nof_carriers = 0; + rf_timestamp_t end_of_burst_time = {}; + std::atomic is_start_of_burst{false}; + uint32_t tx_adv_nsamples = 0; + double tx_adv_sec = 0.0; // Transmission time advance to compensate for antenna->timestamp delay + bool tx_adv_auto = false; + bool tx_adv_negative = false; + bool is_initialized = false; + bool radio_is_streaming = false; + bool continuous_tx = false; + double freq_offset = 0.0; + double cur_tx_srate = 0.0; + double cur_rx_srate = 0.0; + double fix_srate_hz = 0.0; + uint32_t nof_antennas = 0; + uint32_t nof_channels = 0; + uint32_t nof_channels_x_dev = 0; + uint32_t nof_carriers = 0; std::vector cur_tx_freqs = {}; std::vector cur_rx_freqs = {}; From bdc84f24f397a21e15c833fbb4564f68502667e5 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 5 Oct 2021 18:26:25 +0200 Subject: [PATCH 015/208] gnb,cfg: fix SSB config deriviation * this fixes the SSB config for TDD * UE decodes the SSB correctly --- srsenb/src/enb_cfg_parser.cc | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 176ee1a67..91e4313f7 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -1532,15 +1532,27 @@ int set_derived_args_nr(all_args_t* args_, rrc_nr_cfg_t* rrc_cfg_, phy_cfg_t* ph cfg.dl_absolute_freq_point_a = band_helper.get_abs_freq_point_a_arfcn(cfg.phy_cell.carrier.nof_prb, cfg.dl_arfcn); cfg.ul_absolute_freq_point_a = band_helper.get_abs_freq_point_a_arfcn(cfg.phy_cell.carrier.nof_prb, cfg.ul_arfcn); - // Calculate SSB absolute frequency (in ARFCN notation) - if (band_helper.get_ssb_pattern(cfg.band, srsran_subcarrier_spacing_15kHz) != SRSRAN_SSB_PATTERN_INVALID) { - cfg.ssb_absolute_freq_point = - band_helper.get_abs_freq_ssb_arfcn(cfg.band, srsran_subcarrier_spacing_15kHz, cfg.dl_absolute_freq_point_a); + // Calculate SSB params depending on band/duplex + cfg.ssb_cfg.duplex_mode = band_helper.get_duplex_mode(cfg.band); + cfg.ssb_cfg.pattern = band_helper.get_ssb_pattern(cfg.band, srsran_subcarrier_spacing_15kHz); + if (cfg.ssb_cfg.pattern == SRSRAN_SSB_PATTERN_A) { + // 15kHz SSB SCS + cfg.ssb_cfg.scs = srsran_subcarrier_spacing_15kHz; } else { - cfg.ssb_absolute_freq_point = - band_helper.get_abs_freq_ssb_arfcn(cfg.band, srsran_subcarrier_spacing_30kHz, cfg.dl_absolute_freq_point_a); + // try to optain SSB pattern for same band with 30kHz SCS + cfg.ssb_cfg.pattern = band_helper.get_ssb_pattern(cfg.band, srsran_subcarrier_spacing_30kHz); + if (cfg.ssb_cfg.pattern == SRSRAN_SSB_PATTERN_B || cfg.ssb_cfg.pattern == SRSRAN_SSB_PATTERN_C) { + // SSB SCS is 30 kHz + cfg.ssb_cfg.scs = srsran_subcarrier_spacing_30kHz; + } else { + ERROR("Can't derive SSB pattern for band %d", cfg.band); + return SRSRAN_ERROR; + } } + // fill remaining SSB fields + cfg.ssb_absolute_freq_point = + band_helper.get_abs_freq_ssb_arfcn(cfg.band, cfg.ssb_cfg.scs, cfg.dl_absolute_freq_point_a); if (cfg.ssb_absolute_freq_point == 0) { ERROR("Can't derive SSB freq point for dl_arfcn %d and band %d", cfg.dl_arfcn, cfg.band); return SRSRAN_ERROR; @@ -1549,8 +1561,16 @@ int set_derived_args_nr(all_args_t* args_, rrc_nr_cfg_t* rrc_cfg_, phy_cfg_t* ph // Convert to frequency for PHY cfg.phy_cell.carrier.ssb_center_freq_hz = band_helper.nr_arfcn_to_freq(cfg.ssb_absolute_freq_point); - // TODO: set SSB config - cfg.ssb_cfg = {}; + cfg.ssb_cfg.center_freq_hz = cfg.phy_cell.carrier.dl_center_frequency_hz; + cfg.ssb_cfg.ssb_freq_hz = cfg.phy_cell.carrier.ssb_center_freq_hz; + cfg.ssb_cfg.periodicity_ms = 10; // TODO: make a param + cfg.ssb_cfg.beta_pss = 0.0; + cfg.ssb_cfg.beta_sss = 0.0; + cfg.ssb_cfg.beta_pbch = 0.0; + cfg.ssb_cfg.beta_pbch_dmrs = 0.0; + // set by PHY layer in worker_pool::set_common_cfg + cfg.ssb_cfg.srate_hz = 0.0; + cfg.ssb_cfg.scaling = 0.0; phy_cfg_->phy_cell_cfg_nr.push_back(cfg.phy_cell); } From bae003d3a98327839b891d6285295fa4d3c2c8a1 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 5 Oct 2021 16:31:29 +0200 Subject: [PATCH 016/208] enb,rrc: set SSB periodicity to 10ms --- srsenb/src/stack/rrc/rrc_nr.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index a6ea27f79..d2e6b1ff0 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -1170,8 +1170,9 @@ int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_ssb_cfg(asn1::rrc_nr::ce } cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_periodicity_serving_cell_present = true; + // TODO: get periodicitiy from cell config cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_periodicity_serving_cell = - serving_cell_cfg_common_s::ssb_periodicity_serving_cell_opts::ms20; + serving_cell_cfg_common_s::ssb_periodicity_serving_cell_opts::ms10; return SRSRAN_SUCCESS; } From 991013ca2c79becbfa214f448f4365452617c60c Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Wed, 6 Oct 2021 10:39:37 +0200 Subject: [PATCH 017/208] Fix order of dl/ul common cfg. dl must be first. --- srsue/src/stack/rrc/rrc_nr.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/srsue/src/stack/rrc/rrc_nr.cc b/srsue/src/stack/rrc/rrc_nr.cc index 493333d73..af12af83d 100644 --- a/srsue/src/stack/rrc/rrc_nr.cc +++ b/srsue/src/stack/rrc/rrc_nr.cc @@ -1154,21 +1154,21 @@ bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg) logger.warning("Option PCI not present"); return false; } - if (recfg_with_sync.sp_cell_cfg_common.ul_cfg_common_present) { - if (apply_ul_common_cfg(recfg_with_sync.sp_cell_cfg_common.ul_cfg_common) == false) { + // Read essential DL carrier settings + if (recfg_with_sync.sp_cell_cfg_common.dl_cfg_common_present) { + if (apply_dl_common_cfg(recfg_with_sync.sp_cell_cfg_common.dl_cfg_common) == false) { return false; } } else { - logger.warning("Secondary primary cell ul cfg common not present"); + logger.warning("Secondary primary cell dl cfg common not present"); return false; } - // Read essential DL carrier settings - if (recfg_with_sync.sp_cell_cfg_common.dl_cfg_common_present) { - if (apply_dl_common_cfg(recfg_with_sync.sp_cell_cfg_common.dl_cfg_common) == false) { + if (recfg_with_sync.sp_cell_cfg_common.ul_cfg_common_present) { + if (apply_ul_common_cfg(recfg_with_sync.sp_cell_cfg_common.ul_cfg_common) == false) { return false; } } else { - logger.warning("DL cfg common not present"); + logger.warning("Secondary primary cell ul cfg common not present"); return false; } // Build SSB config From 6c4548c243d66eb1627473760fd625db61b87d27 Mon Sep 17 00:00:00 2001 From: faluco Date: Tue, 5 Oct 2021 18:15:23 +0200 Subject: [PATCH 018/208] Fix several data races in LTE and NR harq classes. --- srsue/hdr/stack/mac/ul_harq.h | 1 + srsue/hdr/stack/mac_nr/dl_harq_nr.h | 7 ++++--- srsue/hdr/stack/mac_nr/ul_harq_nr.h | 9 +++++---- srsue/src/stack/mac/ul_harq.cc | 12 ++++++++---- srsue/src/stack/mac_nr/dl_harq_nr.cc | 7 +++++-- srsue/src/stack/mac_nr/ul_harq_nr.cc | 9 ++++++++- 6 files changed, 31 insertions(+), 14 deletions(-) diff --git a/srsue/hdr/stack/mac/ul_harq.h b/srsue/hdr/stack/mac/ul_harq.h index b0726d161..ae51ec542 100644 --- a/srsue/hdr/stack/mac/ul_harq.h +++ b/srsue/hdr/stack/mac/ul_harq.h @@ -99,6 +99,7 @@ private: ue_rnti* rntis = nullptr; srsran::ul_harq_cfg_t harq_cfg = {}; + std::mutex config_mutex; std::atomic average_retx{0}; std::atomic nof_pkts{0}; diff --git a/srsue/hdr/stack/mac_nr/dl_harq_nr.h b/srsue/hdr/stack/mac_nr/dl_harq_nr.h index 9754cb6a6..c0475fba7 100644 --- a/srsue/hdr/stack/mac_nr/dl_harq_nr.h +++ b/srsue/hdr/stack/mac_nr/dl_harq_nr.h @@ -42,7 +42,7 @@ public: ~dl_harq_entity_nr(); int32_t set_config(const srsran::dl_harq_cfg_nr_t& cfg_); - void reset(); + void reset(); /// PHY->MAC interface for DL processes void new_grant_dl(const mac_nr_grant_dl_t& grant, mac_interface_phy_nr::tb_action_dl_t* action); @@ -69,7 +69,7 @@ private: uint8_t get_ndi(); void - new_grant_dl(const mac_nr_grant_dl_t& grant, const bool& ndi_toggled, mac_interface_phy_nr::tb_action_dl_t* action); + new_grant_dl(const mac_nr_grant_dl_t& grant, const bool& ndi_toggled, mac_interface_phy_nr::tb_action_dl_t* action); void tb_decoded(const mac_nr_grant_dl_t& grant, mac_interface_phy_nr::tb_action_dl_result_t result); private: @@ -96,7 +96,8 @@ private: srslog::basic_logger& logger; uint16_t last_temporal_crnti = SRSRAN_INVALID_RNTI; dl_harq_metrics_t metrics = {}; - uint8_t cc_idx = 0; + std::mutex metrics_mutex; + uint8_t cc_idx = 0; pthread_rwlock_t rwlock; }; diff --git a/srsue/hdr/stack/mac_nr/ul_harq_nr.h b/srsue/hdr/stack/mac_nr/ul_harq_nr.h index 918e51eae..4bb5ac21a 100644 --- a/srsue/hdr/stack/mac_nr/ul_harq_nr.h +++ b/srsue/hdr/stack/mac_nr/ul_harq_nr.h @@ -54,9 +54,9 @@ private: ul_harq_process_nr(); ~ul_harq_process_nr(); - bool init(uint32_t pid_, ul_harq_entity_nr* entity_); - void reset(); - void reset_ndi(); + bool init(uint32_t pid_, ul_harq_entity_nr* entity_); + void reset(); + void reset_ndi(); uint8_t get_ndi(); bool has_grant(); @@ -75,7 +75,7 @@ private: mac_interface_phy_nr::tb_action_ul_t* action); private: - mac_interface_phy_nr::mac_nr_grant_ul_t current_grant = {}; + mac_interface_phy_nr::mac_nr_grant_ul_t current_grant = {}; bool grant_configured = false; uint32_t pid = 0; @@ -103,6 +103,7 @@ private: srsran::ul_harq_cfg_t harq_cfg = {}; ul_harq_metrics_t metrics = {}; + std::mutex metrics_mutex; }; typedef std::unique_ptr ul_harq_entity_nr_ptr; diff --git a/srsue/src/stack/mac/ul_harq.cc b/srsue/src/stack/mac/ul_harq.cc index de968b511..6951b2a34 100644 --- a/srsue/src/stack/mac/ul_harq.cc +++ b/srsue/src/stack/mac/ul_harq.cc @@ -57,6 +57,7 @@ void ul_harq_entity::reset_ndi() void ul_harq_entity::set_config(srsran::ul_harq_cfg_t& harq_cfg_) { + std::lock_guard lock(config_mutex); harq_cfg = harq_cfg_; } @@ -174,10 +175,13 @@ void ul_harq_entity::ul_harq_process::new_grant_ul(mac_interface_phy_lte::mac_gr // Get maximum retransmissions uint32_t max_retx; - if (grant.rnti == harq_entity->rntis->get_temp_rnti()) { - max_retx = harq_entity->harq_cfg.max_harq_msg3_tx; - } else { - max_retx = harq_entity->harq_cfg.max_harq_tx; + { + std::lock_guard lock(harq_entity->config_mutex); + if (grant.rnti == harq_entity->rntis->get_temp_rnti()) { + max_retx = harq_entity->harq_cfg.max_harq_msg3_tx; + } else { + max_retx = harq_entity->harq_cfg.max_harq_tx; + } } // Check maximum retransmissions, do not consider last retx ACK diff --git a/srsue/src/stack/mac_nr/dl_harq_nr.cc b/srsue/src/stack/mac_nr/dl_harq_nr.cc index eca971ad6..b1bfd9d70 100644 --- a/srsue/src/stack/mac_nr/dl_harq_nr.cc +++ b/srsue/src/stack/mac_nr/dl_harq_nr.cc @@ -126,8 +126,9 @@ void dl_harq_entity_nr::reset() dl_harq_entity_nr::dl_harq_metrics_t dl_harq_entity_nr::get_metrics() { - dl_harq_metrics_t tmp = metrics; - metrics = {}; + std::lock_guard lock(metrics_mutex); + dl_harq_metrics_t tmp = metrics; + metrics = {}; return tmp; } @@ -230,9 +231,11 @@ void dl_harq_entity_nr::dl_harq_process_nr::tb_decoded(const mac_nr_grant_dl_t& } } + std::lock_guard lock(harq_entity->metrics_mutex); harq_entity->metrics.rx_ok++; harq_entity->metrics.rx_brate += grant.tbs * 8; } else { + std::lock_guard lock(harq_entity->metrics_mutex); harq_entity->metrics.rx_ko++; } diff --git a/srsue/src/stack/mac_nr/ul_harq_nr.cc b/srsue/src/stack/mac_nr/ul_harq_nr.cc index 3e101c82d..1f4ae8c49 100644 --- a/srsue/src/stack/mac_nr/ul_harq_nr.cc +++ b/srsue/src/stack/mac_nr/ul_harq_nr.cc @@ -106,6 +106,7 @@ int ul_harq_entity_nr::get_current_tbs(uint32_t pid) ul_harq_entity_nr::ul_harq_metrics_t ul_harq_entity_nr::get_metrics() { + std::lock_guard lock(metrics_mutex); ul_harq_entity_nr::ul_harq_metrics_t tmp = metrics; metrics = {}; return tmp; @@ -240,6 +241,7 @@ void ul_harq_entity_nr::ul_harq_process_nr::generate_new_tx(const mac_interface_ generate_tx(action); + std::lock_guard lock(harq_entity->metrics_mutex); harq_entity->metrics.tx_ok++; } @@ -255,6 +257,7 @@ void ul_harq_entity_nr::ul_harq_process_nr::generate_retx(const mac_interface_ph generate_tx(action); // increment Tx error count + std::lock_guard lock(harq_entity->metrics_mutex); harq_entity->metrics.tx_ko++; } @@ -262,7 +265,11 @@ void ul_harq_entity_nr::ul_harq_process_nr::generate_retx(const mac_interface_ph void ul_harq_entity_nr::ul_harq_process_nr::generate_tx(mac_interface_phy_nr::tb_action_ul_t* action) { nof_retx++; - harq_entity->metrics.tx_brate += current_grant.tbs * 8; + + { + std::lock_guard lock(harq_entity->metrics_mutex); + harq_entity->metrics.tx_brate += current_grant.tbs * 8; + } action->tb.rv = current_grant.rv; action->tb.enabled = true; From a9c65bd36922b568633eea8fb689cb88a79fc129 Mon Sep 17 00:00:00 2001 From: faluco Date: Wed, 6 Oct 2021 12:25:09 +0200 Subject: [PATCH 019/208] UE: Implement a thread safe wrapper class for accessing the mac_grant_ul_t member in ul_harq_process. This fixes many race conditions detected by TSAN around this class. --- srsue/hdr/stack/mac/ul_harq.h | 51 +++++++++++++++++++++++++++++++++- srsue/src/stack/mac/ul_harq.cc | 30 ++++++++++---------- 2 files changed, 65 insertions(+), 16 deletions(-) diff --git a/srsue/hdr/stack/mac/ul_harq.h b/srsue/hdr/stack/mac/ul_harq.h index ae51ec542..182f15672 100644 --- a/srsue/hdr/stack/mac/ul_harq.h +++ b/srsue/hdr/stack/mac/ul_harq.h @@ -66,7 +66,56 @@ private: void new_grant_ul(mac_interface_phy_lte::mac_grant_ul_t grant, mac_interface_phy_lte::tb_action_ul_t* action); private: - mac_interface_phy_lte::mac_grant_ul_t cur_grant; + /// Thread safe wrapper for a mac_grant_ul_t object. + class lockable_grant + { + mac_interface_phy_lte::mac_grant_ul_t grant = {}; + mutable std::mutex mutex; + + public: + void set(const mac_interface_phy_lte::mac_grant_ul_t& other) + { + std::lock_guard lock(mutex); + grant = other; + } + + void reset() + { + std::lock_guard lock(mutex); + grant = {}; + } + + void set_ndi(bool ndi) + { + std::lock_guard lock(mutex); + grant.tb.ndi = ndi; + } + + bool get_ndi() const + { + std::lock_guard lock(mutex); + return grant.tb.ndi; + } + + uint32_t get_tbs() const + { + std::lock_guard lock(mutex); + return grant.tb.tbs; + } + + int get_rv() const + { + std::lock_guard lock(mutex); + return grant.tb.rv; + } + + void set_rv(int rv) + { + std::lock_guard lock(mutex); + grant.tb.rv = rv; + } + }; + lockable_grant cur_grant; uint32_t pid; uint32_t current_tx_nb; diff --git a/srsue/src/stack/mac/ul_harq.cc b/srsue/src/stack/mac/ul_harq.cc index 6951b2a34..c97eb4a11 100644 --- a/srsue/src/stack/mac/ul_harq.cc +++ b/srsue/src/stack/mac/ul_harq.cc @@ -112,8 +112,6 @@ ul_harq_entity::ul_harq_process::ul_harq_process() : logger(srslog::fetch_basic_ pdu_ptr = NULL; payload_buffer = NULL; - bzero(&cur_grant, sizeof(mac_interface_phy_lte::mac_grant_ul_t)); - harq_feedback = false; is_initiated = false; is_grant_configured = false; @@ -155,12 +153,12 @@ void ul_harq_entity::ul_harq_process::reset() current_tx_nb = 0; current_irv = 0; is_grant_configured = false; - bzero(&cur_grant, sizeof(mac_interface_phy_lte::mac_grant_ul_t)); + cur_grant.reset(); } void ul_harq_entity::ul_harq_process::reset_ndi() { - cur_grant.tb.ndi = false; + cur_grant.set_ndi(false); } void ul_harq_entity::ul_harq_process::new_grant_ul(mac_interface_phy_lte::mac_grant_ul_t grant, @@ -198,8 +196,9 @@ void ul_harq_entity::ul_harq_process::new_grant_ul(mac_interface_phy_lte::mac_gr // Reset HARQ process if TB has changed if (harq_feedback && has_grant() && grant.tb.ndi_present) { - if (grant.tb.tbs != cur_grant.tb.tbs && cur_grant.tb.tbs > 0 && grant.tb.tbs > 0) { - Debug("UL %d: Reset due to change of dci size last_grant=%d, new_grant=%d", pid, cur_grant.tb.tbs, grant.tb.tbs); + uint32_t cur_grant_tbs = cur_grant.get_tbs(); + if (grant.tb.tbs != cur_grant_tbs && cur_grant_tbs > 0 && grant.tb.tbs > 0) { + Debug("UL %d: Reset due to change of dci size last_grant=%d, new_grant=%d", pid, cur_grant_tbs, grant.tb.tbs); reset(); } } @@ -286,7 +285,7 @@ bool ul_harq_entity::ul_harq_process::has_grant() bool ul_harq_entity::ul_harq_process::get_ndi() { - return cur_grant.tb.ndi; + return cur_grant.get_ndi(); } bool ul_harq_entity::ul_harq_process::is_sps() @@ -301,7 +300,7 @@ uint32_t ul_harq_entity::ul_harq_process::get_nof_retx() int ul_harq_entity::ul_harq_process::get_current_tbs() { - return cur_grant.tb.tbs; + return cur_grant.get_tbs(); } // Retransmission with or w/o dci (Section 5.4.2.2) @@ -323,15 +322,15 @@ void ul_harq_entity::ul_harq_process::generate_retx(mac_interface_phy_lte::mac_g grant.tb.tbs, harq_feedback ? "ACK" : "NACK", grant.tb.ndi, - cur_grant.tb.ndi); + cur_grant.get_ndi()); - cur_grant = grant; + cur_grant.set(grant); harq_feedback = false; generate_tx(action); // Reset the RV received in this grant - cur_grant.tb.rv = -1; + cur_grant.set_rv(-1); // HARQ entity requests a non-adaptive transmission } else if (!harq_feedback) { @@ -340,7 +339,7 @@ void ul_harq_entity::ul_harq_process::generate_retx(mac_interface_phy_lte::mac_g pid, current_tx_nb, get_rv(), - cur_grant.tb.tbs, + cur_grant.get_tbs(), harq_feedback ? "ACK" : "NACK"); generate_tx(action); @@ -356,7 +355,7 @@ void ul_harq_entity::ul_harq_process::generate_new_tx(mac_interface_phy_lte::mac harq_entity->average_retx.load(std::memory_order_relaxed), harq_entity->nof_pkts++), std::memory_order_relaxed); - cur_grant = grant; + cur_grant.set(grant); harq_feedback = false; is_grant_configured = true; current_tx_nb = 0; @@ -368,7 +367,7 @@ void ul_harq_entity::ul_harq_process::generate_new_tx(mac_interface_phy_lte::mac pid, grant.rnti == harq_entity->rntis->get_temp_rnti() ? " for Msg3" : "", get_rv(), - cur_grant.tb.tbs); + cur_grant.get_tbs()); generate_tx(action); } @@ -380,7 +379,8 @@ void ul_harq_entity::ul_harq_process::generate_tx(mac_interface_phy_lte::tb_acti action->current_tx_nb = current_tx_nb; action->expect_ack = true; - action->tb.rv = cur_grant.tb.rv > 0 ? cur_grant.tb.rv : get_rv(); + int rv = cur_grant.get_rv(); + action->tb.rv = rv > 0 ? rv : get_rv(); action->tb.enabled = true; action->tb.payload = pdu_ptr; action->tb.softbuffer.tx = &softbuffer; From d5b34696b4a795106bc92c36110c96e304113286 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 4 Oct 2021 12:29:35 +0200 Subject: [PATCH 020/208] Sepparate CSI report configuration from quantification and integrate in nr_phy_test with assertions --- lib/include/srsran/phy/phch/csi.h | 22 ++++-- lib/include/srsran/phy/phch/csi_cfg.h | 7 +- lib/src/common/phy_cfg_nr.cc | 5 +- lib/src/common/phy_cfg_nr_default.cc | 18 +++++ lib/src/phy/phch/csi.c | 110 +++++++++++++++----------- lib/src/phy/phch/ra_ul_nr.c | 4 +- lib/src/phy/phch/test/pusch_nr_test.c | 8 +- lib/src/phy/phch/uci_nr.c | 6 +- srsue/hdr/phy/nr/state.h | 13 ++- srsue/src/phy/nr/cc_worker.cc | 2 +- test/phy/CMakeLists.txt | 2 +- test/phy/dummy_gnb_stack.h | 27 ++++++- test/phy/nr_phy_test.cc | 72 +++++++++++++---- 13 files changed, 204 insertions(+), 92 deletions(-) diff --git a/lib/include/srsran/phy/phch/csi.h b/lib/include/srsran/phy/phch/csi.h index 49319f72b..0bbfe0e24 100644 --- a/lib/include/srsran/phy/phch/csi.h +++ b/lib/include/srsran/phy/phch/csi.h @@ -31,18 +31,26 @@ srsran_csi_new_nzp_csi_rs_measurement(const srsran_csi_hl_resource_cfg_t csi_res uint32_t nzp_csi_rs_id); /** - * @brief Generates CSI report configuration and values from the higher layer configuration and a list of measurements + * @brief Generates CSI report configuration from the higher layer configuration for a given slot * @param cfg Higher layer report configuration - * @param slot_idx Slot index within the radio frame - * @param measurements Filtered CSI measurements - * @param[out] report_cfg Report configuration re + * @param slot_cfg Current slot configuration + * @param[out] report_cfg Report configuration for the given slot + * @return The number CSI reports for transmission if the provided data is valid, SRSRAN_ERROR code otherwise + */ +SRSRAN_API int srsran_csi_reports_generate(const srsran_csi_hl_cfg_t* cfg, + const srsran_slot_cfg_t* slot_cfg, + srsran_csi_report_cfg_t report_cfg[SRSRAN_CSI_MAX_NOF_REPORT]); + +/** + * @brief Quantifies a given set of CSI reports from the given set of measurements + * @param reports Set of report configuration + * @param measurements Set of measurements to quantify + * @param report_value Set of report values * @return The number CSI reports for transmission if the provided data is valid, SRSRAN_ERROR code otherwise */ SRSRAN_API int -srsran_csi_generate_reports(const srsran_csi_hl_cfg_t* cfg, - uint32_t slot_idx, +srsran_csi_reports_quantify(const srsran_csi_report_cfg_t reports[SRSRAN_CSI_MAX_NOF_REPORT], const srsran_csi_channel_measurements_t measurements[SRSRAN_CSI_MAX_NOF_RESOURCES], - srsran_csi_report_cfg_t report_cfg[SRSRAN_CSI_MAX_NOF_REPORT], srsran_csi_report_value_t report_value[SRSRAN_CSI_MAX_NOF_REPORT]); /** diff --git a/lib/include/srsran/phy/phch/csi_cfg.h b/lib/include/srsran/phy/phch/csi_cfg.h index 5fb4e3b84..6471c9fc8 100644 --- a/lib/include/srsran/phy/phch/csi_cfg.h +++ b/lib/include/srsran/phy/phch/csi_cfg.h @@ -162,12 +162,10 @@ typedef struct SRSRAN_API { /** * @brief CSI report configuration + * @note An unset report is marked with `cfg.type = SRSRAN_CSI_REPORT_TYPE_NONE` */ typedef struct SRSRAN_API { - srsran_csi_report_type_t type; ///< CSI report type (none, periodic, semiPersistentOnPUCCH, ...) - srsran_csi_report_quantity_t quantity; ///< Report quantity - srsran_pucch_nr_resource_t pucch_resource; ///< PUCCH resource to use for periodic reporting - srsran_csi_report_freq_t freq_cfg; ///< Determine whether it is wideband or subband + srsran_csi_hl_report_cfg_t cfg; ///< Higher layer CSI report configuration // Resource set context uint32_t nof_ports; ///< Number of antenna ports @@ -193,7 +191,6 @@ typedef struct SRSRAN_API { void* none; srsran_csi_report_wideband_cri_ri_pmi_cqi_t wideband_cri_ri_pmi_cqi; }; - bool valid; ///< Used by receiver only } srsran_csi_report_value_t; /** diff --git a/lib/src/common/phy_cfg_nr.cc b/lib/src/common/phy_cfg_nr.cc index cc096bb90..0c31099d4 100644 --- a/lib/src/common/phy_cfg_nr.cc +++ b/lib/src/common/phy_cfg_nr.cc @@ -307,7 +307,10 @@ bool phy_cfg_nr_t::get_uci_cfg(const srsran_slot_cfg_t& slot_cfg, } // Generate configuration for CSI reports - // ... + n = srsran_csi_reports_generate(&csi, &slot_cfg, uci_cfg.csi); + if (n > SRSRAN_SUCCESS) { + uci_cfg.nof_csi = (uint32_t)n; + } return true; } diff --git a/lib/src/common/phy_cfg_nr_default.cc b/lib/src/common/phy_cfg_nr_default.cc index c3847f836..58c8b1fcb 100644 --- a/lib/src/common/phy_cfg_nr_default.cc +++ b/lib/src/common/phy_cfg_nr_default.cc @@ -472,6 +472,24 @@ phy_cfg_nr_default_t::phy_cfg_nr_default_t(const reference_cfg_t& reference_cfg) } prach.tdd_config.configured = (duplex.mode == SRSRAN_DUPLEX_MODE_TDD); + + // Make default CSI report configuration always + csi.reports[0].channel_meas_id = 0; + csi.reports[0].type = SRSRAN_CSI_REPORT_TYPE_PERIODIC; + csi.reports[0].periodic.period = 20; + csi.reports[0].periodic.offset = 9; + csi.reports[0].periodic.resource.format = SRSRAN_PUCCH_NR_FORMAT_2; + csi.reports[0].periodic.resource.starting_prb = 51; + csi.reports[0].periodic.resource.format = SRSRAN_PUCCH_NR_FORMAT_2; + csi.reports[0].periodic.resource.nof_prb = 1; + csi.reports[0].periodic.resource.nof_symbols = 2; + csi.reports[0].periodic.resource.start_symbol_idx = 10; + csi.reports[0].quantity = SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI; + csi.reports[0].cqi_table = SRSRAN_CSI_CQI_TABLE_1; + csi.reports[0].freq_cfg = SRSRAN_CSI_REPORT_FREQ_WIDEBAND; + csi.csi_resources[0].type = srsran_csi_hl_resource_cfg_t::SRSRAN_CSI_HL_RESOURCE_CFG_TYPE_NZP_CSI_RS_SSB; + csi.csi_resources[0].nzp_csi_rs_ssb.nzp_csi_rs_resource_set_id_list[0] = 0; + csi.csi_resources[0].nzp_csi_rs_ssb.nzp_csi_rs_resource_set_id_list_count = 1; } } // namespace srsran diff --git a/lib/src/phy/phch/csi.c b/lib/src/phy/phch/csi.c index d7d7a1704..412aec709 100644 --- a/lib/src/phy/phch/csi.c +++ b/lib/src/phy/phch/csi.c @@ -39,7 +39,6 @@ static bool csi_report_trigger(const srsran_csi_hl_report_cfg_t* cfg, uint32_t s static void csi_wideband_cri_ri_pmi_cqi_quantify(const srsran_csi_hl_report_cfg_t* cfg, const srsran_csi_channel_measurements_t* channel_meas, const srsran_csi_channel_measurements_t* interf_meas, - srsran_csi_report_cfg_t* report_cfg, srsran_csi_report_value_t* report_value) { // Take SNR by default @@ -50,18 +49,6 @@ static void csi_wideband_cri_ri_pmi_cqi_quantify(const srsran_csi_hl_report_cfg_ wideband_sinr_db = channel_meas->wideband_rsrp_dBm - interf_meas->wideband_epre_dBm; } - // Fill report configuration - report_cfg->type = cfg->type; - report_cfg->quantity = SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI; - report_cfg->freq_cfg = SRSRAN_CSI_REPORT_FREQ_WIDEBAND; - report_cfg->nof_ports = channel_meas->nof_ports; - report_cfg->K_csi_rs = channel_meas->K_csi_rs; - - // Save PUCCH resource only if periodic type - if (cfg->type == SRSRAN_CSI_REPORT_TYPE_PERIODIC) { - report_cfg->pucch_resource = cfg->periodic.resource; - } - // Fill quantified values report_value->wideband_cri_ri_pmi_cqi.cqi = csi_snri_db_to_cqi(cfg->cqi_table, wideband_sinr_db); report_value->wideband_cri_ri_pmi_cqi.ri = 0; @@ -190,48 +177,79 @@ int srsran_csi_new_nzp_csi_rs_measurement( return SRSRAN_SUCCESS; } -int srsran_csi_generate_reports(const srsran_csi_hl_cfg_t* cfg, - uint32_t slot_idx, - const srsran_csi_channel_measurements_t measurements[SRSRAN_CSI_MAX_NOF_RESOURCES], - srsran_csi_report_cfg_t report_cfg[SRSRAN_CSI_MAX_NOF_REPORT], - srsran_csi_report_value_t report_value[SRSRAN_CSI_MAX_NOF_REPORT]) +int srsran_csi_reports_generate(const srsran_csi_hl_cfg_t* cfg, + const srsran_slot_cfg_t* slot_cfg, + srsran_csi_report_cfg_t report_cfg[SRSRAN_CSI_MAX_NOF_REPORT]) { uint32_t count = 0; // Check inputs - if (cfg == NULL || measurements == NULL || report_cfg == NULL || report_value == NULL) { + if (cfg == NULL || report_cfg == NULL) { return SRSRAN_ERROR_INVALID_INPUTS; } + // Make sure report configuration is initialised to zero + SRSRAN_MEM_ZERO(report_cfg, srsran_csi_report_cfg_t, SRSRAN_CSI_MAX_NOF_REPORT); + // Iterate every possible configured CSI report for (uint32_t i = 0; i < SRSRAN_CSI_MAX_NOF_REPORT; i++) { // Skip if report is not configured or triggered - if (!csi_report_trigger(&cfg->reports[i], slot_idx)) { + if (!csi_report_trigger(&cfg->reports[i], slot_cfg->idx)) { continue; } + // Configure report + report_cfg[count].cfg = cfg->reports[i]; + report_cfg[count].nof_ports = 1; + report_cfg[count].K_csi_rs = 1; + report_cfg[count].has_part2 = false; + count++; + } + + return (int)count; +} + +int srsran_csi_reports_quantify(const srsran_csi_report_cfg_t reports[SRSRAN_CSI_MAX_NOF_REPORT], + const srsran_csi_channel_measurements_t measurements[SRSRAN_CSI_MAX_NOF_RESOURCES], + srsran_csi_report_value_t report_value[SRSRAN_CSI_MAX_NOF_REPORT]) +{ + uint32_t count = 0; + + // Check inputs + if (reports == NULL || measurements == NULL || report_value == NULL) { + return SRSRAN_ERROR_INVALID_INPUTS; + } + + // Iterate every possible configured CSI report + for (uint32_t i = 0; i < SRSRAN_CSI_MAX_NOF_REPORT; i++) { + // If the report is the last one, break + if (reports->cfg.type == SRSRAN_CSI_REPORT_TYPE_NONE) { + break; + } + // Select channel measurement - if (cfg->reports->channel_meas_id >= SRSRAN_CSI_MAX_NOF_RESOURCES) { - ERROR("Channel measurement ID (%d) is out of range", cfg->reports->channel_meas_id); + uint32_t channel_meas_id = reports[i].cfg.channel_meas_id; + if (channel_meas_id >= SRSRAN_CSI_MAX_NOF_RESOURCES) { + ERROR("Channel measurement ID (%d) is out of range", channel_meas_id); return SRSRAN_ERROR; } - const srsran_csi_channel_measurements_t* channel_meas = &measurements[cfg->reports->channel_meas_id]; + const srsran_csi_channel_measurements_t* channel_meas = &measurements[channel_meas_id]; // Select interference measurement const srsran_csi_channel_measurements_t* interf_meas = NULL; - if (cfg->reports->interf_meas_present) { - if (cfg->reports->interf_meas_id >= SRSRAN_CSI_MAX_NOF_RESOURCES) { - ERROR("Interference measurement ID (%d) is out of range", cfg->reports->interf_meas_id); + if (reports[i].cfg.interf_meas_present) { + uint32_t interf_meas_id = reports[i].cfg.interf_meas_id; + if (interf_meas_id >= SRSRAN_CSI_MAX_NOF_RESOURCES) { + ERROR("Interference measurement ID (%d) is out of range", interf_meas_id); return SRSRAN_ERROR; } - interf_meas = &measurements[cfg->reports->interf_meas_id]; + interf_meas = &measurements[interf_meas_id]; } // Quantify measurements according to frequency and quantity configuration - if (cfg->reports->freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND && - cfg->reports->quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) { - csi_wideband_cri_ri_pmi_cqi_quantify( - &cfg->reports[i], channel_meas, interf_meas, &report_cfg[count], &report_value[count]); + if (reports[i].cfg.freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND && + reports[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) { + csi_wideband_cri_ri_pmi_cqi_quantify(&reports[i].cfg, channel_meas, interf_meas, &report_value[count]); count++; } else { ; // Ignore other types @@ -253,9 +271,9 @@ int srsran_csi_part1_nof_bits(const srsran_csi_report_cfg_t* report_list, uint32 // Iterate all report configurations for (uint32_t i = 0; i < nof_reports; i++) { const srsran_csi_report_cfg_t* report = &report_list[i]; - if (report->quantity && report->quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) { + if (report->cfg.quantity && report->cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) { count += csi_wideband_cri_ri_pmi_cqi_nof_bits(report); - } else if (report->quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) { + } else if (report->cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) { count += csi_none_nof_bits(report); } } @@ -308,15 +326,15 @@ int srsran_csi_part1_pack(const srsran_csi_report_cfg_t* report_cfg, } for (uint32_t i = 0; i < nof_reports && count < max_o_csi1; i++) { - if (report_cfg[i].freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND && - report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) { + if (report_cfg[i].cfg.freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND && + report_cfg[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) { count += csi_wideband_cri_ri_pmi_cqi_pack(&report_cfg[i], &report_value[i], &o_csi1[count]); - } else if (report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) { + } else if (report_cfg[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) { count += csi_none_pack(&report_cfg[i], &report_value[i], &o_csi1[count]); } else { ERROR("CSI frequency (%d) and quantity (%d) combination is not implemented", - report_cfg[i].freq_cfg, - report_cfg[i].quantity); + report_cfg[i].cfg.freq_cfg, + report_cfg[i].cfg.quantity); } } @@ -342,15 +360,15 @@ int srsran_csi_part1_unpack(const srsran_csi_report_cfg_t* report_cfg, } for (uint32_t i = 0; i < nof_reports && count < max_o_csi1; i++) { - if (report_cfg[i].freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND && - report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) { + if (report_cfg[i].cfg.freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND && + report_cfg[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) { count += csi_wideband_cri_ri_pmi_cqi_unpack(&report_cfg[i], &o_csi1[count], &report_value[i]); - } else if (report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) { + } else if (report_cfg[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) { count += csi_none_unpack(&report_cfg[i], &o_csi1[count], &report_value[i]); } else { ERROR("CSI frequency (%d) and quantity (%d) combination is not implemented", - report_cfg[i].freq_cfg, - report_cfg[i].quantity); + report_cfg[i].cfg.freq_cfg, + report_cfg[i].cfg.quantity); } } @@ -365,10 +383,10 @@ uint32_t srsran_csi_str(const srsran_csi_report_cfg_t* report_cfg, { uint32_t len = 0; for (uint32_t i = 0; i < nof_reports; i++) { - if (report_cfg[i].freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND && - report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) { + if (report_cfg[i].cfg.freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND && + report_cfg[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) { len = srsran_print_check(str, str_len, len, "cqi=%d ", report_value[i].wideband_cri_ri_pmi_cqi.cqi); - } else if (report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) { + } else if (report_cfg[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) { char tmp[20] = {}; srsran_vec_sprint_bin(tmp, sizeof(tmp), report_value[i].none, report_cfg->K_csi_rs); len = srsran_print_check(str, str_len, len, "csi=%s ", tmp); diff --git a/lib/src/phy/phch/ra_ul_nr.c b/lib/src/phy/phch/ra_ul_nr.c index b750f1ea4..d2ae614b8 100644 --- a/lib/src/phy/phch/ra_ul_nr.c +++ b/lib/src/phy/phch/ra_ul_nr.c @@ -614,8 +614,8 @@ int srsran_ra_ul_nr_pucch_resource(const srsran_pucch_nr_hl_cfg_t* pucch_cfg, // - Irrelevant SR opportunities // - No HARQ-ACK // - Single periodic CSI report - if (uci_cfg->ack.count == 0 && uci_cfg->nof_csi == 1 && uci_cfg->csi[0].type == SRSRAN_CSI_REPORT_TYPE_PERIODIC) { - *resource = uci_cfg->csi[0].pucch_resource; + if (uci_cfg->ack.count == 0 && uci_cfg->nof_csi == 1 && uci_cfg->csi[0].cfg.type == SRSRAN_CSI_REPORT_TYPE_PERIODIC) { + *resource = uci_cfg->csi[0].cfg.periodic.resource; return SRSRAN_SUCCESS; } diff --git a/lib/src/phy/phch/test/pusch_nr_test.c b/lib/src/phy/phch/test/pusch_nr_test.c index f2f886047..def99976e 100644 --- a/lib/src/phy/phch/test/pusch_nr_test.c +++ b/lib/src/phy/phch/test/pusch_nr_test.c @@ -225,10 +225,10 @@ int main(int argc, char** argv) uint8_t csi_report_tx[SRSRAN_UCI_NR_MAX_CSI1_BITS] = {}; uint8_t csi_report_rx[SRSRAN_UCI_NR_MAX_CSI1_BITS] = {}; if (nof_csi_bits > 0) { - pusch_cfg.uci.csi[0].quantity = SRSRAN_CSI_REPORT_QUANTITY_NONE; - pusch_cfg.uci.csi[0].K_csi_rs = nof_csi_bits; - pusch_cfg.uci.nof_csi = 1; - data_tx.uci.csi[0].none = csi_report_tx; + pusch_cfg.uci.csi[0].cfg.quantity = SRSRAN_CSI_REPORT_QUANTITY_NONE; + pusch_cfg.uci.csi[0].K_csi_rs = nof_csi_bits; + pusch_cfg.uci.nof_csi = 1; + data_tx.uci.csi[0].none = csi_report_tx; for (uint32_t i = 0; i < nof_csi_bits; i++) { csi_report_tx[i] = (uint8_t)srsran_random_uniform_int_dist(rand_gen, 0, 1); } diff --git a/lib/src/phy/phch/uci_nr.c b/lib/src/phy/phch/uci_nr.c index f93ab6cbf..f7934fe7d 100644 --- a/lib/src/phy/phch/uci_nr.c +++ b/lib/src/phy/phch/uci_nr.c @@ -299,8 +299,7 @@ static int uci_nr_A(const srsran_uci_cfg_nr_t* cfg) } // 6.3.1.1.3 HARQ-ACK/SR and CSI - ERROR("HARQ-ACK/SR and CSI encoding are not implemented"); - return SRSRAN_ERROR; + return cfg->ack.count + cfg->o_sr + o_csi; } static int uci_nr_pack_pucch(const srsran_uci_cfg_nr_t* cfg, const srsran_uci_value_nr_t* value, uint8_t* sequence) @@ -332,8 +331,7 @@ static int uci_nr_unpack_pucch(const srsran_uci_cfg_nr_t* cfg, uint8_t* sequence // 6.3.1.1.2 CSI only if (cfg->ack.count == 0 && cfg->o_sr == 0) { - ERROR("CSI only are not implemented"); - return SRSRAN_ERROR; + return srsran_csi_part1_unpack(cfg->csi, cfg->nof_csi, sequence, SRSRAN_UCI_NR_MAX_NOF_BITS, value->csi); } // 6.3.1.1.3 HARQ-ACK/SR and CSI diff --git a/srsue/hdr/phy/nr/state.h b/srsue/hdr/phy/nr/state.h index 78891e68e..238d5e646 100644 --- a/srsue/hdr/phy/nr/state.h +++ b/srsue/hdr/phy/nr/state.h @@ -344,14 +344,21 @@ public: uci_data.value.sr = sr_count_positive; } - void get_periodic_csi(const uint32_t& tti, srsran_uci_data_nr_t& uci_data) + void get_periodic_csi(const srsran_slot_cfg_t& slot_cfg, srsran_uci_data_nr_t& uci_data) { - int n = srsran_csi_generate_reports(&cfg.csi, tti, csi_measurements.data(), uci_data.cfg.csi, uci_data.value.csi); + // Generate report configurations + int n = srsran_csi_reports_generate(&cfg.csi, &slot_cfg, uci_data.cfg.csi); if (n > SRSRAN_SUCCESS) { uci_data.cfg.nof_csi = n; } - uci_data.cfg.pucch.rnti = stack->get_ul_sched_rnti_nr(tti).id; + // Quantify reports from measurements + n = srsran_csi_reports_quantify(uci_data.cfg.csi, csi_measurements.data(), uci_data.value.csi); + if (n > SRSRAN_SUCCESS) { + uci_data.cfg.nof_csi = n; + } + + uci_data.cfg.pucch.rnti = stack->get_ul_sched_rnti_nr(slot_cfg.idx).id; } /** diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index 79512b4c5..25d126193 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -590,7 +590,7 @@ bool cc_worker::work_ul() } // Add CSI reports to UCI data if available - phy.get_periodic_csi(ul_slot_cfg.idx, uci_data); + phy.get_periodic_csi(ul_slot_cfg, uci_data); // Setup frequency offset srsran_ue_ul_nr_set_freq_offset(&ue_ul, phy.get_ul_cfo()); diff --git a/test/phy/CMakeLists.txt b/test/phy/CMakeLists.txt index 0c79a85b9..2e9ea2f3c 100644 --- a/test/phy/CMakeLists.txt +++ b/test/phy/CMakeLists.txt @@ -40,7 +40,7 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) foreach (NR_PHY_TEST_BW "10MHz" "20MHz") # For each supported frame structure foreach (NR_PHY_TEST_DUPLEX "FDD" "6D+4U" "FR1.15-1") - set(NR_PHY_TEST_DURATION_MS 20) + set(NR_PHY_TEST_DURATION_MS 50) # DL flooding only foreach (NR_PHY_TEST_PDSCH "default" "ts38101/5.2-1") diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index 83c7d7659..b9f80e10c 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -55,10 +55,12 @@ public: }; struct metrics_t { - std::map prach = {}; ///< PRACH metrics indexed with premable index - srsenb::mac_ue_metrics_t mac = {}; ///< MAC metrics - uint32_t sr_count = 0; ///< SR counter - pucch_metrics_t pucch = {}; + std::map prach = {}; ///< PRACH metrics indexed with premable index + srsenb::mac_ue_metrics_t mac = {}; ///< MAC metrics + uint32_t sr_count = 0; ///< SR counter + uint32_t cqi_count = 0; ///< CQI opportunity counter + uint32_t cqi_valid_count = 0; ///< Valid CQI counter + pucch_metrics_t pucch = {}; }; private: @@ -304,6 +306,23 @@ private: metrics.sr_count++; } + // Process CQI + for (uint32_t i = 0; i < cfg.nof_csi; i++) { + // Increment CQI opportunity + metrics.cqi_count++; + + // Skip if invalid or not supported CSI report + if (not value.valid or cfg.csi[i].cfg.quantity != SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI or + cfg.csi[i].cfg.freq_cfg != SRSRAN_CSI_REPORT_FREQ_WIDEBAND) { + continue; + } + + // Add statistics + metrics.mac.dl_cqi = + SRSRAN_VEC_SAFE_CMA(value.csi->wideband_cri_ri_pmi_cqi.cqi, metrics.mac.dl_cqi, metrics.cqi_count); + metrics.cqi_valid_count++; + } + return true; } diff --git a/test/phy/nr_phy_test.cc b/test/phy/nr_phy_test.cc index 3303e9402..bdf8d7222 100644 --- a/test/phy/nr_phy_test.cc +++ b/test/phy/nr_phy_test.cc @@ -21,6 +21,11 @@ // shorten boost program options namespace namespace bpo = boost::program_options; +static double assert_sr_detection_min = 1.000; +static double assert_cqi_detection_min = 1.000; +static double assert_pusch_bler_max = 0.000; +static double assert_pdsch_bler_max = 0.000; + test_bench::args_t::args_t(int argc, char** argv) { std::string reference_cfg_str = ""; @@ -29,6 +34,7 @@ test_bench::args_t::args_t(int argc, char** argv) bpo::options_description options_gnb_phy("gNb PHY related options"); bpo::options_description options_ue_stack("UE stack options"); bpo::options_description options_ue_phy("UE stack options"); + bpo::options_description options_assertion("Test assertions"); uint16_t rnti = 17921; @@ -80,6 +86,13 @@ test_bench::args_t::args_t(int argc, char** argv) ("ue.stack.prach.preamble", bpo::value(&ue_stack.prach_preamble)->default_value(ue_stack.prach_preamble), "PRACH preamble. Set 0 to disable and 1 for all.") ; + options_assertion.add_options() + ("assert.sr.detection.min", bpo::value(&assert_sr_detection_min)->default_value(assert_sr_detection_min), "Scheduling request minimum detection threshold") + ("assert.cqi.detection.min", bpo::value(&assert_cqi_detection_min)->default_value(assert_cqi_detection_min), "CQI report minimum detection threshold") + ("assert.pusch.bler.max", bpo::value(&assert_pusch_bler_max)->default_value(assert_pusch_bler_max), "PUSCH maximum BLER threshold") + ("assert.pdsch.bler.max", bpo::value(&assert_pdsch_bler_max)->default_value(assert_pdsch_bler_max), "PDSCH maximum BLER threshold") + ; + options.add(options_gnb_stack).add(options_gnb_phy).add(options_ue_stack).add(options_ue_phy).add_options() ("help", "Show this message") ; @@ -164,9 +177,9 @@ int main(int argc, char** argv) test_bench::metrics_t metrics = tb.get_gnb_metrics(); // Print PDSCH metrics if scheduled + double pdsch_bler = 0.0; if (metrics.gnb_stack.mac.tx_pkts > 0) { - float pdsch_bler = 0.0f; - pdsch_bler = (float)metrics.gnb_stack.mac.tx_errors / (float)metrics.gnb_stack.mac.tx_pkts; + pdsch_bler = (double)metrics.gnb_stack.mac.tx_errors / (double)metrics.gnb_stack.mac.tx_pkts; float pdsch_shed_rate = 0.0f; pdsch_shed_rate = (float)metrics.gnb_stack.mac.tx_brate / (float)metrics.gnb_stack.mac.tx_pkts / 1000.0f; @@ -181,10 +194,10 @@ int main(int argc, char** argv) } // Print PUSCH metrics if scheduled + double pusch_bler = 0.0; if (metrics.gnb_stack.mac.rx_pkts > 0) { - float pusch_bler = 0.0f; if (metrics.gnb_stack.mac.rx_pkts != 0) { - pusch_bler = (float)metrics.gnb_stack.mac.rx_errors / (float)metrics.gnb_stack.mac.rx_pkts; + pusch_bler = (double)metrics.gnb_stack.mac.rx_errors / (double)metrics.gnb_stack.mac.rx_pkts; } float pusch_shed_rate = 0.0f; @@ -261,23 +274,54 @@ int main(int argc, char** argv) srsran::console(" +------------+------------+------------+------------+\n"); } + srsran::console("UCI stats:\n"); + srsran::console(" +------------+------------+------------+------------+------------+\n"); + srsran::console( + " | %10s | %10s | %10s | %10s | %10s |\n", "Field", "Transmit'd", "Received", "Detection", "Avg. Val."); + srsran::console(" +------------+------------+------------+------------+------------+\n"); + // Print SR + double sr_detection = 0.0; if (metrics.ue_stack.sr_count > 0) { - srsran::console("SR:\n"); - srsran::console(" +------------+------------+------------+\n"); - srsran::console(" | %10s | %10s | %10s |\n", "Transmit'd", "Received", "Detection"); - srsran::console(" +------------+------------+------------+\n"); - srsran::console(" | %10d | %10d | %10.5f |\n", + sr_detection = (double)metrics.gnb_stack.sr_count / (double)metrics.ue_stack.sr_count; + srsran::console(" | %10s | %10d | %10d | %10.5f | %10s |\n", + "SR", metrics.ue_stack.sr_count, metrics.gnb_stack.sr_count, - (double)metrics.gnb_stack.sr_count / (double)metrics.ue_stack.sr_count); - srsran::console(" +------------+------------+------------+\n"); + sr_detection, + "-"); + } + + // Print SR + double cqi_detection = 0.0; + if (metrics.gnb_stack.cqi_count > 0) { + cqi_detection = (double)metrics.gnb_stack.cqi_valid_count / (double)metrics.gnb_stack.cqi_count; + srsran::console(" | %10s | %10d | %10d | %10.5f | %10.5f |\n", + "CQI", + metrics.gnb_stack.cqi_count, + metrics.gnb_stack.cqi_valid_count, + cqi_detection, + metrics.gnb_stack.mac.dl_cqi); } + srsran::console(" +------------+------------+------------+------------+------------+\n"); // Assert metrics - TESTASSERT_EQ(0, metrics.gnb_stack.mac.tx_errors); - TESTASSERT_EQ(0, metrics.gnb_stack.mac.rx_errors); - TESTASSERT(metrics.ue_stack.sr_count == metrics.gnb_stack.sr_count); + srsran_assert(metrics.gnb_stack.mac.tx_pkts == 0 or pdsch_bler <= assert_pdsch_bler_max, + "PDSCH BLER (%f) exceeds the assertion maximum (%f)", + pdsch_bler, + assert_pusch_bler_max); + srsran_assert(metrics.gnb_stack.mac.rx_pkts == 0 or pusch_bler <= assert_pusch_bler_max, + "PUSCH BLER (%f) exceeds the assertion maximum (%f)", + pusch_bler, + assert_pusch_bler_max); + srsran_assert(metrics.ue_stack.sr_count == 0 or sr_detection >= assert_sr_detection_min, + "SR detection probability (%f) did not reach the assertion minimum (%f)", + sr_detection, + assert_sr_detection_min); + srsran_assert(metrics.gnb_stack.cqi_count == 0 or cqi_detection >= assert_cqi_detection_min, + "CQI report detection probability (%f) did not reach the assertion minimum (%f)", + cqi_detection, + assert_sr_detection_min); // If reached here, the test is successful return SRSRAN_SUCCESS; From 3b7939397457729d23b0f95753870c3e2da9bf3d Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 6 Oct 2021 12:10:24 +0100 Subject: [PATCH 021/208] sched,nr: fix default ue configuration when prach arrives --- lib/src/common/phy_cfg_nr_default.cc | 2 +- srsenb/src/stack/mac/nr/mac_nr.cc | 2 +- srsenb/src/stack/rrc/rrc_nr.cc | 2 +- srsenb/test/mac/nr/sched_nr_cfg_generators.h | 23 ++++++++++++++++++++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/src/common/phy_cfg_nr_default.cc b/lib/src/common/phy_cfg_nr_default.cc index 58c8b1fcb..d100c8c83 100644 --- a/lib/src/common/phy_cfg_nr_default.cc +++ b/lib/src/common/phy_cfg_nr_default.cc @@ -477,7 +477,7 @@ phy_cfg_nr_default_t::phy_cfg_nr_default_t(const reference_cfg_t& reference_cfg) csi.reports[0].channel_meas_id = 0; csi.reports[0].type = SRSRAN_CSI_REPORT_TYPE_PERIODIC; csi.reports[0].periodic.period = 20; - csi.reports[0].periodic.offset = 9; + csi.reports[0].periodic.offset = 10; csi.reports[0].periodic.resource.format = SRSRAN_PUCCH_NR_FORMAT_2; csi.reports[0].periodic.resource.starting_prb = 51; csi.reports[0].periodic.resource.format = SRSRAN_PUCCH_NR_FORMAT_2; diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index f018cb9fe..30654c232 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -135,7 +135,7 @@ uint16_t mac_nr::reserve_rnti(uint32_t enb_cc_idx) } // Add new user to the scheduler so that it can RX/TX SRB0 - srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1); + srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_rach_ue_cfg(enb_cc_idx); sched.ue_cfg(rnti, ue_cfg); return rnti; diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index d2e6b1ff0..01edefc30 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -504,7 +504,7 @@ int rrc_nr::sgnb_reconfiguration_complete(uint16_t eutra_rnti, asn1::dyn_octstri Every function in UE class is called from a mutex environment thus does not need extra protection. *******************************************************************************/ -rrc_nr::ue::ue(rrc_nr* parent_, uint16_t rnti_) : parent(parent_), rnti(rnti_), uecfg(srsenb::get_default_ue_cfg(1)) {} +rrc_nr::ue::ue(rrc_nr* parent_, uint16_t rnti_) : parent(parent_), rnti(rnti_), uecfg(srsenb::get_rach_ue_cfg(0)) {} void rrc_nr::ue::send_connection_setup() { diff --git a/srsenb/test/mac/nr/sched_nr_cfg_generators.h b/srsenb/test/mac/nr/sched_nr_cfg_generators.h index dbf8afd1c..2744b40ce 100644 --- a/srsenb/test/mac/nr/sched_nr_cfg_generators.h +++ b/srsenb/test/mac/nr/sched_nr_cfg_generators.h @@ -78,6 +78,29 @@ inline std::vector get_default_cells_cfg( return cells; } +inline sched_nr_interface::ue_cfg_t get_rach_ue_cfg(uint32_t cc) +{ + sched_nr_interface::ue_cfg_t uecfg{}; + + // set Pcell + uecfg.carriers.resize(1); + uecfg.carriers[0].active = true; + uecfg.carriers[0].cc = cc; + + // set SRB0 as active + uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; + + // set basic PHY config + uecfg.phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}}; + uecfg.phy_cfg.csi = {}; + + // Note: dynamic MCS not yet supported + uecfg.fixed_dl_mcs = 28; + uecfg.fixed_ul_mcs = 28; + + return uecfg; +} + inline sched_nr_interface::ue_cfg_t get_default_ue_cfg( uint32_t nof_cc, const srsran::phy_cfg_nr_t& phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}}) From 8d2c394326a367047d3b8204a648c5bacc2abcef Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 6 Oct 2021 16:25:24 +0200 Subject: [PATCH 022/208] enb,rrc: fix SSB absolute freq value in EUTRA measConfig we've been using the ARFCN of the NR carrier instead of the absolute freq SSB. The patch fixes this and renames the variable to make it clearer. --- srsenb/hdr/stack/rrc/rrc_config.h | 2 +- srsenb/src/enb_cfg_parser.cc | 2 +- srsenb/src/stack/rrc/rrc_endc.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_config.h b/srsenb/hdr/stack/rrc/rrc_config.h index 4f6400620..aa402b37b 100644 --- a/srsenb/hdr/stack/rrc/rrc_config.h +++ b/srsenb/hdr/stack/rrc/rrc_config.h @@ -46,7 +46,7 @@ struct srb_cfg_t { // Parameter required for NR cell measurement handling struct rrc_endc_cfg_t { bool act_from_b1_event; - uint32_t nr_dl_arfcn; + uint32_t abs_frequency_ssb; uint32_t nr_band; using ssb_nr_cfg = asn1::rrc::mtc_ssb_nr_r15_s; using ssb_rs_cfg = asn1::rrc::rs_cfg_ssb_nr_r15_s; diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 91e4313f7..13121027b 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -1167,7 +1167,7 @@ int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, rrc_nr_cfg_t* rrc_nr // update EUTRA RRC params for ENDC if (rrc_nr_cfg_->cell_list.size() == 1) { - rrc_cfg_->endc_cfg.nr_dl_arfcn = rrc_nr_cfg_->cell_list.at(0).dl_arfcn; + 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; diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index aa4fe3d28..22a77614a 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -61,7 +61,7 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn meas_obj.meas_obj_id = meas_cfg.meas_obj_to_add_mod_list.size() + 1; meas_obj.meas_obj.set_meas_obj_nr_r15(); auto& meas_obj_nr = meas_obj.meas_obj.meas_obj_nr_r15(); - meas_obj_nr.carrier_freq_r15 = endc_cfg.nr_dl_arfcn; + meas_obj_nr.carrier_freq_r15 = endc_cfg.abs_frequency_ssb; meas_obj_nr.rs_cfg_ssb_r15.meas_timing_cfg_r15.periodicity_and_offset_r15 = endc_cfg.ssb_period_offset; meas_obj_nr.rs_cfg_ssb_r15.meas_timing_cfg_r15.ssb_dur_r15 = endc_cfg.ssb_duration; meas_obj_nr.rs_cfg_ssb_r15.subcarrier_spacing_ssb_r15 = endc_cfg.ssb_ssc; From 703e8dc6f140efbcfff730b24ce95d0dcc3a1e6b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 6 Oct 2021 17:01:50 +0200 Subject: [PATCH 023/208] enb,rrc_nr: fix bug where freqInfoUL was not containing abs_freqpoint_A for FDD --- srsenb/src/stack/rrc/rrc_nr.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 01edefc30..e49493c99 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -1045,6 +1045,7 @@ int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_freq_info_ cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.freq_info_ul_present = true; auto& freq_info_ul = cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.freq_info_ul; freq_info_ul.freq_band_list.push_back(parent->cfg.cell_list[0].band); + freq_info_ul.absolute_freq_point_a_present = true; freq_info_ul.absolute_freq_point_a = parent->cfg.cell_list[0].ul_absolute_freq_point_a; freq_info_ul.scs_specific_carrier_list.resize(1); From f8c2f2bc52e5db2331aff1852001454a858a99f8 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 6 Oct 2021 17:19:20 +0200 Subject: [PATCH 024/208] enb,rrc_nr: also make sure to send UL freq band list item --- srsenb/src/stack/rrc/rrc_nr.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index e49493c99..fc8fc7c7b 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -1044,6 +1044,7 @@ int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_freq_info_ { cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.freq_info_ul_present = true; auto& freq_info_ul = cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.freq_info_ul; + freq_info_ul.freq_band_list_present = true; freq_info_ul.freq_band_list.push_back(parent->cfg.cell_list[0].band); freq_info_ul.absolute_freq_point_a_present = true; freq_info_ul.absolute_freq_point_a = parent->cfg.cell_list[0].ul_absolute_freq_point_a; From 546f637f917af8c7f355a3258fced70db4f6bdae Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 6 Oct 2021 17:20:49 +0200 Subject: [PATCH 025/208] rrc_endc: increase max_report_cells to 8 make sure that both EUTRA and NR cells fit in report --- srsenb/src/stack/rrc/rrc_endc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index 22a77614a..8a1ad789e 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -91,7 +91,7 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn report_cfg.report_cfg.report_cfg_inter_rat().trigger_type.event().hysteresis = 0; report_cfg.report_cfg.report_cfg_inter_rat().trigger_type.event().time_to_trigger = time_to_trigger_opts::ms100; - report_cfg.report_cfg.report_cfg_inter_rat().max_report_cells = 1; + report_cfg.report_cfg.report_cfg_inter_rat().max_report_cells = 8; report_cfg.report_cfg.report_cfg_inter_rat().report_interv = report_interv_opts::ms120; report_cfg.report_cfg.report_cfg_inter_rat().report_amount = report_cfg_inter_rat_s::report_amount_opts::r1; report_cfg.report_cfg.report_cfg_inter_rat().report_quant_cell_nr_r15.set_present(true); From b060c3deca7a40190d8ca456c87d1a7821132856 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 6 Oct 2021 17:03:54 +0200 Subject: [PATCH 026/208] Add possible band when invalid band is given --- srsenb/src/enb_cfg_parser.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 13121027b..c3c17694a 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -1022,6 +1022,17 @@ static int parse_nr_cell_list(all_args_t* args, rrc_nr_cfg_t* rrc_cfg_nr, rrc_cf } } if (!dl_arfcn_valid) { + if (not bands.empty()) { + std::stringstream ss; + for (uint32_t& band : bands) { + ss << band << " "; + } + ERROR("DL ARFCN (%d) does not belong to band (%d). Recommended bands: %s", + it->dl_arfcn, + it->band, + ss.str().c_str()); + return SRSRAN_ERROR; + } ERROR("DL ARFCN (%d) is not valid for the specified band (%d)", it->dl_arfcn, it->band); return SRSRAN_ERROR; } From cda4275ed0fe6766e7665c4b9589e06f463305bc Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 6 Oct 2021 15:46:24 +0100 Subject: [PATCH 027/208] sched,nr: disable simultaneous RAR and SSB until the PHY supports it --- .../src/stack/mac/nr/sched_nr_grant_allocator.cc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc index 512ee7e0a..8e9ba1a07 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc @@ -93,9 +93,15 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t static const uint32_t msg3_nof_prbs = 3, m = 0; bwp_slot_grid& bwp_pdcch_slot = bwp_grid[pdcch_slot]; - slot_point msg3_slot = pdcch_slot + cfg.pusch_ra_list[m].msg3_delay; - bwp_slot_grid& bwp_msg3_slot = bwp_grid[msg3_slot]; - alloc_result ret = verify_pusch_space(bwp_msg3_slot, nullptr); + if (not bwp_pdcch_slot.ssb.empty()) { + // TODO: support concurrent PDSCH and SSB + logger.info("SCHED: skipping ra-rnti=0x%x RAR allocation. Cause: concurrent PDSCH and SSB not yet supported", + ra_rnti); + return alloc_result::no_sch_space; + } + slot_point msg3_slot = pdcch_slot + cfg.pusch_ra_list[m].msg3_delay; + bwp_slot_grid& bwp_msg3_slot = bwp_grid[msg3_slot]; + alloc_result ret = verify_pusch_space(bwp_msg3_slot, nullptr); if (ret != alloc_result::success) { return ret; } @@ -197,7 +203,7 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr } bwp_slot_grid& bwp_pdcch_slot = bwp_grid[ue.pdcch_slot]; bwp_slot_grid& bwp_pdsch_slot = bwp_grid[ue.pdsch_slot]; - bwp_slot_grid& bwp_uci_slot = bwp_grid[ue.uci_slot]; // UCI : UL control info + bwp_slot_grid& bwp_uci_slot = bwp_grid[ue.uci_slot]; // UCI : UL control info alloc_result result = verify_pdsch_space(bwp_pdsch_slot, bwp_pdcch_slot); if (result != alloc_result::success) { return result; From a066236a9637dbdbab5fe3ac37be7e56bfc7e060 Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 6 Oct 2021 17:00:12 +0100 Subject: [PATCH 028/208] rrc,nr: disable NZP-CSI for FDD --- srsenb/src/stack/rrc/nr/cell_asn1_config.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc index e54cfee2f..d5e2d9689 100644 --- a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc +++ b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc @@ -222,7 +222,10 @@ int fill_csi_meas_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas // } // Fill NZP-CSI Resources - fill_nzp_csi_rs_from_enb_cfg(cfg, csi_meas_cfg); + if (cfg.cell_list[0].duplex_mode != SRSRAN_DUPLEX_MODE_FDD) { + // TODO: Support nzp-csi for FDD + fill_nzp_csi_rs_from_enb_cfg(cfg, csi_meas_cfg); + } // CSI IM config // TODO: add csi im config From b0430ebfe223415aa0bbfa243daad87234f28626 Mon Sep 17 00:00:00 2001 From: Robert Falkenberg Date: Wed, 6 Oct 2021 14:53:27 +0200 Subject: [PATCH 029/208] rf_imp.c: fix segfault when closing RF device with no AGC thread --- lib/src/phy/rf/rf_imp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/src/phy/rf/rf_imp.c b/lib/src/phy/rf/rf_imp.c index bccfe5758..f7b55a502 100644 --- a/lib/src/phy/rf/rf_imp.c +++ b/lib/src/phy/rf/rf_imp.c @@ -181,7 +181,9 @@ int srsran_rf_close(srsran_rf_t* rf) } pthread_mutex_unlock(&rf->mutex); pthread_cond_signal(&rf->cond); - pthread_join(rf->thread_gain, NULL); + if (rf->thread_gain) { + pthread_join(rf->thread_gain, NULL); + } return ((rf_dev_t*)rf->dev)->srsran_rf_close(rf->handler); } From 850606f20b3d297459e1f24201c75f5ba546658f Mon Sep 17 00:00:00 2001 From: Bedran Karakoc Date: Mon, 20 Sep 2021 06:40:30 +0200 Subject: [PATCH 030/208] Added deregistration (UE terminating) --- .../srsran/interfaces/gnb_rrc_nr_interfaces.h | 1 + srsenb/hdr/stack/ngap/ngap_interfaces.h | 7 +- srsenb/hdr/stack/ngap/ngap_ue.h | 2 + .../hdr/stack/ngap/ngap_ue_bearer_manager.h | 2 + srsenb/hdr/stack/ngap/ngap_ue_proc.h | 8 ++- srsenb/hdr/stack/rrc/rrc_nr.h | 1 + srsenb/src/stack/ngap/ngap.cc | 13 +++- srsenb/src/stack/ngap/ngap_ue.cc | 26 ++++++- .../src/stack/ngap/ngap_ue_bearer_manager.cc | 9 +++ srsenb/src/stack/ngap/ngap_ue_proc.cc | 14 ++-- srsenb/src/stack/rrc/rrc_nr.cc | 5 ++ srsenb/test/ngap/ngap_test.cc | 1 + srsue/hdr/stack/upper/nas_5g.h | 7 +- srsue/src/stack/upper/nas_5g.cc | 70 ++++++++++++++++++- 14 files changed, 147 insertions(+), 19 deletions(-) diff --git a/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h b/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h index fba566f6c..883749d37 100644 --- a/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h @@ -29,6 +29,7 @@ public: virtual int establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid) = 0; virtual int allocate_lcid(uint16_t rnti) = 0; + virtual int release_bearers(uint16_t rnti) = 0; virtual void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) = 0; }; diff --git a/srsenb/hdr/stack/ngap/ngap_interfaces.h b/srsenb/hdr/stack/ngap/ngap_interfaces.h index 44cd77425..12dbf1975 100644 --- a/srsenb/hdr/stack/ngap/ngap_interfaces.h +++ b/srsenb/hdr/stack/ngap/ngap_interfaces.h @@ -21,9 +21,10 @@ class ngap_interface_ngap_proc public: virtual bool send_initial_ctxt_setup_response() = 0; virtual bool - send_pdu_session_resource_setup_response(uint16_t pdu_session_id, - uint32_t teid_out, - asn1::bounded_bitstring<1, 160, true, true> transport_layer_address) = 0; + send_pdu_session_resource_setup_response(uint16_t pdu_session_id, + uint32_t teid_out, + asn1::bounded_bitstring<1, 160, true, true> transport_layer_address) = 0; + virtual bool send_ue_ctxt_release_complete() = 0; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/ngap/ngap_ue.h b/srsenb/hdr/stack/ngap/ngap_ue.h index 77004fdc0..4515b1fef 100644 --- a/srsenb/hdr/stack/ngap/ngap_ue.h +++ b/srsenb/hdr/stack/ngap/ngap_ue.h @@ -44,6 +44,8 @@ public: bool send_pdu_session_resource_setup_response(uint16_t pdu_session_id, uint32_t teid_in, asn1::bounded_bitstring<1, 160, true, true> addr_in); + // TS 38.413 - Section 9.2.1.2 - UE Context Release Complete + bool send_ue_ctxt_release_complete(); // TS 38.413 - Section 9.2.2.1 - Initial Context Setup Request bool handle_initial_ctxt_setup_request(const asn1::ngap_nr::init_context_setup_request_s& msg); // TS 38.413 - Section 9.2.2.5 - UE Context Release Command diff --git a/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h b/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h index ed4c3bdeb..d54db909d 100644 --- a/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h +++ b/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h @@ -54,6 +54,8 @@ public: uint32_t& teid_in, asn1::ngap_nr::cause_c& cause); + int reset_pdu_sessions(uint16_t rnti); + private: gtpu_interface_rrc* gtpu = nullptr; rrc_interface_ngap_nr* rrc = nullptr; diff --git a/srsenb/hdr/stack/ngap/ngap_ue_proc.h b/srsenb/hdr/stack/ngap/ngap_ue_proc.h index 71ddd58a0..3d1cad5e1 100644 --- a/srsenb/hdr/stack/ngap/ngap_ue_proc.h +++ b/srsenb/hdr/stack/ngap/ngap_ue_proc.h @@ -16,12 +16,12 @@ #include "ngap_interfaces.h" #include "ngap_ue_utils.h" +#include "srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h" #include "srsran/asn1/asn1_utils.h" #include "srsran/asn1/ngap.h" #include "srsran/common/buffer_pool.h" #include "srsran/common/stack_procedure.h" #include "srsran/interfaces/gnb_rrc_nr_interfaces.h" -#include "srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h" #include #include @@ -57,6 +57,7 @@ public: explicit ngap_ue_ue_context_release_proc(ngap_interface_ngap_proc* parent_, rrc_interface_ngap_nr* rrc_, ngap_ue_ctxt_t* ue_ctxt, + ngap_ue_bearer_manager* bearer_manager, srslog::basic_logger& logger_); srsran::proc_outcome_t init(const asn1::ngap_nr::ue_context_release_cmd_s& msg); srsran::proc_outcome_t step(); @@ -64,8 +65,9 @@ public: private: ngap_ue_ctxt_t* ue_ctxt; - ngap_interface_ngap_proc* parent = nullptr; - rrc_interface_ngap_nr* rrc = nullptr; + ngap_interface_ngap_proc* parent = nullptr; + rrc_interface_ngap_nr* rrc = nullptr; + ngap_ue_bearer_manager* bearer_manager = nullptr; srslog::basic_logger& logger; }; diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index a680068be..4fa9b3bfb 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -95,6 +95,7 @@ public: int ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps); int start_security_mode_procedure(uint16_t rnti); int establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid); + int release_bearers(uint16_t rnti); void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu); int set_aggregate_max_bitrate(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates); int allocate_lcid(uint16_t rnti); diff --git a/srsenb/src/stack/ngap/ngap.cc b/srsenb/src/stack/ngap/ngap.cc index e3660d749..3b3d604bb 100644 --- a/srsenb/src/stack/ngap/ngap.cc +++ b/srsenb/src/stack/ngap/ngap.cc @@ -112,7 +112,7 @@ ngap::ngap(srsran::task_sched_handle task_sched_, ngap::~ngap() {} -int ngap::init(const ngap_args_t& args_, rrc_interface_ngap_nr* rrc_, gtpu_interface_rrc * gtpu_) +int ngap::init(const ngap_args_t& args_, rrc_interface_ngap_nr* rrc_, gtpu_interface_rrc* gtpu_) { rrc = rrc_; args = args_; @@ -537,14 +537,21 @@ bool ngap::handle_initial_ctxt_setup_request(const asn1::ngap_nr::init_context_s bool ngap::handle_ue_ctxt_release_cmd(const asn1::ngap_nr::ue_context_release_cmd_s& msg) { - // TODO: UE Context Release Command contains a list of ue_ngap_ids + const asn1::ngap_nr::ue_ngap_id_pair_s& ue_ngap_id_pair = msg.protocol_ies.ue_ngap_ids.value.ue_ngap_id_pair(); + + ue* u = handle_ngapmsg_ue_id(ue_ngap_id_pair.ran_ue_ngap_id, ue_ngap_id_pair.amf_ue_ngap_id); + if (u == nullptr) { + logger.warning("Can not find UE"); + return false; + } + + u->handle_ue_ctxt_release_cmd(msg); return true; } bool ngap::handle_ue_pdu_session_res_setup_request(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg) { - ue* u = handle_ngapmsg_ue_id(msg.protocol_ies.ran_ue_ngap_id.value.value, msg.protocol_ies.amf_ue_ngap_id.value.value); if (u == nullptr) { diff --git a/srsenb/src/stack/ngap/ngap_ue.cc b/srsenb/src/stack/ngap/ngap_ue.cc index 5fc7f5e86..b3fa39137 100644 --- a/srsenb/src/stack/ngap/ngap_ue.cc +++ b/srsenb/src/stack/ngap/ngap_ue.cc @@ -31,7 +31,7 @@ ngap::ue::ue(ngap* ngap_ptr_, ngap_ptr(ngap_ptr_), bearer_manager(rrc_ptr_, gtpu_ptr_, logger_), initial_context_setup_proc(this, rrc_ptr_, &ctxt, logger_), - ue_context_release_proc(this, rrc_ptr_, &ctxt, logger_), + ue_context_release_proc(this, rrc_ptr_, &ctxt, &bearer_manager, logger_), ue_pdu_session_res_setup_proc(this, rrc_ptr_, &ctxt, &bearer_manager, logger_) { ctxt.ran_ue_ngap_id = ngap_ptr->next_gnb_ue_ngap_id++; @@ -223,6 +223,30 @@ bool ngap::ue::send_pdu_session_resource_setup_response(uint16_t return ngap_ptr->sctp_send_ngap_pdu(tx_pdu, ctxt.rnti, "PDUSessionResourceSetupResponse"); } +bool ngap::ue::send_ue_ctxt_release_complete() +{ + if (not ngap_ptr->amf_connected) { + logger.warning("AMF not connected"); + return false; + } + + ngap_pdu_c tx_pdu; + tx_pdu.set_successful_outcome().load_info_obj(ASN1_NGAP_NR_ID_UE_CONTEXT_RELEASE); + ue_context_release_complete_s& container = tx_pdu.successful_outcome().value.ue_context_release_complete(); + + // userLocationInformationNR + container.protocol_ies.user_location_info.value.set_user_location_info_nr(); + container.protocol_ies.user_location_info.value.user_location_info_nr().nr_cgi.nrcell_id = ngap_ptr->nr_cgi.nrcell_id; + container.protocol_ies.user_location_info.value.user_location_info_nr().nr_cgi.plmn_id = ngap_ptr->nr_cgi.plmn_id; + container.protocol_ies.user_location_info.value.user_location_info_nr().tai.plmn_id = ngap_ptr->tai.plmn_id; + container.protocol_ies.user_location_info.value.user_location_info_nr().tai.tac = ngap_ptr->tai.tac; + + container.protocol_ies.ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; + container.protocol_ies.amf_ue_ngap_id.value = ctxt.amf_ue_ngap_id.value(); + + return ngap_ptr->sctp_send_ngap_pdu(tx_pdu, ctxt.rnti, "UEContextReleaseComplete"); +} + /******************************************************************************* /* NGAP message handler ********************************************************************************/ diff --git a/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc b/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc index 19c71526f..57e776f8d 100644 --- a/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc +++ b/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc @@ -61,6 +61,15 @@ int ngap_ue_bearer_manager::add_pdu_session(uint16_t return SRSRAN_SUCCESS; } +int ngap_ue_bearer_manager::reset_pdu_sessions(uint16_t rnti) +{ + for (auto iter = pdu_session_list.begin(); iter != pdu_session_list.end(); iter++) { + auto pdu_session_id = iter->first; + rem_gtpu_bearer(pdu_session_id, rnti); + } + return true; +} + int ngap_ue_bearer_manager::add_gtpu_bearer(uint16_t rnti, uint32_t lcid, uint32_t pdu_session_id, diff --git a/srsenb/src/stack/ngap/ngap_ue_proc.cc b/srsenb/src/stack/ngap/ngap_ue_proc.cc index ad61f8c6c..698beba11 100644 --- a/srsenb/src/stack/ngap/ngap_ue_proc.cc +++ b/srsenb/src/stack/ngap/ngap_ue_proc.cc @@ -66,19 +66,23 @@ proc_outcome_t ngap_ue_initial_context_setup_proc::step() ngap_ue_ue_context_release_proc::ngap_ue_ue_context_release_proc(ngap_interface_ngap_proc* parent_, rrc_interface_ngap_nr* rrc_, ngap_ue_ctxt_t* ue_ctxt_, + ngap_ue_bearer_manager* bearer_manager_, srslog::basic_logger& logger_) : logger(logger_) { - parent = parent_; - rrc = rrc_; - ue_ctxt = ue_ctxt_; + parent = parent_; + rrc = rrc_; + ue_ctxt = ue_ctxt_; + bearer_manager = bearer_manager_; }; proc_outcome_t ngap_ue_ue_context_release_proc::init(const asn1::ngap_nr::ue_context_release_cmd_s& msg) { - // ue_ngap_ids_c ue_ngap_ids = msg.protocol_ies.ue_ngap_ids.value; - // cause_c cause = msg.protocol_ies.cause.value; logger.info("Started %s", name()); + // TODO: How to approach erasing users ? + bearer_manager->reset_pdu_sessions(ue_ctxt->rnti); + rrc->release_bearers(ue_ctxt->rnti); + parent->send_initial_ctxt_setup_response(); return proc_outcome_t::success; } diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index fc8fc7c7b..9968128d8 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -450,6 +450,11 @@ int rrc_nr::establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran: return SRSRAN_SUCCESS; } +int rrc_nr::release_bearers(uint16_t rnti) +{ + return SRSRAN_SUCCESS; +} + int rrc_nr::allocate_lcid(uint16_t rnti) { return SRSRAN_SUCCESS; diff --git a/srsenb/test/ngap/ngap_test.cc b/srsenb/test/ngap/ngap_test.cc index 117ace1bb..8b6f8baf1 100644 --- a/srsenb/test/ngap/ngap_test.cc +++ b/srsenb/test/ngap/ngap_test.cc @@ -86,6 +86,7 @@ public: { return SRSRAN_SUCCESS; } + int release_bearers(uint16_t rnti) { return SRSRAN_SUCCESS; } int allocate_lcid(uint16_t rnti) { return SRSRAN_SUCCESS; } void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) {} }; diff --git a/srsue/hdr/stack/upper/nas_5g.h b/srsue/hdr/stack/upper/nas_5g.h index 27ebc2141..85083b890 100644 --- a/srsue/hdr/stack/upper/nas_5g.h +++ b/srsue/hdr/stack/upper/nas_5g.h @@ -80,7 +80,7 @@ private: srsran::nas_5g::nas_5gs_msg initial_registration_request_stored; - nas_args_t cfg = {}; + nas_args_t cfg = {}; mm5g_state_t state; // Security @@ -132,10 +132,12 @@ private: int send_pdu_session_establishment_request(uint32_t transaction_identity, uint16_t pdu_session_id, const pdu_session_cfg_t& pdu_session); + int send_deregistration_request_ue_originating(); void fill_security_caps(srsran::nas_5g::ue_security_capability_t& sec_caps); int apply_security_config(srsran::unique_byte_buffer_t& pdu, uint8_t sec_hdr_type); - + int handle_deregistration_accept_ue_originating( + srsran::nas_5g::deregistration_accept_ue_originating_t& deregistration_accept_ue_originating); // message handler int handle_registration_accept(srsran::nas_5g::registration_accept_t& registration_accept); int handle_registration_reject(srsran::nas_5g::registration_reject_t& registration_reject); @@ -168,6 +170,7 @@ private: int configure_pdu_session(uint16_t pdu_session_id); bool unestablished_pdu_sessions(); int get_unestablished_pdu_session(uint16_t& pdu_session_id, pdu_session_cfg_t& pdu_session_cfg); + int reset_pdu_sessions(); struct pdu_session_t { bool configured; diff --git a/srsue/src/stack/upper/nas_5g.cc b/srsue/src/stack/upper/nas_5g.cc index 660b87600..b28c58b4d 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -136,6 +136,7 @@ void nas_5g::run_tti() break; case mm5g_state_t::state_t::deregistered_initiated: logger.debug("UE detaching..."); + send_deregistration_request_ue_originating(); break; default: break; @@ -222,6 +223,9 @@ int nas_5g::write_pdu(srsran::unique_byte_buffer_t pdu) case msg_opts::options::dl_nas_transport: handle_dl_nas_transport(nas_msg.dl_nas_transport()); break; + case msg_opts::options::deregistration_accept_ue_originating: + handle_deregistration_accept_ue_originating(nas_msg.deregistration_accept_ue_originating()); + break; default: logger.error( "Not handling NAS message type: %s (0x%02x)", nas_msg.hdr.message_type.to_string(), nas_msg.hdr.message_type); @@ -587,6 +591,51 @@ int nas_5g::send_pdu_session_establishment_request(uint32_t tran return SRSRAN_SUCCESS; } +int nas_5g::send_deregistration_request_ue_originating() +{ + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (!pdu) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return SRSRAN_ERROR; + } + + logger.info("Generating Deregistration Request (UE Originating)"); + + nas_5gs_msg nas_msg; + deregistration_request_ue_originating_t& deregistration_request = nas_msg.set_deregistration_request_ue_originating(); + + // Note 5.5.2.2.2 : AMF does not send a Deregistration Accept NAS message if De-registration type IE indicates "switch + // off" + deregistration_request.de_registration_type.switch_off.value = + de_registration_type_t::switch_off_type_::options::normal_de_registration; + + mobile_identity_5gs_t::suci_s& suci = deregistration_request.mobile_identity_5gs.set_suci(); + suci.supi_format = mobile_identity_5gs_t::suci_s::supi_format_type_::options::imsi; + usim->get_home_mcc_bytes(suci.mcc.data(), suci.mcc.size()); + usim->get_home_mnc_bytes(suci.mnc.data(), suci.mnc.size()); + + deregistration_request.ng_ksi.nas_key_set_identifier.value = + key_set_identifier_t::nas_key_set_identifier_type_::options::no_key_is_available_or_reserved; + + if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { + logger.error("Failed to pack Deregistration Request (UE Originating)."); + return SRSRAN_ERROR; + } + + if (pcap != nullptr) { + pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); + } + + logger.info("Sending Deregistration Request (UE Originating)"); + rrc_nr->write_sdu(std::move(pdu)); + + reset_pdu_sessions(); + + // TODO: Delete / Reset context (ctxt & ctxt_5g) + + return SRSASN_SUCCESS; +} + // Message handler int nas_5g::handle_registration_accept(registration_accept_t& registration_accept) { @@ -797,6 +846,13 @@ int nas_5g::handle_n1_sm_information(std::vector payload_container_cont return SRSRAN_SUCCESS; } +int nas_5g::handle_deregistration_accept_ue_originating( + srsran::nas_5g::deregistration_accept_ue_originating_t& deregistration_accept_ue_originating) +{ + logger.info("Received Deregistration Request (UE Originating)"); + return SRSASN_SUCCESS; +} + /******************************************************************************* * NAS Timers ******************************************************************************/ @@ -823,7 +879,7 @@ int nas_5g::switch_on() int nas_5g::switch_off() { logger.info("Switching off"); - // TODO + state.set_deregistered_initiated(); return SRSRAN_SUCCESS; } @@ -847,6 +903,16 @@ int nas_5g::start_service_request() return SRSRAN_SUCCESS; } +int nas_5g::reset_pdu_sessions() +{ + for (auto pdu_session : pdu_sessions) { + pdu_session.established = false; + pdu_session.pdu_session_id = 0; + } + + return SRSRAN_SUCCESS; +} + /******************************************************************************* * Helpers ******************************************************************************/ @@ -905,7 +971,7 @@ void nas_5g::fill_security_caps(srsran::nas_5g::ue_security_capability_t& sec_ca } /******************************************************************************* - * Helpers for Session Management + * Helpers for Session Management ******************************************************************************/ int nas_5g::trigger_pdu_session_est() From ca08b18745eaceaa8a18327160d93105793842ae Mon Sep 17 00:00:00 2001 From: Bedran Karakoc Date: Mon, 20 Sep 2021 07:09:22 +0200 Subject: [PATCH 031/208] Pass pdu_session_id instead of lcid for mapping in GTPU --- srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h | 1 - srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc | 10 +++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h b/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h index d54db909d..1be0fa4e8 100644 --- a/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h +++ b/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h @@ -63,7 +63,6 @@ private: srslog::basic_logger& logger; int add_gtpu_bearer(uint16_t rnti, - uint32_t lcid, uint32_t pdu_session_id, uint32_t teid_out, asn1::bounded_bitstring<1, 160, true, true> address, diff --git a/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc b/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc index 57e776f8d..0cd113acf 100644 --- a/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc +++ b/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc @@ -30,9 +30,6 @@ int ngap_ue_bearer_manager::add_pdu_session(uint16_t uint32_t& teid_in, asn1::ngap_nr::cause_c& cause) { - // RRC call for QoS parameter and lcid <-> ID mapping - lcid = rrc->allocate_lcid(rnti); - // Only add session if gtpu was successful pdu_session_t::gtpu_tunnel tunnel; @@ -43,7 +40,7 @@ int ngap_ue_bearer_manager::add_pdu_session(uint16_t } // TODO: remove lcid and just use pdu_session_id and rnti as id for GTP tunnel - int rtn = add_gtpu_bearer(rnti, lcid, pdu_session_id, teid_out, addr_out, tunnel); + int rtn = add_gtpu_bearer(rnti, pdu_session_id, teid_out, addr_out, tunnel); if (rtn != SRSRAN_SUCCESS) { logger.error("Adding PDU Session ID=%d to GTPU", pdu_session_id); return SRSRAN_ERROR; @@ -71,7 +68,6 @@ int ngap_ue_bearer_manager::reset_pdu_sessions(uint16_t rnti) } int ngap_ue_bearer_manager::add_gtpu_bearer(uint16_t rnti, - uint32_t lcid, uint32_t pdu_session_id, uint32_t teid_out, asn1::bounded_bitstring<1, 160, true, true> address_out, @@ -80,7 +76,8 @@ int ngap_ue_bearer_manager::add_gtpu_bearer(uint16_t { // Initialize ERAB tunnel in GTPU right-away. DRBs are only created during RRC setup/reconf uint32_t addr_in; - srsran::expected rtn = gtpu->add_bearer(rnti, lcid, address_out.to_number(), teid_out, addr_in, props); + srsran::expected rtn = + gtpu->add_bearer(rnti, pdu_session_id, address_out.to_number(), teid_out, addr_in, props); if (rtn.is_error()) { logger.error("Failed adding pdu_session_id=%d to GTPU", pdu_session_id); return SRSRAN_ERROR; @@ -97,7 +94,6 @@ int ngap_ue_bearer_manager::add_gtpu_bearer(uint16_t logger.info("Added GTPU tunnel rnti 0x%04x, lcid %d, pdu_session_id=%d, teid_out %d, teid_in %d, address out 0x%x, " "address in 0x%x", rnti, - lcid, pdu_session_id, tunnel.teid_out, tunnel.teid_in, From 1adf67c559c5e2d9d8a1b8bba6ac0cdfca57bfdd Mon Sep 17 00:00:00 2001 From: Bedran Karakoc Date: Mon, 20 Sep 2021 08:00:51 +0200 Subject: [PATCH 032/208] Extend NAS failure causes --- srsue/src/stack/upper/nas_5g.cc | 39 +++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/srsue/src/stack/upper/nas_5g.cc b/srsue/src/stack/upper/nas_5g.cc index b28c58b4d..9e4d24c68 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -667,6 +667,29 @@ int nas_5g::handle_registration_accept(registration_accept_t& registration_accep int nas_5g::handle_registration_reject(registration_reject_t& registration_reject) { logger.info("Handling Registration Reject"); + + state.set_deregistered(mm5g_state_t::deregistered_substate_t::plmn_search); + + switch (registration_reject.cause_5gmm.cause_5gmm.value) { + case (cause_5gmm_t::cause_5gmm_type_::options::illegal_ue): + logger.error("Registration Reject: Illegal UE"); + break; + case (cause_5gmm_t::cause_5gmm_type_::options::plmn_not_allowed): + logger.error("Registration Reject: PLMN not allowed"); + break; + case (cause_5gmm_t::cause_5gmm_type_::options::ue_security_capabilities_mismatch): + logger.error("Registration Reject: UE security capabilities mismatch"); + break; + case (cause_5gmm_t::cause_5gmm_type_::options::mac_failure): + logger.error("Registration Reject: MAC Failure"); + break; + case (cause_5gmm_t::cause_5gmm_type_::options::maximum_number_of_pdu_sessions_reached_): + logger.error("Registration Reject: Maximum number of pdu sessions reached"); + break; + default: + logger.error("Unhandled Registration Reject cause"); + } + return SRSRAN_SUCCESS; } @@ -710,19 +733,27 @@ int nas_5g::handle_authentication_request(authentication_request_t& authenticati authentication_request.abba.abba_contents.size(), res_star, ctxt_5g.k_amf); + logger.info(ctxt_5g.k_amf, 32, "Generated k_amf:"); + + if (ctxt.ksi == authentication_request.ng_ksi.nas_key_set_identifier.value) { + send_authentication_failure(cause_5gmm_t::cause_5gmm_type_::ng_ksi_already_in_use, res); + return SRSRAN_ERROR; + } + if (auth_result == AUTH_OK) { logger.info("Network authentication successful"); send_authentication_response(res_star); logger.info(res_star, 16, "Generated res_star (%d):", 16); + } else if (auth_result == AUTH_FAILED) { + logger.error("Network authentication failure."); + send_authentication_failure(cause_5gmm_t::cause_5gmm_type::mac_failure, res); } else if (auth_result == AUTH_SYNCH_FAILURE) { logger.error("Network authentication synchronization failure."); - // send_authentication_failure(LIBLTE_MME_EMM_CAUSE_SYNCH_FAILURE, res); + send_authentication_failure(cause_5gmm_t::cause_5gmm_type::synch_failure, res); } else { - logger.warning("Network authentication failure"); - srsran::console("Warning: Network authentication failure\n"); - // send_authentication_failure(LIBLTE_MME_EMM_CAUSE_MAC_FAILURE, nullptr); + logger.error("Unhandled authentication failure cause"); } return SRSRAN_SUCCESS; From e8bcc0a61ee17f1a8231ce69c3eb7edd1582d342 Mon Sep 17 00:00:00 2001 From: Bedran Karakoc Date: Mon, 20 Sep 2021 08:28:15 +0200 Subject: [PATCH 033/208] Added handler for identity request and sender for identity response --- srsue/hdr/stack/upper/nas_5g.h | 1 + srsue/src/stack/upper/nas_5g.cc | 43 ++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/srsue/hdr/stack/upper/nas_5g.h b/srsue/hdr/stack/upper/nas_5g.h index 85083b890..1d724db9c 100644 --- a/srsue/hdr/stack/upper/nas_5g.h +++ b/srsue/hdr/stack/upper/nas_5g.h @@ -133,6 +133,7 @@ private: uint16_t pdu_session_id, const pdu_session_cfg_t& pdu_session); int send_deregistration_request_ue_originating(); + int send_identity_response(srsran::nas_5g::identity_type_5gs_t::identity_types_::options requested_identity_type); void fill_security_caps(srsran::nas_5g::ue_security_capability_t& sec_caps); int apply_security_config(srsran::unique_byte_buffer_t& pdu, uint8_t sec_hdr_type); diff --git a/srsue/src/stack/upper/nas_5g.cc b/srsue/src/stack/upper/nas_5g.cc index 9e4d24c68..8616bd375 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -636,6 +636,46 @@ int nas_5g::send_deregistration_request_ue_originating() return SRSASN_SUCCESS; } +int nas_5g::send_identity_response(srsran::nas_5g::identity_type_5gs_t::identity_types_::options identity_type) +{ + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (!pdu) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return SRSRAN_ERROR; + } + + logger.info("Generating Identity Response"); + + nas_5gs_msg nas_msg; + identity_response_t& identity_response = nas_msg.set_identity_response(); + if (identity_type == identity_type_5gs_t::identity_types::suci) { + srsran::nas_5g::mobile_identity_5gs_t::suci_s& suci = identity_response.mobile_identity.suci(); + suci.supi_format = mobile_identity_5gs_t::suci_s::supi_format_type_::options::imsi; + usim->get_home_mcc_bytes(suci.mcc.data(), suci.mcc.size()); + usim->get_home_mnc_bytes(suci.mnc.data(), suci.mnc.size()); + + suci.scheme_output.resize(5); + } + + else { + logger.error("Unhandled identity type for identity response"); + return SRSRAN_ERROR; + } + + if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { + logger.error("Failed to pack Identity Response."); + return SRSRAN_ERROR; + } + + if (pcap != nullptr) { + pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); + } + + rrc_nr->write_sdu(std::move(pdu)); + + return SRSRAN_SUCCESS; +} + // Message handler int nas_5g::handle_registration_accept(registration_accept_t& registration_accept) { @@ -735,7 +775,7 @@ int nas_5g::handle_authentication_request(authentication_request_t& authenticati ctxt_5g.k_amf); logger.info(ctxt_5g.k_amf, 32, "Generated k_amf:"); - + if (ctxt.ksi == authentication_request.ng_ksi.nas_key_set_identifier.value) { send_authentication_failure(cause_5gmm_t::cause_5gmm_type_::ng_ksi_already_in_use, res); return SRSRAN_ERROR; @@ -762,6 +802,7 @@ int nas_5g::handle_authentication_request(authentication_request_t& authenticati int nas_5g::handle_identity_request(identity_request_t& identity_request) { logger.info("Handling Identity Request"); + send_identity_response(identity_request.identity_type.type_of_identity.value); return SRSRAN_SUCCESS; } From a4cc9b6ca05b55ee0807041f685ceabb0113aa10 Mon Sep 17 00:00:00 2001 From: Bedran Karakoc Date: Mon, 20 Sep 2021 16:06:22 +0200 Subject: [PATCH 034/208] Fix handle_authentication_request and add handler for authentication reject --- srsue/hdr/stack/upper/nas_5g.h | 1 + srsue/src/stack/upper/nas_5g.cc | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/srsue/hdr/stack/upper/nas_5g.h b/srsue/hdr/stack/upper/nas_5g.h index 1d724db9c..c953cbf4a 100644 --- a/srsue/hdr/stack/upper/nas_5g.h +++ b/srsue/hdr/stack/upper/nas_5g.h @@ -143,6 +143,7 @@ private: int handle_registration_accept(srsran::nas_5g::registration_accept_t& registration_accept); int handle_registration_reject(srsran::nas_5g::registration_reject_t& registration_reject); int handle_authentication_request(srsran::nas_5g::authentication_request_t& authentication_request); + int handle_authentication_reject(srsran::nas_5g::authentication_reject_t& authentication_reject); int handle_identity_request(srsran::nas_5g::identity_request_t& identity_request); int handle_service_accept(srsran::nas_5g::service_accept_t& service_accept); int handle_service_reject(srsran::nas_5g::service_reject_t& service_reject); diff --git a/srsue/src/stack/upper/nas_5g.cc b/srsue/src/stack/upper/nas_5g.cc index 8616bd375..f70cdbfca 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -199,6 +199,9 @@ int nas_5g::write_pdu(srsran::unique_byte_buffer_t pdu) case msg_opts::options::registration_reject: handle_registration_reject(nas_msg.registration_reject()); break; + case msg_opts::options::authentication_reject: + handle_authentication_reject(nas_msg.authentication_reject()); + break; case msg_opts::options::authentication_request: handle_authentication_request(nas_msg.authentication_request()); break; @@ -403,7 +406,7 @@ int nas_5g::send_security_mode_complete(const srsran::nas_5g::security_mode_comm imeisv.imeisv[14] = ue_svn_oct1; imeisv.imeisv[15] = ue_svn_oct2; } - + // TODO: Save TMSI registration_request_t& modified_registration_request = initial_registration_request_stored.registration_request(); modified_registration_request.capability_5gmm_present = true; modified_registration_request.requested_nssai_present = true; @@ -475,7 +478,6 @@ int nas_5g::send_authentication_failure(const cause_5gmm_t::cause_5gmm_type_::op pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); } - logger.info("Sending Authentication Failure"); rrc_nr->write_sdu(std::move(pdu)); return SRSRAN_SUCCESS; @@ -776,11 +778,6 @@ int nas_5g::handle_authentication_request(authentication_request_t& authenticati logger.info(ctxt_5g.k_amf, 32, "Generated k_amf:"); - if (ctxt.ksi == authentication_request.ng_ksi.nas_key_set_identifier.value) { - send_authentication_failure(cause_5gmm_t::cause_5gmm_type_::ng_ksi_already_in_use, res); - return SRSRAN_ERROR; - } - if (auth_result == AUTH_OK) { logger.info("Network authentication successful"); send_authentication_response(res_star); @@ -799,6 +796,13 @@ int nas_5g::handle_authentication_request(authentication_request_t& authenticati return SRSRAN_SUCCESS; } +int nas_5g::handle_authentication_reject(srsran::nas_5g::authentication_reject_t& authentication_reject) +{ + logger.info("Handling Authentication Reject"); + state.set_deregistered(mm5g_state_t::deregistered_substate_t::plmn_search); + return SRSRAN_SUCCESS; +} + int nas_5g::handle_identity_request(identity_request_t& identity_request) { logger.info("Handling Identity Request"); From aaaaea0537bf0a1eb34f610fedc57896debd4e65 Mon Sep 17 00:00:00 2001 From: Bedran Karakoc Date: Mon, 20 Sep 2021 16:55:19 +0200 Subject: [PATCH 035/208] Fix logging string formatting --- srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc b/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc index 0cd113acf..7b1dccb5a 100644 --- a/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc +++ b/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc @@ -91,7 +91,7 @@ int ngap_ue_bearer_manager::add_gtpu_bearer(uint16_t tunnel.address_in.from_number(addr_in); tunnel.teid_in = rtn.value(); - logger.info("Added GTPU tunnel rnti 0x%04x, lcid %d, pdu_session_id=%d, teid_out %d, teid_in %d, address out 0x%x, " + logger.info("Added GTPU tunnel rnti 0x%04x, pdu_session_id=%d, teid_out %d, teid_in %d, address out 0x%x, " "address in 0x%x", rnti, pdu_session_id, From 441251bdd18983d3d72681d15630d9b3e62463b2 Mon Sep 17 00:00:00 2001 From: Bedran Karakoc Date: Thu, 23 Sep 2021 01:09:41 +0200 Subject: [PATCH 036/208] Remove unused parameter --- srsue/hdr/stack/upper/nas_5g.h | 3 +-- srsue/src/stack/upper/nas_5g.cc | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/srsue/hdr/stack/upper/nas_5g.h b/srsue/hdr/stack/upper/nas_5g.h index c953cbf4a..854bec922 100644 --- a/srsue/hdr/stack/upper/nas_5g.h +++ b/srsue/hdr/stack/upper/nas_5g.h @@ -125,8 +125,7 @@ private: int send_registration_request(); int send_authentication_response(const uint8_t res[16]); int send_security_mode_reject(const srsran::nas_5g::cause_5gmm_t::cause_5gmm_type_::options cause); - int send_authentication_failure(const srsran::nas_5g::cause_5gmm_t::cause_5gmm_type_::options cause, - const uint8_t* auth_fail_param); + int send_authentication_failure(const srsran::nas_5g::cause_5gmm_t::cause_5gmm_type_::options cause); int send_security_mode_complete(const srsran::nas_5g::security_mode_command_t& security_mode_command); int send_registration_complete(); int send_pdu_session_establishment_request(uint32_t transaction_identity, diff --git a/srsue/src/stack/upper/nas_5g.cc b/srsue/src/stack/upper/nas_5g.cc index f70cdbfca..3c607467b 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -457,8 +457,7 @@ int nas_5g::send_security_mode_complete(const srsran::nas_5g::security_mode_comm return SRSRAN_SUCCESS; } -int nas_5g::send_authentication_failure(const cause_5gmm_t::cause_5gmm_type_::options cause, - const uint8_t* auth_fail_param) +int nas_5g::send_authentication_failure(const cause_5gmm_t::cause_5gmm_type_::options cause) { unique_byte_buffer_t pdu = srsran::make_byte_buffer(); if (!pdu) { @@ -785,10 +784,10 @@ int nas_5g::handle_authentication_request(authentication_request_t& authenticati } else if (auth_result == AUTH_FAILED) { logger.error("Network authentication failure."); - send_authentication_failure(cause_5gmm_t::cause_5gmm_type::mac_failure, res); + send_authentication_failure(cause_5gmm_t::cause_5gmm_type::mac_failure); } else if (auth_result == AUTH_SYNCH_FAILURE) { logger.error("Network authentication synchronization failure."); - send_authentication_failure(cause_5gmm_t::cause_5gmm_type::synch_failure, res); + send_authentication_failure(cause_5gmm_t::cause_5gmm_type::synch_failure); } else { logger.error("Unhandled authentication failure cause"); } From 193ec4abfa4bdd90318bb101c520dc11d87a9761 Mon Sep 17 00:00:00 2001 From: Bedran Karakoc Date: Thu, 23 Sep 2021 02:31:47 +0200 Subject: [PATCH 037/208] Trigger switch_off in NAS --- srsue/hdr/stack/upper/nas_5g.h | 2 +- srsue/src/stack/upper/nas_5g.cc | 27 +++++++++++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/srsue/hdr/stack/upper/nas_5g.h b/srsue/hdr/stack/upper/nas_5g.h index 854bec922..dbd55b4dd 100644 --- a/srsue/hdr/stack/upper/nas_5g.h +++ b/srsue/hdr/stack/upper/nas_5g.h @@ -131,7 +131,7 @@ private: int send_pdu_session_establishment_request(uint32_t transaction_identity, uint16_t pdu_session_id, const pdu_session_cfg_t& pdu_session); - int send_deregistration_request_ue_originating(); + int send_deregistration_request_ue_originating(bool switch_off); int send_identity_response(srsran::nas_5g::identity_type_5gs_t::identity_types_::options requested_identity_type); void fill_security_caps(srsran::nas_5g::ue_security_capability_t& sec_caps); diff --git a/srsue/src/stack/upper/nas_5g.cc b/srsue/src/stack/upper/nas_5g.cc index 3c607467b..60585c114 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -24,7 +24,6 @@ #include #include -#include #include #define MAC_5G_OFFSET 2 @@ -135,8 +134,6 @@ void nas_5g::run_tti() case mm5g_state_t::state_t::registered: break; case mm5g_state_t::state_t::deregistered_initiated: - logger.debug("UE detaching..."); - send_deregistration_request_ue_originating(); break; default: break; @@ -592,7 +589,7 @@ int nas_5g::send_pdu_session_establishment_request(uint32_t tran return SRSRAN_SUCCESS; } -int nas_5g::send_deregistration_request_ue_originating() +int nas_5g::send_deregistration_request_ue_originating(bool switch_off) { unique_byte_buffer_t pdu = srsran::make_byte_buffer(); if (!pdu) { @@ -607,13 +604,22 @@ int nas_5g::send_deregistration_request_ue_originating() // Note 5.5.2.2.2 : AMF does not send a Deregistration Accept NAS message if De-registration type IE indicates "switch // off" - deregistration_request.de_registration_type.switch_off.value = - de_registration_type_t::switch_off_type_::options::normal_de_registration; + if (switch_off) { + deregistration_request.de_registration_type.switch_off.value = + de_registration_type_t::switch_off_type_::options::switch_off; + state.set_deregistered(mm5g_state_t::deregistered_substate_t::null); + } else { + deregistration_request.de_registration_type.switch_off.value = + de_registration_type_t::switch_off_type_::options::normal_de_registration; + // In this case we need to wait for the response by the core + state.set_deregistered_initiated(); + } mobile_identity_5gs_t::suci_s& suci = deregistration_request.mobile_identity_5gs.set_suci(); suci.supi_format = mobile_identity_5gs_t::suci_s::supi_format_type_::options::imsi; usim->get_home_mcc_bytes(suci.mcc.data(), suci.mcc.size()); usim->get_home_mnc_bytes(suci.mnc.data(), suci.mnc.size()); + suci.scheme_output.resize(5); deregistration_request.ng_ksi.nas_key_set_identifier.value = key_set_identifier_t::nas_key_set_identifier_type_::options::no_key_is_available_or_reserved; @@ -924,7 +930,12 @@ int nas_5g::handle_n1_sm_information(std::vector payload_container_cont int nas_5g::handle_deregistration_accept_ue_originating( srsran::nas_5g::deregistration_accept_ue_originating_t& deregistration_accept_ue_originating) { - logger.info("Received Deregistration Request (UE Originating)"); + logger.info("Received Deregistration Accept (UE Originating)"); + if (state.get_state() != mm5g_state_t::state_t::deregistered_initiated) { + logger.warning("Received deregistration accept while not in deregistered initiated state"); + } + + state.set_deregistered(mm5g_state_t::deregistered_substate_t::null); return SRSASN_SUCCESS; } @@ -954,7 +965,7 @@ int nas_5g::switch_on() int nas_5g::switch_off() { logger.info("Switching off"); - state.set_deregistered_initiated(); + send_deregistration_request_ue_originating(true); return SRSRAN_SUCCESS; } From de750fad09ccd143ec6d41be73b83114585d25c1 Mon Sep 17 00:00:00 2001 From: Bedran Karakoc Date: Thu, 23 Sep 2021 04:22:10 +0200 Subject: [PATCH 038/208] Added helper function for replayed security capabilities --- srsue/hdr/stack/upper/nas_5g.h | 7 +++++-- srsue/src/stack/upper/nas_5g.cc | 37 +++++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/srsue/hdr/stack/upper/nas_5g.h b/srsue/hdr/stack/upper/nas_5g.h index dbd55b4dd..6c1a4e120 100644 --- a/srsue/hdr/stack/upper/nas_5g.h +++ b/srsue/hdr/stack/upper/nas_5g.h @@ -134,10 +134,11 @@ private: int send_deregistration_request_ue_originating(bool switch_off); int send_identity_response(srsran::nas_5g::identity_type_5gs_t::identity_types_::options requested_identity_type); + // Helper functions void fill_security_caps(srsran::nas_5g::ue_security_capability_t& sec_caps); int apply_security_config(srsran::unique_byte_buffer_t& pdu, uint8_t sec_hdr_type); - int handle_deregistration_accept_ue_originating( - srsran::nas_5g::deregistration_accept_ue_originating_t& deregistration_accept_ue_originating); + bool check_replayed_ue_security_capabilities(srsran::nas_5g::ue_security_capability_t& caps); + // message handler int handle_registration_accept(srsran::nas_5g::registration_accept_t& registration_accept); int handle_registration_reject(srsran::nas_5g::registration_reject_t& registration_reject); @@ -150,6 +151,8 @@ private: srsran::unique_byte_buffer_t pdu); int handle_deregistration_accept_ue_terminated( srsran::nas_5g::deregistration_accept_ue_terminated_t& deregistration_accept_ue_terminated); + int handle_deregistration_accept_ue_originating( + srsran::nas_5g::deregistration_accept_ue_originating_t& deregistration_accept_ue_originating); int handle_deregistration_request_ue_terminated( srsran::nas_5g::deregistration_request_ue_terminated_t& deregistration_request_ue_terminated); int handle_configuration_update_command(srsran::nas_5g::configuration_update_command_t& configuration_update_command); diff --git a/srsue/src/stack/upper/nas_5g.cc b/srsue/src/stack/upper/nas_5g.cc index 60585c114..a62a36b1f 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -836,11 +836,10 @@ int nas_5g::handle_security_mode_command(security_mode_command_t& security_m ctxt.integ_algo = (INTEGRITY_ALGORITHM_ID_ENUM) security_mode_command.selected_nas_security_algorithms.integrity_protection_algorithm.value; - // Check capabilities - // TODO: Check replayed sec capabilities - if (!ea5g_caps[ctxt.cipher_algo] || !ia5g_caps[ctxt.integ_algo]) { + // Check replayed ue security capabilities + if (!check_replayed_ue_security_capabilities(security_mode_command.replayed_ue_security_capabilities)) { logger.warning("Sending Security Mode Reject due to security capabilities mismatch"); - send_security_mode_reject(cause_5gmm_t::cause_5gmm_type_::options::ue_security_capabilities_mismatch); + send_security_mode_reject(cause_5gmm_t::cause_5gmm_type_::ue_security_capabilities_mismatch); return SRSRAN_ERROR; } @@ -1056,6 +1055,36 @@ void nas_5g::fill_security_caps(srsran::nas_5g::ue_security_capability_t& sec_ca } } +bool nas_5g::check_replayed_ue_security_capabilities(srsran::nas_5g::ue_security_capability_t& caps) +{ + if (caps.ia0_5g_supported != ia5g_caps[0] || caps.ea0_5g_supported != ea5g_caps[0]) { + return false; + } + if (caps.ia1_128_5g_supported != ia5g_caps[1] || caps.ea1_128_5g_supported != ea5g_caps[1]) { + return false; + } + if (caps.ia2_128_5g_supported != ia5g_caps[2] || caps.ea2_128_5g_supported != ea5g_caps[2]) { + return false; + } + if (caps.ia3_128_5g_supported != ia5g_caps[3] || caps.ea3_128_5g_supported != ea5g_caps[3]) { + return false; + } + if (caps.ia4_5g_supported != ia5g_caps[4] || caps.ea4_5g_supported != ea5g_caps[4]) { + return false; + } + if (caps.ia5_5g_supported != ia5g_caps[5] || caps.ea5_5g_supported != ea5g_caps[5]) { + return false; + } + if (caps.ia6_5g_supported != ia5g_caps[6] || caps.ea6_5g_supported != ea5g_caps[6]) { + return false; + } + if (caps.ia7_5g_supported != ia5g_caps[7] || caps.ea7_5g_supported != ea5g_caps[7]) { + return false; + } + + return true; +} + /******************************************************************************* * Helpers for Session Management ******************************************************************************/ From 361ff3f37afe4ba8c78c1f78f431634fd1b3de0f Mon Sep 17 00:00:00 2001 From: Bedran Karakoc Date: Thu, 23 Sep 2021 05:09:14 +0200 Subject: [PATCH 039/208] Extend identity type handling in Identity Response --- srsue/src/stack/upper/nas_5g.cc | 39 +++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/srsue/src/stack/upper/nas_5g.cc b/srsue/src/stack/upper/nas_5g.cc index a62a36b1f..74ebe1fcf 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -655,18 +655,33 @@ int nas_5g::send_identity_response(srsran::nas_5g::identity_type_5gs_t::identity nas_5gs_msg nas_msg; identity_response_t& identity_response = nas_msg.set_identity_response(); - if (identity_type == identity_type_5gs_t::identity_types::suci) { - srsran::nas_5g::mobile_identity_5gs_t::suci_s& suci = identity_response.mobile_identity.suci(); - suci.supi_format = mobile_identity_5gs_t::suci_s::supi_format_type_::options::imsi; - usim->get_home_mcc_bytes(suci.mcc.data(), suci.mcc.size()); - usim->get_home_mnc_bytes(suci.mnc.data(), suci.mnc.size()); - - suci.scheme_output.resize(5); - } - - else { - logger.error("Unhandled identity type for identity response"); - return SRSRAN_ERROR; + + switch (identity_type) { + case (identity_type_5gs_t::identity_types_::suci): { + srsran::nas_5g::mobile_identity_5gs_t::suci_s& suci = identity_response.mobile_identity.set_suci(); + suci.supi_format = mobile_identity_5gs_t::suci_s::supi_format_type_::options::imsi; + usim->get_home_mcc_bytes(suci.mcc.data(), suci.mcc.size()); + usim->get_home_mnc_bytes(suci.mnc.data(), suci.mnc.size()); + suci.scheme_output.resize(5); + usim->get_home_msin_bcd(suci.scheme_output.data(), 5); + } break; + case (identity_type_5gs_t::identity_types_::guti_5g): { + srsran::nas_5g::mobile_identity_5gs_t::guti_5g_s& guti = identity_response.mobile_identity.set_guti_5g(); + guti = guti_5g; + } break; + case (identity_type_5gs_t::identity_types_::imei): { + srsran::nas_5g::mobile_identity_5gs_t::imei_s& imei = identity_response.mobile_identity.set_imei(); + usim->get_imei_vec(imei.imei.data(), 15); + } break; + case (identity_type_5gs_t::identity_types_::imeisv): { + srsran::nas_5g::mobile_identity_5gs_t::imeisv_s& imeisv = identity_response.mobile_identity.set_imeisv(); + usim->get_imei_vec(imeisv.imeisv.data(), 15); + imeisv.imeisv[14] = ue_svn_oct1; + imeisv.imeisv[15] = ue_svn_oct2; + } break; + default: + logger.warning("Unhandled identity type for identity response"); + return SRSRAN_ERROR; } if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { From 1e1e1420b13461dc4d33875338abba87e49ea9a4 Mon Sep 17 00:00:00 2001 From: Bedran Karakoc Date: Fri, 1 Oct 2021 19:08:53 +0200 Subject: [PATCH 040/208] Return AUTS in authentication failure for case AUTH_SYNCH_FAILURE --- srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h | 3 +-- srsenb/src/stack/ngap/ngap_ue.cc | 2 +- srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc | 6 ++---- srsenb/src/stack/ngap/ngap_ue_proc.cc | 2 +- srsue/hdr/stack/upper/nas_5g.h | 2 +- srsue/src/stack/upper/nas_5g.cc | 15 +++++++++++---- srsue/src/stack/upper/pcsc_usim.cc | 4 ++-- 7 files changed, 19 insertions(+), 15 deletions(-) diff --git a/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h b/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h index 1be0fa4e8..91f2d9855 100644 --- a/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h +++ b/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h @@ -41,7 +41,7 @@ public: std::vector tunnels; }; - ngap_ue_bearer_manager(rrc_interface_ngap_nr* rrc_, gtpu_interface_rrc* gtpu_, srslog::basic_logger& logger_); + ngap_ue_bearer_manager(gtpu_interface_rrc* gtpu_, srslog::basic_logger& logger_); ~ngap_ue_bearer_manager(); int add_pdu_session(uint16_t rnti, @@ -58,7 +58,6 @@ public: private: gtpu_interface_rrc* gtpu = nullptr; - rrc_interface_ngap_nr* rrc = nullptr; std::map pdu_session_list; srslog::basic_logger& logger; diff --git a/srsenb/src/stack/ngap/ngap_ue.cc b/srsenb/src/stack/ngap/ngap_ue.cc index b3fa39137..875b784d6 100644 --- a/srsenb/src/stack/ngap/ngap_ue.cc +++ b/srsenb/src/stack/ngap/ngap_ue.cc @@ -29,7 +29,7 @@ ngap::ue::ue(ngap* ngap_ptr_, srslog::basic_logger& logger_) : logger(logger_), ngap_ptr(ngap_ptr_), - bearer_manager(rrc_ptr_, gtpu_ptr_, logger_), + bearer_manager(gtpu_ptr_, logger_), initial_context_setup_proc(this, rrc_ptr_, &ctxt, logger_), ue_context_release_proc(this, rrc_ptr_, &ctxt, &bearer_manager, logger_), ue_pdu_session_res_setup_proc(this, rrc_ptr_, &ctxt, &bearer_manager, logger_) diff --git a/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc b/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc index 7b1dccb5a..68944c3d6 100644 --- a/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc +++ b/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc @@ -13,10 +13,8 @@ #include "srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h" namespace srsenb { -ngap_ue_bearer_manager::ngap_ue_bearer_manager(rrc_interface_ngap_nr* rrc_, - gtpu_interface_rrc* gtpu_, - srslog::basic_logger& logger_) : - gtpu(gtpu_), rrc(rrc_), logger(logger_) +ngap_ue_bearer_manager::ngap_ue_bearer_manager(gtpu_interface_rrc* gtpu_, srslog::basic_logger& logger_) : + gtpu(gtpu_), logger(logger_) {} ngap_ue_bearer_manager::~ngap_ue_bearer_manager(){}; diff --git a/srsenb/src/stack/ngap/ngap_ue_proc.cc b/srsenb/src/stack/ngap/ngap_ue_proc.cc index 698beba11..750cf5ac9 100644 --- a/srsenb/src/stack/ngap/ngap_ue_proc.cc +++ b/srsenb/src/stack/ngap/ngap_ue_proc.cc @@ -82,7 +82,7 @@ proc_outcome_t ngap_ue_ue_context_release_proc::init(const asn1::ngap_nr::ue_con // TODO: How to approach erasing users ? bearer_manager->reset_pdu_sessions(ue_ctxt->rnti); rrc->release_bearers(ue_ctxt->rnti); - parent->send_initial_ctxt_setup_response(); + parent->send_ue_ctxt_release_complete(); return proc_outcome_t::success; } diff --git a/srsue/hdr/stack/upper/nas_5g.h b/srsue/hdr/stack/upper/nas_5g.h index 6c1a4e120..3278ddad8 100644 --- a/srsue/hdr/stack/upper/nas_5g.h +++ b/srsue/hdr/stack/upper/nas_5g.h @@ -125,7 +125,7 @@ private: int send_registration_request(); int send_authentication_response(const uint8_t res[16]); int send_security_mode_reject(const srsran::nas_5g::cause_5gmm_t::cause_5gmm_type_::options cause); - int send_authentication_failure(const srsran::nas_5g::cause_5gmm_t::cause_5gmm_type_::options cause); + int send_authentication_failure(const srsran::nas_5g::cause_5gmm_t::cause_5gmm_type_::options cause, const uint8_t res_star[16]); int send_security_mode_complete(const srsran::nas_5g::security_mode_command_t& security_mode_command); int send_registration_complete(); int send_pdu_session_establishment_request(uint32_t transaction_identity, diff --git a/srsue/src/stack/upper/nas_5g.cc b/srsue/src/stack/upper/nas_5g.cc index 74ebe1fcf..4e226b2b8 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -454,7 +454,7 @@ int nas_5g::send_security_mode_complete(const srsran::nas_5g::security_mode_comm return SRSRAN_SUCCESS; } -int nas_5g::send_authentication_failure(const cause_5gmm_t::cause_5gmm_type_::options cause) +int nas_5g::send_authentication_failure(const cause_5gmm_t::cause_5gmm_type_::options cause, const uint8_t res[16]) { unique_byte_buffer_t pdu = srsran::make_byte_buffer(); if (!pdu) { @@ -464,6 +464,13 @@ int nas_5g::send_authentication_failure(const cause_5gmm_t::cause_5gmm_type_::op nas_5gs_msg nas_msg; authentication_failure_t& auth_fail = nas_msg.set_authentication_failure(); + auth_fail.cause_5gmm.cause_5gmm = cause; + + if (cause == cause_5gmm_t::cause_5gmm_type::synch_failure) { + auth_fail.authentication_failure_parameter_present = true; + auth_fail.authentication_failure_parameter.auth_failure.resize(14); + memcpy(auth_fail.authentication_failure_parameter.auth_failure.data(), res, 14); + } if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { logger.error("Failed to pack authentication failure."); @@ -655,7 +662,7 @@ int nas_5g::send_identity_response(srsran::nas_5g::identity_type_5gs_t::identity nas_5gs_msg nas_msg; identity_response_t& identity_response = nas_msg.set_identity_response(); - + switch (identity_type) { case (identity_type_5gs_t::identity_types_::suci): { srsran::nas_5g::mobile_identity_5gs_t::suci_s& suci = identity_response.mobile_identity.set_suci(); @@ -805,10 +812,10 @@ int nas_5g::handle_authentication_request(authentication_request_t& authenticati } else if (auth_result == AUTH_FAILED) { logger.error("Network authentication failure."); - send_authentication_failure(cause_5gmm_t::cause_5gmm_type::mac_failure); + send_authentication_failure(cause_5gmm_t::cause_5gmm_type::mac_failure, res_star); } else if (auth_result == AUTH_SYNCH_FAILURE) { logger.error("Network authentication synchronization failure."); - send_authentication_failure(cause_5gmm_t::cause_5gmm_type::synch_failure); + send_authentication_failure(cause_5gmm_t::cause_5gmm_type::synch_failure, res_star); } else { logger.error("Unhandled authentication failure cause"); } diff --git a/srsue/src/stack/upper/pcsc_usim.cc b/srsue/src/stack/upper/pcsc_usim.cc index 3cc963b1e..cded6369a 100644 --- a/srsue/src/stack/upper/pcsc_usim.cc +++ b/srsue/src/stack/upper/pcsc_usim.cc @@ -181,7 +181,7 @@ auth_result_t pcsc_usim::generate_authentication_response_5g(uint8_t* rand, case -2: logger.info("SCARD: USIM synchronization failure, AUTS generated"); logger.debug(auts, AKA_AUTS_LEN, "AUTS"); - memcpy(res, auts, AKA_AUTS_LEN); + memcpy(res_star, auts, AKA_AUTS_LEN); res_len = AKA_AUTS_LEN; return AUTH_SYNCH_FAILURE; default: @@ -213,7 +213,7 @@ auth_result_t pcsc_usim::generate_authentication_response_5g(uint8_t* rand, // Generate K_seaf security_generate_k_seaf(k_ausf, serving_network_name, k_seaf); logger.debug(k_seaf, 32, "K SEAF"); - // Generate K_seaf + // Generate K_amf security_generate_k_amf(k_ausf, imsi_str.c_str(), abba, abba_len, k_amf); logger.debug(k_amf, 32, "K AMF"); From 420d6a6a9860ddd16cb7533b9e2cf218251a1668 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Wed, 6 Oct 2021 17:23:50 +0200 Subject: [PATCH 041/208] enhanced and fixed some tests. --- lib/src/common/test/band_helper_test.cc | 28 ++++++++++++++----------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/lib/src/common/test/band_helper_test.cc b/lib/src/common/test/band_helper_test.cc index b59ff3977..2ef31ced7 100644 --- a/lib/src/common/test/band_helper_test.cc +++ b/lib/src/common/test/band_helper_test.cc @@ -33,27 +33,31 @@ int bands_test_nr() // n32 n75 TESTASSERT(bands.nr_arfcn_to_freq(290400) == 1452.0e6); TESTASSERT(bands.nr_arfcn_to_freq(294400) == 1472.0e6); - // n5 - TESTASSERT(bands.get_duplex_mode(5) == SRSRAN_DUPLEX_MODE_FDD); - TESTASSERT(bands.nr_arfcn_to_freq(176300) == 881.5e6); - TESTASSERT(bands.freq_to_nr_arfcn(881.5e6) == 176300); - TESTASSERT(bands.get_ul_arfcn_from_dl_arfcn(176300) == 167300); - TESTASSERT(bands.nr_arfcn_to_freq(167300) == 836.5e6); // check actual freqs for FDD carrier (example values are for 52 PRB) TESTASSERT(bands.get_center_freq_from_abs_freq_point_a(52, 175364) == 881.5e6); TESTASSERT(bands.get_center_freq_from_abs_freq_point_a(52, 166364) == 836.5e6); - - // n3 - TESTASSERT(bands.nr_arfcn_to_freq(342000) == 1710.0e6); - TESTASSERT(bands.nr_arfcn_to_freq(348000) == 1740.0e6); - TESTASSERT(bands.nr_arfcn_to_freq(361000) == 1805.0e6); - TESTASSERT(bands.nr_arfcn_to_freq(376000) == 1880.0e6); // n1 TESTASSERT(bands.nr_arfcn_to_freq(384000) == 1920.0e6); TESTASSERT(bands.nr_arfcn_to_freq(388030) == 1940.15e6); TESTASSERT(bands.nr_arfcn_to_freq(391830) == 1959.15e6); TESTASSERT(bands.nr_arfcn_to_freq(434000) == 2170.0e6); + // n3 + TESTASSERT(bands.get_duplex_mode(3) == SRSRAN_DUPLEX_MODE_FDD); + TESTASSERT(bands.nr_arfcn_to_freq(342000) == 1710.0e6); + TESTASSERT(bands.nr_arfcn_to_freq(348000) == 1740.0e6); + TESTASSERT(bands.nr_arfcn_to_freq(361000) == 1805.0e6); + TESTASSERT(bands.nr_arfcn_to_freq(376000) == 1880.0e6); + TESTASSERT(bands.get_abs_freq_point_a_arfcn(52, 368500) == 367564); + TESTASSERT(bands.get_abs_freq_ssb_arfcn(3, srsran_subcarrier_spacing_15kHz, 367564) > 367924); + // n5 + TESTASSERT(bands.get_duplex_mode(5) == SRSRAN_DUPLEX_MODE_FDD); + TESTASSERT(bands.nr_arfcn_to_freq(176300) == 881.5e6); + TESTASSERT(bands.freq_to_nr_arfcn(881.5e6) == 176300); + TESTASSERT(bands.get_ul_arfcn_from_dl_arfcn(176300) == 167300); + TESTASSERT(bands.nr_arfcn_to_freq(167300) == 836.5e6); + TESTASSERT(bands.get_abs_freq_point_a_arfcn(52, 176300) == 175364); + TESTASSERT(bands.get_abs_freq_ssb_arfcn(5, srsran_subcarrier_spacing_15kHz, 175364) > 175724); // n7 n38 TESTASSERT(bands.get_duplex_mode(7) == SRSRAN_DUPLEX_MODE_FDD); TESTASSERT(bands.nr_arfcn_to_freq(500000) == 2500.0e6); From 8fff7f664612c8e67ca5f00a75b6675ee060981a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 6 Oct 2021 15:30:06 +0200 Subject: [PATCH 042/208] Fix potential overflow in rssi_read_cnt --- srsue/src/phy/phy_common.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/phy/phy_common.cc b/srsue/src/phy/phy_common.cc index 244e0b160..18248166a 100644 --- a/srsue/src/phy/phy_common.cc +++ b/srsue/src/phy/phy_common.cc @@ -687,7 +687,7 @@ void phy_common::update_measurements(uint32_t cc_idx, rx_gain_offset = get_radio()->get_rx_gain() + args->rx_gain_offset; } rssi_read_cnt++; - if (rssi_read_cnt == 1000) { + if (rssi_read_cnt >= 1000) { rssi_read_cnt = 0; } } From 9d35c5d018963fa92037276ffd52df4364dcf590 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 7 Oct 2021 11:26:25 +0200 Subject: [PATCH 043/208] srsue: stop rx stream after finishing sync thread to avoid deadlock at stop --- srsue/src/phy/sync.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/sync.cc b/srsue/src/phy/sync.cc index 4209edeba..4d0f0cfe5 100644 --- a/srsue/src/phy/sync.cc +++ b/srsue/src/phy/sync.cc @@ -135,10 +135,10 @@ void sync::stop() } running = false; + wait_thread_finish(); + // Reset (stop Rx stream) as soon as possible to avoid base-band Rx buffer overflow radio_h->reset(); - - wait_thread_finish(); } void sync::reset() From 5c3f0a39eea8fef36781749a78e6336450ae1b7f Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 7 Oct 2021 11:43:49 +0100 Subject: [PATCH 044/208] sched,nr: set scheduler ue candidate logging to debug level --- srsenb/src/stack/mac/nr/sched_nr_helpers.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsenb/src/stack/mac/nr/sched_nr_helpers.cc b/srsenb/src/stack/mac/nr/sched_nr_helpers.cc index 086e223ef..a2905226c 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_helpers.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_helpers.cc @@ -114,7 +114,7 @@ void fill_ul_dci_ue_fields(const slot_ue& ue, void log_sched_slot_ues(srslog::basic_logger& logger, slot_point pdcch_slot, uint32_t cc, const slot_ue_map_t& slot_ues) { - if (not logger.info.enabled() or slot_ues.empty()) { + if (not logger.debug.enabled() or slot_ues.empty()) { return; } @@ -130,7 +130,7 @@ void log_sched_slot_ues(srslog::basic_logger& logger, slot_point pdcch_slot, uin use_comma = ", "; } - logger.info("%s]", srsran::to_c_str(fmtbuf)); + logger.debug("%s]", srsran::to_c_str(fmtbuf)); } void log_sched_bwp_result(srslog::basic_logger& logger, From 82ae0e6c37587a963fe80e0838f39d192621a887 Mon Sep 17 00:00:00 2001 From: Joaquim <89880406+joaquim-srs@users.noreply.github.com> Date: Thu, 7 Oct 2021 16:14:46 +0200 Subject: [PATCH 045/208] nr_phy test: add AWGN channel simulator, add High Speed Train channel (#3288) Add channel simulator to nr_phy tests. UL and DL channel simulators added, with AWGN and CFO using the HST scenario. The DL AWGN is adjusted according to signal power. --- srsue/src/phy/nr/cc_worker.cc | 5 ++- test/phy/CMakeLists.txt | 1 - test/phy/nr_phy_test.cc | 57 ++++++++++++++++++++++++----------- test/phy/test_bench.h | 25 +++++++++++++-- 4 files changed, 66 insertions(+), 22 deletions(-) diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index 25d126193..9d1f04e8e 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -344,7 +344,10 @@ bool cc_worker::decode_pdsch_dl() dl_m.evm = pdsch_res.evm[0]; phy.set_dl_metrics(dl_m); } - + ch_metrics_t ch_metrics = {}; + ch_metrics.sinr = ue_dl.chest.snr_db; + ch_metrics.sync_err = ue_dl.chest.sync_error; + phy.set_channel_metrics(ch_metrics); return true; } diff --git a/test/phy/CMakeLists.txt b/test/phy/CMakeLists.txt index 2e9ea2f3c..518a9b53c 100644 --- a/test/phy/CMakeLists.txt +++ b/test/phy/CMakeLists.txt @@ -35,7 +35,6 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} ${ATOMIC_LIBS}) - # For each supported bandwidth foreach (NR_PHY_TEST_BW "10MHz" "20MHz") # For each supported frame structure diff --git a/test/phy/nr_phy_test.cc b/test/phy/nr_phy_test.cc index bdf8d7222..b5df81698 100644 --- a/test/phy/nr_phy_test.cc +++ b/test/phy/nr_phy_test.cc @@ -43,11 +43,17 @@ test_bench::args_t::args_t(int argc, char** argv) // clang-format off options.add_options() - ("rnti", bpo::value(&rnti)->default_value(rnti), "UE RNTI") - ("duration", bpo::value(&durations_slots)->default_value(durations_slots), "Test duration in slots") - ("lib.log.level", bpo::value(&phy_lib_log_level)->default_value(phy_lib_log_level), "PHY librray log level") - ("reference", bpo::value(&reference_cfg_str)->default_value(reference_cfg_str), "Reference PHY configuration arguments") - ; + ("rnti", bpo::value(&rnti)->default_value(rnti), "UE RNTI") + ("duration", bpo::value(&durations_slots)->default_value(durations_slots), "Test duration in slots") + ("lib.log.level", bpo::value(&phy_lib_log_level)->default_value(phy_lib_log_level), "PHY librray log level") + ("reference", bpo::value(&reference_cfg_str)->default_value(reference_cfg_str), "Reference PHY configuration arguments") + ("dl_channel.awgn_enable", bpo::value(&dl_channel.awgn_enable)->default_value(dl_channel.awgn_enable), "DL Channel AWGN enable / disable") + ("dl_channel.awgn_snr", bpo::value(&dl_channel.awgn_snr_dB)->default_value(dl_channel.awgn_snr_dB), "DL Channel AWGN SNR in dB") + ("ul_channel.awgn_enable", bpo::value(&ul_channel.awgn_enable)->default_value(ul_channel.awgn_enable), "UL Channel AWGN enable / disable") + ("ul_channel.awgn_snr", bpo::value(&ul_channel.awgn_snr_dB)->default_value(ul_channel.awgn_snr_dB), "UL Channel AWGN SNR in dB") + ("ul_channel.signal_power_dBfs", bpo::value(&ul_channel.awgn_signal_power_dBfs)->default_value(ul_channel.awgn_signal_power_dBfs), "UL Channel expected signal power") + ("channel.cfo", bpo::value(&ul_channel.hst_fd_hz)->default_value(0), "Channel HST Doppler frequency") +; options_gnb_stack.add_options() ("gnb.stack.pdcch.aggregation_level", bpo::value(&gnb_stack.pdcch_aggregation_level)->default_value(gnb_stack.pdcch_aggregation_level), "PDCCH aggregation level") @@ -102,6 +108,11 @@ test_bench::args_t::args_t(int argc, char** argv) try { bpo::store(bpo::command_line_parser(argc, argv).options(options).run(), vm); bpo::notify(vm); + + // Apply the High Speed Train args to the DL channel as well + ul_channel.hst_enable = std::isnormal(ul_channel.hst_fd_hz); + dl_channel.hst_enable = ul_channel.hst_enable; + dl_channel.hst_fd_hz = ul_channel.hst_fd_hz; } catch (bpo::error& e) { std::cerr << e.what() << std::endl; return; @@ -117,6 +128,12 @@ test_bench::args_t::args_t(int argc, char** argv) // Load default reference configuration phy_cfg = srsran::phy_cfg_nr_default_t(srsran::phy_cfg_nr_default_t::reference_cfg_t(reference_cfg_str)); + // Calulate the DL signal power from the number of PRBs + dl_channel.awgn_signal_power_dBfs = srsran_gnb_dl_get_maximum_signal_power_dBfs(phy_cfg.carrier.nof_prb); + + // Reverses the Doppler shift for the UL + ul_channel.hst_init_time_s = 0.5 * dl_channel.hst_period_s; + // Calculate sampling rate in Hz srate_hz = (double)(srsran_min_symbol_sz_rb(phy_cfg.carrier.nof_prb) * SRSRAN_SUBC_SPACING_NR(phy_cfg.carrier.scs)); @@ -174,22 +191,26 @@ int main(int argc, char** argv) srslog::flush(); // Retrieve MAC metrics - test_bench::metrics_t metrics = tb.get_gnb_metrics(); + test_bench::metrics_t metrics = tb.get_metrics(); // Print PDSCH metrics if scheduled double pdsch_bler = 0.0; if (metrics.gnb_stack.mac.tx_pkts > 0) { pdsch_bler = (double)metrics.gnb_stack.mac.tx_errors / (double)metrics.gnb_stack.mac.tx_pkts; - float pdsch_shed_rate = 0.0f; - pdsch_shed_rate = (float)metrics.gnb_stack.mac.tx_brate / (float)metrics.gnb_stack.mac.tx_pkts / 1000.0f; + float pdsch_shed_rate = 0.0f; + pdsch_shed_rate = (float)metrics.gnb_stack.mac.tx_brate / (float)metrics.gnb_stack.mac.tx_pkts / 1000.0f; + float decode_iterations = metrics.ue_phy.dl[0].fec_iters; + float ue_snr = metrics.ue_phy.ch[0].sinr; srsran::console("PDSCH:\n"); - srsran::console(" Count: %d\n", metrics.gnb_stack.mac.tx_pkts); - srsran::console(" BLER: %f\n", pdsch_bler); - srsran::console(" Sched Rate: %f Mbps\n", pdsch_shed_rate); - srsran::console(" Net Rate: %f Mbps\n", (1.0f - pdsch_bler) * pdsch_shed_rate); - srsran::console(" Retx Rate: %f Mbps\n", pdsch_bler * pdsch_shed_rate); + srsran::console(" Count: %d\n", metrics.gnb_stack.mac.tx_pkts); + srsran::console(" BLER: %f\n", pdsch_bler); + srsran::console(" Sched Rate: %f Mbps\n", pdsch_shed_rate); + srsran::console(" Net Rate: %f Mbps\n", (1.0f - pdsch_bler) * pdsch_shed_rate); + srsran::console(" Retx Rate: %f Mbps\n", pdsch_bler * pdsch_shed_rate); + srsran::console(" Measured SNR: %f dB\n", ue_snr); + srsran::console(" Dec Iterations: %f\n", decode_iterations); srsran::console("\n"); } @@ -206,11 +227,11 @@ int main(int argc, char** argv) } srsran::console("PUSCH:\n"); - srsran::console(" Count: %d\n", metrics.gnb_stack.mac.rx_pkts); - srsran::console(" BLER: %f\n", pusch_bler); - srsran::console(" Sched Rate: %f Mbps\n", pusch_shed_rate); - srsran::console(" Net Rate: %f Mbps\n", (1.0f - pusch_bler) * pusch_shed_rate); - srsran::console(" Retx Rate: %f Mbps\n", pusch_bler * pusch_shed_rate); + srsran::console(" Count: %d\n", metrics.gnb_stack.mac.rx_pkts); + srsran::console(" BLER: %f\n", pusch_bler); + srsran::console(" Sched Rate: %f Mbps\n", pusch_shed_rate); + srsran::console(" Net Rate: %f Mbps\n", (1.0f - pusch_bler) * pusch_shed_rate); + srsran::console(" Retx Rate: %f Mbps\n", pusch_bler * pusch_shed_rate); srsran::console("\n"); } diff --git a/test/phy/test_bench.h b/test/phy/test_bench.h index 8269652c3..bd169475c 100644 --- a/test/phy/test_bench.h +++ b/test/phy/test_bench.h @@ -22,6 +22,7 @@ class test_bench private: const std::string UE_PHY_COM_LOG_NAME = "UE /PHY/COM"; const std::string GNB_PHY_COM_LOG_NAME = "GNB/PHY/COM"; + const std::string CHANNEL_LOG_NAME = "CHANNEL"; uint32_t slot_idx = 0; uint64_t slot_count = 0; uint64_t duration_slots = 0; @@ -33,6 +34,9 @@ private: phy_common ue_phy_com; bool initialised = false; uint32_t sf_sz = 0; + // Channel simulator + srsran::channel dl_channel; + srsran::channel ul_channel; public: struct args_t { @@ -50,12 +54,16 @@ public: std::string phy_lib_log_level = "none"; uint64_t durations_slots = 100; + // channel simulator args + srsran::channel::args_t dl_channel; + srsran::channel::args_t ul_channel; args_t(int argc, char** argv); }; struct metrics_t { gnb_dummy_stack::metrics_t gnb_stack = {}; ue_dummy_stack::metrics_t ue_stack = {}; + srsue::phy_metrics_t ue_phy = {}; }; test_bench(const args_t& args) : @@ -69,10 +77,13 @@ public: gnb_phy_com(phy_common::args_t(args.srate_hz, args.buffer_sz_ms, args.nof_channels), srslog::fetch_basic_logger(GNB_PHY_COM_LOG_NAME, srslog::get_default_sink(), false)), sf_sz((uint32_t)std::round(args.srate_hz * 1e-3)), - duration_slots(args.durations_slots) + duration_slots(args.durations_slots), + dl_channel(args.dl_channel, 1, srslog::fetch_basic_logger(CHANNEL_LOG_NAME, srslog::get_default_sink(), false)), + ul_channel(args.ul_channel, 1, srslog::fetch_basic_logger(CHANNEL_LOG_NAME, srslog::get_default_sink(), false)) { srslog::fetch_basic_logger(UE_PHY_COM_LOG_NAME).set_level(srslog::str_to_basic_level(args.phy_com_log_level)); srslog::fetch_basic_logger(GNB_PHY_COM_LOG_NAME).set_level(srslog::str_to_basic_level(args.phy_com_log_level)); + srslog::fetch_basic_logger(CHANNEL_LOG_NAME).set_level(srslog::basic_levels::error); if (not gnb_phy.init(args.gnb_phy, args.cell_list)) { return; @@ -109,6 +120,9 @@ public: srsran_verbose = SRSRAN_VERBOSE_NONE; } + // Configure channel + dl_channel.set_srate((uint32_t)args.srate_hz); + ul_channel.set_srate((uint32_t)args.srate_hz); initialised = true; } @@ -141,6 +155,9 @@ public: // Set gNb time gnb_time.add(TX_ENB_DELAY * 1e-3); + // Run the UL channel simulator + ul_channel.run(gnb_rx_buffers.data(), gnb_rx_buffers.data(), (uint32_t)sf_sz, gnb_time.get(0)); + // Set gnb context srsran::phy_common_interface::worker_context_t gnb_context; gnb_context.sf_idx = slot_idx; @@ -168,6 +185,9 @@ public: // Set UE time ue_time.add(TX_ENB_DELAY * 1e-3); + // Run the DL channel simulator + dl_channel.run(ue_rx_buffers.data(), ue_rx_buffers.data(), (uint32_t)sf_sz, ue_time.get(0)); + // Set gnb context srsran::phy_common_interface::worker_context_t ue_context; ue_context.sf_idx = slot_idx; @@ -188,11 +208,12 @@ public: return slot_count <= duration_slots; } - metrics_t get_gnb_metrics() + metrics_t get_metrics() { metrics_t metrics = {}; metrics.gnb_stack = gnb_stack.get_metrics(); metrics.ue_stack = ue_stack.get_metrics(); + ue_phy.get_metrics(metrics.ue_phy); // get the metrics from the ue_phy return metrics; } }; From 1bdb1bb62db45302c47870ac0f004863482fe1fe Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 5 Oct 2021 11:56:48 +0200 Subject: [PATCH 046/208] Store PUSCH CSI from PUSCH DMRS --- .../srsran/interfaces/gnb_interfaces.h | 2 +- .../srsran/phy/ch_estimation/dmrs_sch.h | 2 + lib/src/phy/ch_estimation/dmrs_sch.c | 48 ++++++++---- srsenb/src/phy/nr/slot_worker.cc | 3 + test/phy/dummy_gnb_stack.h | 16 ++++ test/phy/nr_phy_test.cc | 75 ++++++++++++++++++- 6 files changed, 125 insertions(+), 21 deletions(-) diff --git a/lib/include/srsran/interfaces/gnb_interfaces.h b/lib/include/srsran/interfaces/gnb_interfaces.h index 91efba3dd..48ab3d340 100644 --- a/lib/include/srsran/interfaces/gnb_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_interfaces.h @@ -268,7 +268,7 @@ public: srsran::unique_byte_buffer_t pdu = nullptr; // PUSCH signal measurements - // ... + srsran_csi_trs_measurements_t csi; ///< DMRS based signal Channel State Information (CSI) }; struct rach_info_t { diff --git a/lib/include/srsran/phy/ch_estimation/dmrs_sch.h b/lib/include/srsran/phy/ch_estimation/dmrs_sch.h index 477d51278..1ccbec53e 100644 --- a/lib/include/srsran/phy/ch_estimation/dmrs_sch.h +++ b/lib/include/srsran/phy/ch_estimation/dmrs_sch.h @@ -50,6 +50,8 @@ typedef struct { cf_t* temp; /// Temporal data vector of size SRSRAN_NRE * carrier.nof_prb float* filter; ///< Smoothing filter + + srsran_csi_trs_measurements_t csi; ///< Last estimated channel state information } srsran_dmrs_sch_t; /** diff --git a/lib/src/phy/ch_estimation/dmrs_sch.c b/lib/src/phy/ch_estimation/dmrs_sch.c index 37dd0b410..629e61b2f 100644 --- a/lib/src/phy/ch_estimation/dmrs_sch.c +++ b/lib/src/phy/ch_estimation/dmrs_sch.c @@ -808,7 +808,7 @@ int srsran_dmrs_sch_estimate(srsran_dmrs_sch_t* q, sync_err += srsran_vec_estimate_frequency(&q->pilot_estimates[nof_pilots_x_symbol * i], nof_pilots_x_symbol); } sync_err /= (float)nof_symbols; - chest_res->sync_error = sync_err / (dmrs_stride * SRSRAN_SUBC_SPACING_NR(q->carrier.scs)); + float delay_us = sync_err / (dmrs_stride * SRSRAN_SUBC_SPACING_NR(q->carrier.scs)); #if DMRS_SCH_SYNC_PRECOMPENSATE // Pre-compensate synchronization error @@ -836,36 +836,52 @@ int srsran_dmrs_sch_estimate(srsran_dmrs_sch_t* q, epre /= nof_symbols; rsrp = SRSRAN_MIN(rsrp, epre - epre * 1e-7); - chest_res->rsrp = rsrp; - chest_res->rsrp_dbm = srsran_convert_power_to_dB(chest_res->rsrp); - - chest_res->noise_estimate = epre - rsrp; - chest_res->noise_estimate_dbm = srsran_convert_power_to_dB(chest_res->noise_estimate); - - chest_res->snr_db = chest_res->rsrp_dbm - chest_res->noise_estimate_dbm; - // Measure CFO if more than one symbol is used - float cfo_avg = 0.0; + float cfo_avg_hz = 0.0; + float cfo_hz_max = INFINITY; for (uint32_t i = 0; i < nof_symbols - 1; i++) { float time_diff = srsran_symbol_distance_s(symbols[i], symbols[i + 1], q->carrier.scs); float phase_diff = cargf(corr[i + 1] * conjf(corr[i])); if (isnormal(time_diff)) { - cfo_avg += phase_diff / (2.0f * M_PI * time_diff * (nof_symbols - 1)); + cfo_avg_hz += phase_diff / (2.0f * M_PI * time_diff * (nof_symbols - 1)); + + // The maximum measured CFO depends on the symbol time difference + cfo_hz_max = SRSRAN_MIN(cfo_hz_max, 1 / time_diff); } } - chest_res->cfo = cfo_avg; + + // Store internal CSI + q->csi.rsrp = rsrp; + q->csi.rsrp_dB = srsran_convert_power_to_dB(rsrp); + q->csi.epre = epre; + q->csi.epre_dB = srsran_convert_power_to_dB(epre); + q->csi.n0 = epre - rsrp; + q->csi.n0_dB = srsran_convert_power_to_dB(q->csi.n0); + q->csi.snr_dB = q->csi.rsrp_dB - q->csi.n0_dB; + q->csi.cfo_hz = cfo_avg_hz; + q->csi.cfo_hz_max = cfo_hz_max; + q->csi.delay_us = delay_us; + + // Write CSI in estimated channel result + chest_res->rsrp = q->csi.rsrp; + chest_res->rsrp_dbm = q->csi.rsrp_dB; + chest_res->noise_estimate = q->csi.n0; + chest_res->noise_estimate_dbm = q->csi.n0_dB; + chest_res->snr_db = q->csi.snr_dB; + chest_res->cfo = q->csi.cfo_hz; + chest_res->sync_error = q->csi.delay_us; #if DMRS_SCH_CFO_PRECOMPENSATE // Pre-compensate CFO cf_t cfo_correction[SRSRAN_NSYMB_PER_SLOT_NR] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; - if (isnormal(cfo_avg)) { + if (isnormal(cfo_avg_hz)) { // Calculate phase of the first OFDM symbol (l = 0) - float arg0 = cargf(corr[0]) - 2.0f * M_PI * srsran_symbol_distance_s(0, symbols[0], q->carrier.scs) * cfo_avg; + float arg0 = cargf(corr[0]) - 2.0f * M_PI * srsran_symbol_distance_s(0, symbols[0], q->carrier.scs) * cfo_avg_hz; // Calculate CFO corrections for (uint32_t l = 0; l < SRSRAN_NSYMB_PER_SLOT_NR; l++) { - float arg = arg0 + 2.0f * M_PI * cfo_avg * srsran_symbol_distance_s(0, l, q->carrier.scs); + float arg = arg0 + 2.0f * M_PI * cfo_avg_hz * srsran_symbol_distance_s(0, l, q->carrier.scs); cfo_correction[l] = cexpf(I * arg); } @@ -883,7 +899,7 @@ int srsran_dmrs_sch_estimate(srsran_dmrs_sch_t* q, INFO("PDSCH-DMRS: RSRP=%+.2fdB EPRE=%+.2fdB CFO=%+.0fHz Sync=%.3fus", chest_res->rsrp_dbm, srsran_convert_power_to_dB(epre), - cfo_avg, + cfo_avg_hz, chest_res->sync_error * 1e6); // Average over time, only if more than one DMRS symbol diff --git a/srsenb/src/phy/nr/slot_worker.cc b/srsenb/src/phy/nr/slot_worker.cc index c0fcb4827..00fc13f2d 100644 --- a/srsenb/src/phy/nr/slot_worker.cc +++ b/srsenb/src/phy/nr/slot_worker.cc @@ -224,6 +224,9 @@ bool slot_worker::work_ul() return false; } + // Extract DMRS information + pusch_info.csi = gnb_ul.dmrs.csi; + // Inform stack if (stack.pusch_info(ul_slot_cfg, pusch_info) < SRSRAN_SUCCESS) { logger.error("Error pushing PUSCH information to stack"); diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index b9f80e10c..15b841d0b 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -61,6 +61,7 @@ public: uint32_t cqi_count = 0; ///< CQI opportunity counter uint32_t cqi_valid_count = 0; ///< Valid CQI counter pucch_metrics_t pucch = {}; + pucch_metrics_t pusch = {}; }; private: @@ -662,6 +663,21 @@ public: metrics.mac.rx_brate += rx_harq_proc[pusch_info.pid].get_tbs(); metrics.mac.rx_pkts++; + // Handle PHY metrics + metrics.pusch.epre_db_avg = SRSRAN_VEC_CMA(pusch_info.csi.epre_dB, metrics.pusch.epre_db_avg, metrics.pusch.count); + metrics.pusch.epre_db_min = SRSRAN_MIN(metrics.pusch.epre_db_min, pusch_info.csi.epre_dB); + metrics.pusch.epre_db_max = SRSRAN_MAX(metrics.pusch.epre_db_max, pusch_info.csi.epre_dB); + metrics.pusch.rsrp_db_avg = SRSRAN_VEC_CMA(pusch_info.csi.rsrp_dB, metrics.pusch.rsrp_db_avg, metrics.pusch.count); + metrics.pusch.rsrp_db_min = SRSRAN_MIN(metrics.pusch.rsrp_db_min, pusch_info.csi.rsrp_dB); + metrics.pusch.rsrp_db_max = SRSRAN_MAX(metrics.pusch.rsrp_db_max, pusch_info.csi.rsrp_dB); + metrics.pusch.snr_db_avg = SRSRAN_VEC_CMA(pusch_info.csi.snr_dB, metrics.pusch.snr_db_avg, metrics.pusch.count); + metrics.pusch.snr_db_min = SRSRAN_MIN(metrics.pusch.snr_db_min, pusch_info.csi.snr_dB); + metrics.pusch.snr_db_max = SRSRAN_MAX(metrics.pusch.snr_db_max, pusch_info.csi.snr_dB); + metrics.pusch.ta_us_avg = SRSRAN_VEC_CMA(pusch_info.csi.delay_us, metrics.pusch.ta_us_avg, metrics.pusch.count); + metrics.pusch.ta_us_min = SRSRAN_MIN(metrics.pusch.ta_us_min, pusch_info.csi.delay_us); + metrics.pusch.ta_us_max = SRSRAN_MAX(metrics.pusch.ta_us_max, pusch_info.csi.delay_us); + metrics.pusch.count++; + return SRSRAN_SUCCESS; } diff --git a/test/phy/nr_phy_test.cc b/test/phy/nr_phy_test.cc index b5df81698..57ed9a069 100644 --- a/test/phy/nr_phy_test.cc +++ b/test/phy/nr_phy_test.cc @@ -194,9 +194,9 @@ int main(int argc, char** argv) test_bench::metrics_t metrics = tb.get_metrics(); // Print PDSCH metrics if scheduled - double pdsch_bler = 0.0; if (metrics.gnb_stack.mac.tx_pkts > 0) { - pdsch_bler = (double)metrics.gnb_stack.mac.tx_errors / (double)metrics.gnb_stack.mac.tx_pkts; + float pdsch_bler = 0.0f; + pdsch_bler = (float)metrics.gnb_stack.mac.tx_errors / (float)metrics.gnb_stack.mac.tx_pkts; float pdsch_shed_rate = 0.0f; pdsch_shed_rate = (float)metrics.gnb_stack.mac.tx_brate / (float)metrics.gnb_stack.mac.tx_pkts / 1000.0f; @@ -215,10 +215,10 @@ int main(int argc, char** argv) } // Print PUSCH metrics if scheduled - double pusch_bler = 0.0; if (metrics.gnb_stack.mac.rx_pkts > 0) { + float pusch_bler = 0.0f; if (metrics.gnb_stack.mac.rx_pkts != 0) { - pusch_bler = (double)metrics.gnb_stack.mac.rx_errors / (double)metrics.gnb_stack.mac.rx_pkts; + pusch_bler = (float)metrics.gnb_stack.mac.rx_errors / (float)metrics.gnb_stack.mac.rx_pkts; } float pusch_shed_rate = 0.0f; @@ -295,6 +295,73 @@ int main(int argc, char** argv) srsran::console(" +------------+------------+------------+------------+\n"); } + // Print PDSCH metrics if scheduled + double pdsch_bler = 0.0; + if (metrics.gnb_stack.mac.tx_pkts > 0) { + pdsch_bler = (double)metrics.gnb_stack.mac.tx_errors / (double)metrics.gnb_stack.mac.tx_pkts; + + float pdsch_shed_rate = 0.0f; + pdsch_shed_rate = (float)metrics.gnb_stack.mac.tx_brate / (float)metrics.gnb_stack.mac.tx_pkts / 1000.0f; + + srsran::console("PDSCH:\n"); + srsran::console(" Count: %d\n", metrics.gnb_stack.mac.tx_pkts); + srsran::console(" BLER: %f\n", pdsch_bler); + srsran::console(" Sched Rate: %f Mbps\n", pdsch_shed_rate); + srsran::console(" Net Rate: %f Mbps\n", (1.0f - pdsch_bler) * pdsch_shed_rate); + srsran::console(" Retx Rate: %f Mbps\n", pdsch_bler * pdsch_shed_rate); + srsran::console("\n"); + } + + // Print PUSCH metrics if scheduled + double pusch_bler = 0.0; + if (metrics.gnb_stack.mac.rx_pkts > 0) { + if (metrics.gnb_stack.mac.rx_pkts != 0) { + pusch_bler = (double)metrics.gnb_stack.mac.rx_errors / (double)metrics.gnb_stack.mac.rx_pkts; + } + + float pusch_shed_rate = 0.0f; + if (metrics.gnb_stack.mac.rx_pkts != 0) { + pusch_shed_rate = (float)metrics.gnb_stack.mac.rx_brate / (float)metrics.gnb_stack.mac.rx_pkts / 1000.0f; + } + + srsran::console("PUSCH:\n"); + srsran::console(" Count: %d\n", metrics.gnb_stack.mac.rx_pkts); + srsran::console(" BLER: %f\n", pusch_bler); + srsran::console(" Sched Rate: %f Mbps\n", pusch_shed_rate); + srsran::console(" Net Rate: %f Mbps\n", (1.0f - pusch_bler) * pusch_shed_rate); + srsran::console(" Retx Rate: %f Mbps\n", pusch_bler * pusch_shed_rate); + srsran::console("\n"); + } + + // Print PUSCH + if (metrics.gnb_stack.pusch.count > 0) { + srsran::console("PUSCH DMRS Receiver metrics:\n"); + srsran::console(" +------------+------------+------------+------------+\n"); + srsran::console(" | %10s | %10s | %10s | %10s |\n", "Measure", "Average", "Min", "Max"); + srsran::console(" +------------+------------+------------+------------+\n"); + srsran::console(" | %10s | %+10.2f | %+10.2f | %+10.2f |\n", + "EPRE (dB)", + metrics.gnb_stack.pusch.epre_db_avg, + metrics.gnb_stack.pusch.epre_db_min, + metrics.gnb_stack.pusch.epre_db_min); + srsran::console(" | %10s | %+10.2f | %+10.2f | %+10.2f |\n", + "RSRP (dB)", + metrics.gnb_stack.pusch.rsrp_db_avg, + metrics.gnb_stack.pusch.rsrp_db_min, + metrics.gnb_stack.pusch.rsrp_db_max); + srsran::console(" | %10s | %+10.2f | %+10.2f | %+10.2f |\n", + "SINR (dB)", + metrics.gnb_stack.pusch.snr_db_avg, + metrics.gnb_stack.pusch.snr_db_min, + metrics.gnb_stack.pusch.snr_db_max); + srsran::console(" | %10s | %+10.2f | %+10.2f | %+10.2f |\n", + "TA (us)", + metrics.gnb_stack.pusch.ta_us_avg, + metrics.gnb_stack.pusch.ta_us_min, + metrics.gnb_stack.pusch.ta_us_max); + srsran::console(" +------------+------------+------------+------------+\n"); + } + srsran::console("UCI stats:\n"); srsran::console(" +------------+------------+------------+------------+------------+\n"); srsran::console( From ef78c7e06ff2264f34690b3af4f29cb4b709b62e Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 7 Oct 2021 12:33:27 +0100 Subject: [PATCH 047/208] rrc,nr,gnb: add csi resource to add/mod config to FDD --- srsenb/src/stack/rrc/nr/cell_asn1_config.cc | 32 +++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc index d5e2d9689..1f0e78457 100644 --- a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc +++ b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc @@ -212,6 +212,35 @@ void fill_nzp_csi_rs_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_m } } +/// Fill csi-ResoureConfigToAddModList +void fill_csi_resource_cfg_to_add(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas_cfg) +{ + if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { + csi_meas_cfg.csi_res_cfg_to_add_mod_list_present = true; + csi_meas_cfg.csi_res_cfg_to_add_mod_list.resize(3); + + csi_meas_cfg.csi_res_cfg_to_add_mod_list[0].csi_res_cfg_id = 0; + auto& nzp = csi_meas_cfg.csi_res_cfg_to_add_mod_list[0].csi_rs_res_set_list.set_nzp_csi_rs_ssb(); + nzp.nzp_csi_rs_res_set_list_present = true; + nzp.nzp_csi_rs_res_set_list.push_back(0); + csi_meas_cfg.csi_res_cfg_to_add_mod_list[0].bwp_id = 0; + csi_meas_cfg.csi_res_cfg_to_add_mod_list[0].res_type.value = csi_res_cfg_s::res_type_opts::periodic; + + csi_meas_cfg.csi_res_cfg_to_add_mod_list[1].csi_res_cfg_id = 1; + auto& imres = csi_meas_cfg.csi_res_cfg_to_add_mod_list[1].csi_rs_res_set_list.set_csi_im_res_set_list(); + imres.push_back(0); + csi_meas_cfg.csi_res_cfg_to_add_mod_list[1].bwp_id = 0; + csi_meas_cfg.csi_res_cfg_to_add_mod_list[1].res_type.value = csi_res_cfg_s::res_type_opts::periodic; + + csi_meas_cfg.csi_res_cfg_to_add_mod_list[2].csi_res_cfg_id = 2; + auto& nzp2 = csi_meas_cfg.csi_res_cfg_to_add_mod_list[2].csi_rs_res_set_list.set_nzp_csi_rs_ssb(); + nzp2.nzp_csi_rs_res_set_list_present = true; + nzp2.nzp_csi_rs_res_set_list.push_back(1); + csi_meas_cfg.csi_res_cfg_to_add_mod_list[2].bwp_id = 0; + csi_meas_cfg.csi_res_cfg_to_add_mod_list[2].res_type.value = csi_res_cfg_s::res_type_opts::periodic; + } +} + /// Fill CSI-MeasConfig with gNB config int fill_csi_meas_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas_cfg) { @@ -221,6 +250,9 @@ int fill_csi_meas_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas // return SRSRAN_ERROR; // } + // Fill CSI resource config + fill_csi_resource_cfg_to_add(cfg, csi_meas_cfg); + // Fill NZP-CSI Resources if (cfg.cell_list[0].duplex_mode != SRSRAN_DUPLEX_MODE_FDD) { // TODO: Support nzp-csi for FDD From 47e5e85449bf991d9bdf297ddf93a8c68f1298c8 Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 7 Oct 2021 17:39:43 +0100 Subject: [PATCH 048/208] refactor: clean unnecessary includes of the asn1/rrc_nr.h --- lib/include/srsran/rrc/rrc_common.h | 4 +-- srsenb/hdr/enb.h | 1 - srsenb/src/enb_cfg_parser.h | 2 +- srsue/hdr/stack/mac_nr/mac_nr.h | 2 +- srsue/hdr/stack/rrc/nr/rrc_nr_config.h | 40 +++++++++++++++++++++ srsue/hdr/stack/rrc/rrc.h | 24 +------------ srsue/hdr/stack/rrc/rrc_config.h | 44 ++++++++++++++++++++++++ srsue/hdr/stack/rrc/rrc_nr.h | 19 +--------- srsue/hdr/stack/ue_stack_base.h | 5 ++- srsue/hdr/stack/ue_stack_lte.h | 21 ++++++----- srsue/hdr/stack/ue_stack_nr.h | 4 ++- srsue/src/main.cc | 1 + srsue/src/stack/mac_nr/mac_nr.cc | 6 ++++ srsue/src/stack/ue_stack_nr.cc | 3 +- srsue/src/test/ttcn3/hdr/lte_ttcn3_phy.h | 1 + 15 files changed, 115 insertions(+), 62 deletions(-) create mode 100644 srsue/hdr/stack/rrc/nr/rrc_nr_config.h create mode 100644 srsue/hdr/stack/rrc/rrc_config.h diff --git a/lib/include/srsran/rrc/rrc_common.h b/lib/include/srsran/rrc/rrc_common.h index c70aa4b93..1dada2655 100644 --- a/lib/include/srsran/rrc/rrc_common.h +++ b/lib/include/srsran/rrc/rrc_common.h @@ -13,10 +13,10 @@ #ifndef SRSUE_RRC_COMMON_H #define SRSUE_RRC_COMMON_H -namespace srsran { - #include +namespace srsran { + enum quant_s { quant_rsrp, quant_rsrq }; uint8_t rrc_value_to_range(quant_s quant, const float value); diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index 3b72417e7..a47828f2d 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -30,7 +30,6 @@ #include "srsenb/hdr/phy/enb_phy_base.h" #include "srsenb/hdr/stack/enb_stack_base.h" -#include "srsenb/hdr/stack/rrc/nr/rrc_config_nr.h" #include "srsenb/hdr/stack/rrc/rrc_config.h" #include "srsenb/hdr/stack/mac/sched_interface.h" diff --git a/srsenb/src/enb_cfg_parser.h b/srsenb/src/enb_cfg_parser.h index 3f974b933..acc368fd0 100644 --- a/srsenb/src/enb_cfg_parser.h +++ b/srsenb/src/enb_cfg_parser.h @@ -21,7 +21,6 @@ #include #include -#include "srsenb/hdr/stack/rrc/nr/rrc_config_nr.h" #include "srsenb/hdr/stack/rrc/rrc.h" #include "srsran/asn1/asn1_utils.h" @@ -31,6 +30,7 @@ using namespace libconfig; struct all_args_t; struct phy_cfg_t; +struct rrc_nr_cfg_t; bool sib_is_present(const asn1::rrc::sched_info_list_l& l, asn1::rrc::sib_type_e sib_num); diff --git a/srsue/hdr/stack/mac_nr/mac_nr.h b/srsue/hdr/stack/mac_nr/mac_nr.h index 40a5ed772..e7e5e03db 100644 --- a/srsue/hdr/stack/mac_nr/mac_nr.h +++ b/srsue/hdr/stack/mac_nr/mac_nr.h @@ -107,7 +107,7 @@ public: bool msg3_is_empty() { return mux.msg3_is_empty(); } /// RRC - void rrc_ra_problem() { rrc->ra_problem(); } + void rrc_ra_problem(); /// stack interface void process_pdus(); diff --git a/srsue/hdr/stack/rrc/nr/rrc_nr_config.h b/srsue/hdr/stack/rrc/nr/rrc_nr_config.h new file mode 100644 index 000000000..ae3b37b70 --- /dev/null +++ b/srsue/hdr/stack/rrc/nr/rrc_nr_config.h @@ -0,0 +1,40 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#ifndef SRSRAN_RRC_NR_CONFIG_H +#define SRSRAN_RRC_NR_CONFIG_H + +#include +#include + +namespace srsue { + +// Expert arguments to create GW without proper RRC +struct core_less_args_t { + std::string ip_addr; + uint8_t drb_lcid; +}; + +struct rrc_nr_args_t { + core_less_args_t coreless; + uint32_t sim_nr_meas_pci; + bool pdcp_short_sn_support; + std::string supported_bands_nr_str; + std::vector supported_bands_nr; + std::vector supported_bands_eutra; + std::string log_level; + uint32_t log_hex_limit; +}; + +} // namespace srsue + +#endif // SRSRAN_RRC_NR_CONFIG_H diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index 8d2ebbcf7..09ab8d8dc 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -14,6 +14,7 @@ #define SRSUE_RRC_H #include "rrc_cell.h" +#include "rrc_config.h" #include "rrc_metrics.h" #include "rrc_rlf_report.h" #include "srsran/asn1/rrc_utils.h" @@ -36,29 +37,6 @@ using srsran::byte_buffer_t; namespace srsue { -#define SRSRAN_RRC_N_BANDS 43 -typedef struct { - std::string ue_category_str; - uint32_t ue_category; - int ue_category_ul; - int ue_category_dl; - uint32_t release; - uint32_t feature_group; - std::array supported_bands; - std::vector supported_bands_nr; - uint32_t nof_supported_bands; - bool support_ca; - int mbms_service_id; - uint32_t mbms_service_port; -} rrc_args_t; - -#define SRSRAN_UE_CATEGORY_DEFAULT "4" -#define SRSRAN_UE_CATEGORY_MIN 1 -#define SRSRAN_UE_CATEGORY_MAX 21 -#define SRSRAN_RELEASE_MIN 8 -#define SRSRAN_RELEASE_MAX 15 -#define SRSRAN_RELEASE_DEFAULT (SRSRAN_RELEASE_MIN) - class phy_controller; class usim_interface_rrc; class gw_interface_rrc; diff --git a/srsue/hdr/stack/rrc/rrc_config.h b/srsue/hdr/stack/rrc/rrc_config.h new file mode 100644 index 000000000..1f66c3eb7 --- /dev/null +++ b/srsue/hdr/stack/rrc/rrc_config.h @@ -0,0 +1,44 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#ifndef SRSRAN_RRC_CONFIG_H +#define SRSRAN_RRC_CONFIG_H + +namespace srsue { + +#define SRSRAN_RRC_N_BANDS 43 + +struct rrc_args_t { + std::string ue_category_str; + uint32_t ue_category; + int ue_category_ul; + int ue_category_dl; + uint32_t release; + uint32_t feature_group; + std::array supported_bands; + std::vector supported_bands_nr; + uint32_t nof_supported_bands; + bool support_ca; + int mbms_service_id; + uint32_t mbms_service_port; +}; + +#define SRSRAN_UE_CATEGORY_DEFAULT "4" +#define SRSRAN_UE_CATEGORY_MIN 1 +#define SRSRAN_UE_CATEGORY_MAX 21 +#define SRSRAN_RELEASE_MIN 8 +#define SRSRAN_RELEASE_MAX 15 +#define SRSRAN_RELEASE_DEFAULT (SRSRAN_RELEASE_MIN) + +} // namespace srsue + +#endif // SRSRAN_RRC_CONFIG_H diff --git a/srsue/hdr/stack/rrc/rrc_nr.h b/srsue/hdr/stack/rrc/rrc_nr.h index 11774dcd7..011922934 100644 --- a/srsue/hdr/stack/rrc/rrc_nr.h +++ b/srsue/hdr/stack/rrc/rrc_nr.h @@ -13,6 +13,7 @@ #ifndef SRSUE_RRC_NR_H #define SRSUE_RRC_NR_H +#include "nr/rrc_nr_config.h" #include "srsran/adt/circular_map.h" #include "srsran/asn1/rrc_nr.h" #include "srsran/asn1/rrc_nr_utils.h" @@ -32,24 +33,6 @@ class usim_interface_rrc_nr; class pdcp_interface_rrc; class rlc_interface_rrc; -// Expert arguments to create GW without proper RRC -struct core_less_args_t { - std::string ip_addr; - srsue::gw_args_t gw_args; - uint8_t drb_lcid; -}; - -struct rrc_nr_args_t { - core_less_args_t coreless; - uint32_t sim_nr_meas_pci; - bool pdcp_short_sn_support; - std::string supported_bands_nr_str; - std::vector supported_bands_nr; - std::vector supported_bands_eutra; - std::string log_level; - uint32_t log_hex_limit; -}; - struct rrc_nr_metrics_t {}; class rrc_nr final : public rrc_interface_phy_nr, diff --git a/srsue/hdr/stack/ue_stack_base.h b/srsue/hdr/stack/ue_stack_base.h index 1fa5f35ce..2551922c0 100644 --- a/srsue/hdr/stack/ue_stack_base.h +++ b/srsue/hdr/stack/ue_stack_base.h @@ -13,11 +13,10 @@ #ifndef SRSUE_UE_STACK_BASE_H #define SRSUE_UE_STACK_BASE_H +#include "rrc/nr/rrc_nr_config.h" +#include "rrc/rrc_config.h" #include "srsue/hdr/stack/upper/nas_config.h" #include "srsue/hdr/ue_metrics_interface.h" - -#include "rrc/rrc.h" -#include "rrc/rrc_nr.h" #include "upper/gw.h" #include "upper/usim.h" diff --git a/srsue/hdr/stack/ue_stack_lte.h b/srsue/hdr/stack/ue_stack_lte.h index d7698a40d..89b7742e8 100644 --- a/srsue/hdr/stack/ue_stack_lte.h +++ b/srsue/hdr/stack/ue_stack_lte.h @@ -17,20 +17,10 @@ #ifndef SRSUE_UE_STACK_LTE_H #define SRSUE_UE_STACK_LTE_H -#include -#include -#include -#include - #include "mac/mac.h" #include "mac_nr/mac_nr.h" #include "rrc/rrc.h" -#include "srsran/radio/radio.h" -#include "srsran/rlc/rlc.h" -#include "srsran/upper/pdcp.h" -#include "upper/nas.h" -#include "upper/usim.h" - +#include "rrc/rrc_nr.h" #include "srsran/common/bearer_manager.h" #include "srsran/common/buffer_pool.h" #include "srsran/common/multiqueue.h" @@ -39,8 +29,17 @@ #include "srsran/common/thread_pool.h" #include "srsran/common/time_prof.h" #include "srsran/interfaces/ue_interfaces.h" +#include "srsran/radio/radio.h" +#include "srsran/rlc/rlc.h" +#include "srsran/upper/pdcp.h" #include "srsue/hdr/ue_metrics_interface.h" #include "ue_stack_base.h" +#include "upper/nas.h" +#include "upper/usim.h" +#include +#include +#include +#include namespace srsue { diff --git a/srsue/hdr/stack/ue_stack_nr.h b/srsue/hdr/stack/ue_stack_nr.h index c3704c7c3..1174c9dad 100644 --- a/srsue/hdr/stack/ue_stack_nr.h +++ b/srsue/hdr/stack/ue_stack_nr.h @@ -19,7 +19,6 @@ #include #include "mac_nr/mac_nr.h" -#include "rrc/rrc_nr.h" #include "srsran/radio/radio.h" #include "srsran/rlc/rlc.h" #include "srsran/upper/pdcp.h" @@ -30,6 +29,7 @@ #include "srsran/common/mac_pcap.h" #include "srsran/common/multiqueue.h" #include "srsran/common/thread_pool.h" +#include "srsran/interfaces/ue_interfaces.h" #include "srsran/interfaces/ue_nr_interfaces.h" #include "srsue/hdr/ue_metrics_interface.h" @@ -37,6 +37,8 @@ namespace srsue { +class rrc_nr; + /** \brief L2/L3 stack class for 5G/NR UEs. * * This class wraps all L2/L3 blocks and provides a single interface towards the PHY. diff --git a/srsue/src/main.cc b/srsue/src/main.cc index e63afe241..05e43934b 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -14,6 +14,7 @@ #include "srsran/common/config_file.h" #include "srsran/common/crash_handler.h" #include "srsran/common/metrics_hub.h" +#include "srsran/common/multiqueue.h" #include "srsran/common/signal_handler.h" #include "srsran/common/tsan_options.h" #include "srsran/srslog/event_trace.h" diff --git a/srsue/src/stack/mac_nr/mac_nr.cc b/srsue/src/stack/mac_nr/mac_nr.cc index 11cc1c4ce..49a4dd325 100644 --- a/srsue/src/stack/mac_nr/mac_nr.cc +++ b/srsue/src/stack/mac_nr/mac_nr.cc @@ -12,6 +12,7 @@ #include "srsue/hdr/stack/mac_nr/mac_nr.h" #include "srsran/interfaces/ue_rlc_interfaces.h" +#include "srsran/interfaces/ue_rrc_interfaces.h" #include "srsran/mac/mac_rar_pdu_nr.h" #include "srsue/hdr/stack/mac_nr/proc_ra_nr.h" @@ -500,6 +501,11 @@ void mac_nr::get_metrics(mac_metrics_t m[SRSRAN_MAX_CARRIERS]) metrics = {}; } +void mac_nr::rrc_ra_problem() +{ + rrc->ra_problem(); +} + /** * Called from the main stack thread to process received PDUs */ diff --git a/srsue/src/stack/ue_stack_nr.cc b/srsue/src/stack/ue_stack_nr.cc index 473e45706..bd8b95a61 100644 --- a/srsue/src/stack/ue_stack_nr.cc +++ b/srsue/src/stack/ue_stack_nr.cc @@ -12,6 +12,7 @@ #include "srsue/hdr/stack/ue_stack_nr.h" #include "srsran/srsran.h" +#include "srsue/hdr/stack/rrc/rrc_nr.h" using namespace srsran; @@ -110,7 +111,7 @@ void ue_stack_nr::stop_impl() bool ue_stack_nr::switch_on() { // statically setup TUN (will be done through RRC later) - char* err_str = nullptr; + char* err_str = nullptr; struct in_addr in_addr; if (inet_pton(AF_INET, "192.168.1.3", &in_addr.s_addr) != 1) { perror("inet_pton"); diff --git a/srsue/src/test/ttcn3/hdr/lte_ttcn3_phy.h b/srsue/src/test/ttcn3/hdr/lte_ttcn3_phy.h index e262855e8..ee741817a 100644 --- a/srsue/src/test/ttcn3/hdr/lte_ttcn3_phy.h +++ b/srsue/src/test/ttcn3/hdr/lte_ttcn3_phy.h @@ -13,6 +13,7 @@ #ifndef SRSUE_TTCN3_LTE_PHY_H #define SRSUE_TTCN3_LTE_PHY_H +#include "srsran/common/task_scheduler.h" #include "srsran/interfaces/ue_interfaces.h" #include "srsran/interfaces/ue_phy_interfaces.h" #include "srsue/hdr/phy/ue_lte_phy_base.h" From 053877f489490f322cb64d391a80a0546183766a Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 6 Oct 2021 17:56:18 +0100 Subject: [PATCH 049/208] rrc,nr: fix conversion from asn1 to phy cfg --- lib/src/asn1/rrc_nr_utils.cc | 3 +- srsenb/src/stack/rrc/nr/cell_asn1_config.cc | 124 ++++++++------------ 2 files changed, 50 insertions(+), 77 deletions(-) diff --git a/lib/src/asn1/rrc_nr_utils.cc b/lib/src/asn1/rrc_nr_utils.cc index 5aac53bbf..98ae4abba 100644 --- a/lib/src/asn1/rrc_nr_utils.cc +++ b/lib/src/asn1/rrc_nr_utils.cc @@ -1488,8 +1488,9 @@ bool make_pdsch_cfg_from_serv_cell(asn1::rrc_nr::serving_cell_cfg_s& serv_cell, auto& uecfg_set = sch_hl->nzp_csi_rs_sets[nzp_set.nzp_csi_res_set_id]; uecfg_set.trs_info = nzp_set.trs_info_present; uecfg_set.count = nzp_set.nzp_csi_rs_res.size(); + uint32_t count = 0; for (uint8_t nzp_rs_idx : nzp_set.nzp_csi_rs_res) { - auto& res = uecfg_set.data[nzp_rs_idx]; + auto& res = uecfg_set.data[count++]; if (not srsran::make_phy_nzp_csi_rs_resource(setup.nzp_csi_rs_res_to_add_mod_list[nzp_rs_idx], &res)) { return false; } diff --git a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc index 1f0e78457..d23b90b7a 100644 --- a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc +++ b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc @@ -67,7 +67,7 @@ void fill_nzp_csi_rs_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_m { csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list_present = true; if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { - csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list.resize(5); + csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list.resize(3); auto& nzp_csi_res = csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list; // item 0 nzp_csi_res[0].nzp_csi_rs_res_id = 0; @@ -89,81 +89,56 @@ void fill_nzp_csi_rs_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_m nzp_csi_res[0].qcl_info_periodic_csi_rs_present = true; nzp_csi_res[0].qcl_info_periodic_csi_rs = 0; // item 1 + nzp_csi_res[1] = nzp_csi_res[0]; nzp_csi_res[1].nzp_csi_rs_res_id = 1; nzp_csi_res[1].res_map.freq_domain_alloc.set_row1(); nzp_csi_res[1].res_map.freq_domain_alloc.row1().from_number(0b0001); - nzp_csi_res[1].res_map.nrof_ports = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; - nzp_csi_res[1].res_map.first_ofdm_symbol_in_time_domain = 4; - nzp_csi_res[1].res_map.cdm_type = asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; + nzp_csi_res[2].res_map.first_ofdm_symbol_in_time_domain = 4; nzp_csi_res[1].res_map.density.set_three(); - nzp_csi_res[1].res_map.freq_band.start_rb = 0; - nzp_csi_res[1].res_map.freq_band.nrof_rbs = 52; - nzp_csi_res[1].pwr_ctrl_offset = 0; - // Skip pwr_ctrl_offset_ss_present - nzp_csi_res[1].scrambling_id = cfg.cell_list[0].phy_cell.cell_id; - nzp_csi_res[1].periodicity_and_offset_present = true; nzp_csi_res[1].periodicity_and_offset.set_slots40(); nzp_csi_res[1].periodicity_and_offset.slots40() = 11; - // optional - nzp_csi_res[1].qcl_info_periodic_csi_rs_present = true; - nzp_csi_res[1].qcl_info_periodic_csi_rs = 0; // item 2 - nzp_csi_res[2].nzp_csi_rs_res_id = 2; - nzp_csi_res[2].res_map.freq_domain_alloc.set_row1(); - nzp_csi_res[2].res_map.freq_domain_alloc.row1().from_number(0b0001); - nzp_csi_res[2].res_map.nrof_ports = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + nzp_csi_res[2] = nzp_csi_res[1]; + nzp_csi_res[2].nzp_csi_rs_res_id = 2; nzp_csi_res[2].res_map.first_ofdm_symbol_in_time_domain = 8; - nzp_csi_res[2].res_map.cdm_type = asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; - nzp_csi_res[2].res_map.density.set_three(); - nzp_csi_res[2].res_map.freq_band.start_rb = 0; - nzp_csi_res[2].res_map.freq_band.nrof_rbs = 52; - nzp_csi_res[2].pwr_ctrl_offset = 0; - // Skip pwr_ctrl_offset_ss_present - nzp_csi_res[2].scrambling_id = cfg.cell_list[0].phy_cell.cell_id; - nzp_csi_res[2].periodicity_and_offset_present = true; - nzp_csi_res[2].periodicity_and_offset.set_slots40(); - nzp_csi_res[2].periodicity_and_offset.slots40() = 11; - // optional - nzp_csi_res[2].qcl_info_periodic_csi_rs_present = true; - nzp_csi_res[2].qcl_info_periodic_csi_rs = 0; // item 3 - nzp_csi_res[3].nzp_csi_rs_res_id = 3; - nzp_csi_res[3].res_map.freq_domain_alloc.set_row1(); - nzp_csi_res[3].res_map.freq_domain_alloc.row1().from_number(0b0001); - nzp_csi_res[3].res_map.nrof_ports = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; - nzp_csi_res[3].res_map.first_ofdm_symbol_in_time_domain = 4; - nzp_csi_res[3].res_map.cdm_type = asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; - nzp_csi_res[3].res_map.density.set_three(); - nzp_csi_res[3].res_map.freq_band.start_rb = 0; - nzp_csi_res[3].res_map.freq_band.nrof_rbs = 52; - nzp_csi_res[3].pwr_ctrl_offset = 0; - // Skip pwr_ctrl_offset_ss_present - nzp_csi_res[3].scrambling_id = cfg.cell_list[0].phy_cell.cell_id; - nzp_csi_res[3].periodicity_and_offset_present = true; - nzp_csi_res[3].periodicity_and_offset.set_slots40(); - nzp_csi_res[3].periodicity_and_offset.slots40() = 12; - // optional - nzp_csi_res[3].qcl_info_periodic_csi_rs_present = true; - nzp_csi_res[3].qcl_info_periodic_csi_rs = 0; - // item 4 - nzp_csi_res[4].nzp_csi_rs_res_id = 4; - nzp_csi_res[4].res_map.freq_domain_alloc.set_row1(); - nzp_csi_res[4].res_map.freq_domain_alloc.row1().from_number(0b0001); - nzp_csi_res[4].res_map.nrof_ports = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; - nzp_csi_res[4].res_map.first_ofdm_symbol_in_time_domain = 8; - nzp_csi_res[4].res_map.cdm_type = asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; - nzp_csi_res[4].res_map.density.set_three(); - nzp_csi_res[4].res_map.freq_band.start_rb = 0; - nzp_csi_res[4].res_map.freq_band.nrof_rbs = 52; - nzp_csi_res[4].pwr_ctrl_offset = 0; - // Skip pwr_ctrl_offset_ss_present - nzp_csi_res[4].scrambling_id = cfg.cell_list[0].phy_cell.cell_id; - nzp_csi_res[4].periodicity_and_offset_present = true; - nzp_csi_res[4].periodicity_and_offset.set_slots40(); - nzp_csi_res[4].periodicity_and_offset.slots40() = 12; - // optional - nzp_csi_res[4].qcl_info_periodic_csi_rs_present = true; - nzp_csi_res[4].qcl_info_periodic_csi_rs = 0; + // nzp_csi_res[3].nzp_csi_rs_res_id = 3; + // nzp_csi_res[3].res_map.freq_domain_alloc.set_row1(); + // nzp_csi_res[3].res_map.freq_domain_alloc.row1().from_number(0b0001); + // nzp_csi_res[3].res_map.nrof_ports = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + // nzp_csi_res[3].res_map.first_ofdm_symbol_in_time_domain = 4; + // nzp_csi_res[3].res_map.cdm_type = + // asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; nzp_csi_res[3].res_map.density.set_three(); + // nzp_csi_res[3].res_map.freq_band.start_rb = 0; + // nzp_csi_res[3].res_map.freq_band.nrof_rbs = 52; + // nzp_csi_res[3].pwr_ctrl_offset = 0; + // // Skip pwr_ctrl_offset_ss_present + // nzp_csi_res[3].scrambling_id = cfg.cell_list[0].phy_cell.cell_id; + // nzp_csi_res[3].periodicity_and_offset_present = true; + // nzp_csi_res[3].periodicity_and_offset.set_slots40(); + // nzp_csi_res[3].periodicity_and_offset.slots40() = 12; + // // optional + // nzp_csi_res[3].qcl_info_periodic_csi_rs_present = true; + // nzp_csi_res[3].qcl_info_periodic_csi_rs = 0; + // // item 4 + // nzp_csi_res[4].nzp_csi_rs_res_id = 4; + // nzp_csi_res[4].res_map.freq_domain_alloc.set_row1(); + // nzp_csi_res[4].res_map.freq_domain_alloc.row1().from_number(0b0001); + // nzp_csi_res[4].res_map.nrof_ports = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + // nzp_csi_res[4].res_map.first_ofdm_symbol_in_time_domain = 8; + // nzp_csi_res[4].res_map.cdm_type = + // asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; nzp_csi_res[4].res_map.density.set_three(); + // nzp_csi_res[4].res_map.freq_band.start_rb = 0; + // nzp_csi_res[4].res_map.freq_band.nrof_rbs = 52; + // nzp_csi_res[4].pwr_ctrl_offset = 0; + // // Skip pwr_ctrl_offset_ss_present + // nzp_csi_res[4].scrambling_id = cfg.cell_list[0].phy_cell.cell_id; + // nzp_csi_res[4].periodicity_and_offset_present = true; + // nzp_csi_res[4].periodicity_and_offset.set_slots40(); + // nzp_csi_res[4].periodicity_and_offset.slots40() = 12; + // // optional + // nzp_csi_res[4].qcl_info_periodic_csi_rs_present = true; + // nzp_csi_res[4].qcl_info_periodic_csi_rs = 0; } else { csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list.resize(1); auto& nzp_csi_res = csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list; @@ -188,7 +163,7 @@ void fill_nzp_csi_rs_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_m // Fill NZP-CSI Resource Sets csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list_present = true; if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { - csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list.resize(2); + csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list.resize(3); auto& nzp_csi_res_set = csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list; // item 0 nzp_csi_res_set[0].nzp_csi_res_set_id = 0; @@ -196,12 +171,12 @@ void fill_nzp_csi_rs_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_m nzp_csi_res_set[0].nzp_csi_rs_res[0] = 0; // item 1 nzp_csi_res_set[1].nzp_csi_res_set_id = 1; - nzp_csi_res_set[1].nzp_csi_rs_res.resize(4); + nzp_csi_res_set[1].nzp_csi_rs_res.resize(1); nzp_csi_res_set[1].nzp_csi_rs_res[0] = 1; nzp_csi_res_set[1].nzp_csi_rs_res[1] = 2; - nzp_csi_res_set[1].nzp_csi_rs_res[2] = 3; - nzp_csi_res_set[1].nzp_csi_rs_res[3] = 4; - // Skip TRS info + // nzp_csi_res_set[1].nzp_csi_rs_res[2] = 3; + // nzp_csi_res_set[1].nzp_csi_rs_res[3] = 4; + // // Skip TRS info } else { csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list.resize(1); auto& nzp_csi_res_set = csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list; @@ -254,10 +229,7 @@ int fill_csi_meas_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas fill_csi_resource_cfg_to_add(cfg, csi_meas_cfg); // Fill NZP-CSI Resources - if (cfg.cell_list[0].duplex_mode != SRSRAN_DUPLEX_MODE_FDD) { - // TODO: Support nzp-csi for FDD - fill_nzp_csi_rs_from_enb_cfg(cfg, csi_meas_cfg); - } + fill_nzp_csi_rs_from_enb_cfg(cfg, csi_meas_cfg); // CSI IM config // TODO: add csi im config From d6a3daff8aace194b2bc0e6624d0d91b9f2ef420 Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 7 Oct 2021 09:22:21 +0100 Subject: [PATCH 050/208] rrc,nr: re-activate NZP-CSI-RS for FDD --- srsenb/src/stack/rrc/nr/cell_asn1_config.cc | 62 +++++++-------------- 1 file changed, 19 insertions(+), 43 deletions(-) diff --git a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc index d23b90b7a..a70d0256b 100644 --- a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc +++ b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc @@ -67,7 +67,7 @@ void fill_nzp_csi_rs_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_m { csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list_present = true; if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { - csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list.resize(3); + csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list.resize(5); auto& nzp_csi_res = csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list; // item 0 nzp_csi_res[0].nzp_csi_rs_res_id = 0; @@ -93,7 +93,7 @@ void fill_nzp_csi_rs_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_m nzp_csi_res[1].nzp_csi_rs_res_id = 1; nzp_csi_res[1].res_map.freq_domain_alloc.set_row1(); nzp_csi_res[1].res_map.freq_domain_alloc.row1().from_number(0b0001); - nzp_csi_res[2].res_map.first_ofdm_symbol_in_time_domain = 4; + nzp_csi_res[1].res_map.first_ofdm_symbol_in_time_domain = 4; nzp_csi_res[1].res_map.density.set_three(); nzp_csi_res[1].periodicity_and_offset.set_slots40(); nzp_csi_res[1].periodicity_and_offset.slots40() = 11; @@ -101,44 +101,20 @@ void fill_nzp_csi_rs_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_m nzp_csi_res[2] = nzp_csi_res[1]; nzp_csi_res[2].nzp_csi_rs_res_id = 2; nzp_csi_res[2].res_map.first_ofdm_symbol_in_time_domain = 8; + nzp_csi_res[2].periodicity_and_offset.set_slots40(); + nzp_csi_res[2].periodicity_and_offset.slots40() = 11; // item 3 - // nzp_csi_res[3].nzp_csi_rs_res_id = 3; - // nzp_csi_res[3].res_map.freq_domain_alloc.set_row1(); - // nzp_csi_res[3].res_map.freq_domain_alloc.row1().from_number(0b0001); - // nzp_csi_res[3].res_map.nrof_ports = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; - // nzp_csi_res[3].res_map.first_ofdm_symbol_in_time_domain = 4; - // nzp_csi_res[3].res_map.cdm_type = - // asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; nzp_csi_res[3].res_map.density.set_three(); - // nzp_csi_res[3].res_map.freq_band.start_rb = 0; - // nzp_csi_res[3].res_map.freq_band.nrof_rbs = 52; - // nzp_csi_res[3].pwr_ctrl_offset = 0; - // // Skip pwr_ctrl_offset_ss_present - // nzp_csi_res[3].scrambling_id = cfg.cell_list[0].phy_cell.cell_id; - // nzp_csi_res[3].periodicity_and_offset_present = true; - // nzp_csi_res[3].periodicity_and_offset.set_slots40(); - // nzp_csi_res[3].periodicity_and_offset.slots40() = 12; - // // optional - // nzp_csi_res[3].qcl_info_periodic_csi_rs_present = true; - // nzp_csi_res[3].qcl_info_periodic_csi_rs = 0; - // // item 4 - // nzp_csi_res[4].nzp_csi_rs_res_id = 4; - // nzp_csi_res[4].res_map.freq_domain_alloc.set_row1(); - // nzp_csi_res[4].res_map.freq_domain_alloc.row1().from_number(0b0001); - // nzp_csi_res[4].res_map.nrof_ports = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; - // nzp_csi_res[4].res_map.first_ofdm_symbol_in_time_domain = 8; - // nzp_csi_res[4].res_map.cdm_type = - // asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; nzp_csi_res[4].res_map.density.set_three(); - // nzp_csi_res[4].res_map.freq_band.start_rb = 0; - // nzp_csi_res[4].res_map.freq_band.nrof_rbs = 52; - // nzp_csi_res[4].pwr_ctrl_offset = 0; - // // Skip pwr_ctrl_offset_ss_present - // nzp_csi_res[4].scrambling_id = cfg.cell_list[0].phy_cell.cell_id; - // nzp_csi_res[4].periodicity_and_offset_present = true; - // nzp_csi_res[4].periodicity_and_offset.set_slots40(); - // nzp_csi_res[4].periodicity_and_offset.slots40() = 12; - // // optional - // nzp_csi_res[4].qcl_info_periodic_csi_rs_present = true; - // nzp_csi_res[4].qcl_info_periodic_csi_rs = 0; + nzp_csi_res[3] = nzp_csi_res[1]; + nzp_csi_res[3].nzp_csi_rs_res_id = 3; + nzp_csi_res[3].res_map.first_ofdm_symbol_in_time_domain = 4; + nzp_csi_res[3].periodicity_and_offset.set_slots40(); + nzp_csi_res[3].periodicity_and_offset.slots40() = 12; + // item 4 + nzp_csi_res[4] = nzp_csi_res[1]; + nzp_csi_res[4].nzp_csi_rs_res_id = 4; + nzp_csi_res[4].res_map.first_ofdm_symbol_in_time_domain = 8; + nzp_csi_res[4].periodicity_and_offset.set_slots40(); + nzp_csi_res[4].periodicity_and_offset.slots40() = 12; } else { csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list.resize(1); auto& nzp_csi_res = csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list; @@ -163,7 +139,7 @@ void fill_nzp_csi_rs_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_m // Fill NZP-CSI Resource Sets csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list_present = true; if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { - csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list.resize(3); + csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list.resize(2); auto& nzp_csi_res_set = csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list; // item 0 nzp_csi_res_set[0].nzp_csi_res_set_id = 0; @@ -171,11 +147,11 @@ void fill_nzp_csi_rs_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_m nzp_csi_res_set[0].nzp_csi_rs_res[0] = 0; // item 1 nzp_csi_res_set[1].nzp_csi_res_set_id = 1; - nzp_csi_res_set[1].nzp_csi_rs_res.resize(1); + nzp_csi_res_set[1].nzp_csi_rs_res.resize(4); nzp_csi_res_set[1].nzp_csi_rs_res[0] = 1; nzp_csi_res_set[1].nzp_csi_rs_res[1] = 2; - // nzp_csi_res_set[1].nzp_csi_rs_res[2] = 3; - // nzp_csi_res_set[1].nzp_csi_rs_res[3] = 4; + nzp_csi_res_set[1].nzp_csi_rs_res[2] = 3; + nzp_csi_res_set[1].nzp_csi_rs_res[3] = 4; // // Skip TRS info } else { csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list.resize(1); From 7d4a5238f692b32b0402068bced39259d412abd5 Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 7 Oct 2021 10:30:09 +0100 Subject: [PATCH 051/208] sched,nr: force R<0.9 by reducing mcs --- srsenb/hdr/stack/mac/nr/sched_nr_harq.h | 2 +- .../stack/mac/nr/sched_nr_grant_allocator.cc | 75 +++++++++++-------- srsenb/src/stack/mac/nr/sched_nr_harq.cc | 5 +- 3 files changed, 50 insertions(+), 32 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_harq.h b/srsenb/hdr/stack/mac/nr/sched_nr_harq.h index d060baee2..dcf2c587e 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_harq.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_harq.h @@ -58,7 +58,7 @@ public: bool new_retx(slot_point slot_tx, slot_point slot_ack); // NOTE: Has to be used before first tx is dispatched - bool set_tbs(uint32_t tbs); + bool set_tbs(uint32_t tbs, int mcs = -1); const uint32_t pid; diff --git a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc index 8e9ba1a07..36f1ccb0a 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc @@ -243,36 +243,51 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr // Allocation Successful - // Generate PDCCH - pdcch_dl_t& pdcch = bwp_pdcch_slot.dl_pdcchs.back(); - fill_dl_dci_ue_fields(ue, *bwp_grid.cfg, ss_id, pdcch.dci.ctx.location, pdcch.dci); - pdcch.dci.pucch_resource = 0; - pdcch.dci.dai = std::count_if(bwp_uci_slot.pending_acks.begin(), - bwp_uci_slot.pending_acks.end(), - [&ue](const harq_ack_t& p) { return p.res.rnti == ue.rnti; }); - pdcch.dci.dai %= 4; - pdcch.dci_cfg = ue.cfg->phy().get_dci_cfg(); - - // Generate PUCCH - bwp_uci_slot.pending_acks.emplace_back(); - bwp_uci_slot.pending_acks.back().phy_cfg = &ue.cfg->phy(); - srsran_assert(ue.cfg->phy().get_pdsch_ack_resource(pdcch.dci, bwp_uci_slot.pending_acks.back().res), - "Error getting ack resource"); - - // Generate PDSCH - bwp_pdsch_slot.dl_prbs |= dl_grant; - bwp_pdsch_slot.pdschs.emplace_back(); - pdsch_t& pdsch = bwp_pdsch_slot.pdschs.back(); - srsran_slot_cfg_t slot_cfg; - slot_cfg.idx = ue.pdsch_slot.to_uint(); - bool ret = ue.cfg->phy().get_pdsch_cfg(slot_cfg, pdcch.dci, pdsch.sch); - srsran_assert(ret, "Error converting DCI to grant"); - pdsch.sch.grant.tb[0].softbuffer.tx = ue.h_dl->get_softbuffer().get(); - pdsch.data[0] = ue.h_dl->get_tx_pdu()->get(); - if (ue.h_dl->nof_retx() == 0) { - ue.h_dl->set_tbs(pdsch.sch.grant.tb[0].tbs); // update HARQ with correct TBS - } else { - srsran_assert(pdsch.sch.grant.tb[0].tbs == (int)ue.h_dl->tbs(), "The TBS did not remain constant in retx"); + int mcs = ue.cfg->ue_cfg()->fixed_dl_mcs; + do { + // Generate PDCCH + pdcch_dl_t& pdcch = bwp_pdcch_slot.dl_pdcchs.back(); + fill_dl_dci_ue_fields(ue, *bwp_grid.cfg, ss_id, pdcch.dci.ctx.location, pdcch.dci); + pdcch.dci.pucch_resource = 0; + pdcch.dci.dai = std::count_if(bwp_uci_slot.pending_acks.begin(), + bwp_uci_slot.pending_acks.end(), + [&ue](const harq_ack_t& p) { return p.res.rnti == ue.rnti; }); + pdcch.dci.dai %= 4; + pdcch.dci_cfg = ue.cfg->phy().get_dci_cfg(); + + // Generate PUCCH + bwp_uci_slot.pending_acks.emplace_back(); + bwp_uci_slot.pending_acks.back().phy_cfg = &ue.cfg->phy(); + srsran_assert(ue.cfg->phy().get_pdsch_ack_resource(pdcch.dci, bwp_uci_slot.pending_acks.back().res), + "Error getting ack resource"); + + // Generate PDSCH + bwp_pdsch_slot.dl_prbs |= dl_grant; + bwp_pdsch_slot.pdschs.emplace_back(); + pdsch_t& pdsch = bwp_pdsch_slot.pdschs.back(); + srsran_slot_cfg_t slot_cfg; + slot_cfg.idx = ue.pdsch_slot.to_uint(); + bool ret = ue.cfg->phy().get_pdsch_cfg(slot_cfg, pdcch.dci, pdsch.sch); + srsran_assert(ret, "Error converting DCI to grant"); + + pdsch.sch.grant.tb[0].softbuffer.tx = ue.h_dl->get_softbuffer().get(); + pdsch.data[0] = ue.h_dl->get_tx_pdu()->get(); + if (ue.h_dl->nof_retx() == 0) { + ue.h_dl->set_tbs(pdsch.sch.grant.tb[0].tbs); // update HARQ with correct TBS + } else { + srsran_assert(pdsch.sch.grant.tb[0].tbs == (int)ue.h_dl->tbs(), "The TBS did not remain constant in retx"); + } + if (bwp_pdsch_slot.pdschs.back().sch.grant.tb[0].R < 0.9 or mcs == 0) { + break; + } + // Decrease MCS if rate is too high + mcs--; + ue.h_dl->set_tbs(100, mcs); + bwp_pdsch_slot.pdschs.pop_back(); + bwp_uci_slot.pending_acks.pop_back(); + } while (true); + if (mcs == 0) { + logger.warning("Couldn't find mcs that leads to R<0.9"); } return alloc_result::success; diff --git a/srsenb/src/stack/mac/nr/sched_nr_harq.cc b/srsenb/src/stack/mac/nr/sched_nr_harq.cc index 11e6ae078..19800cc0f 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_harq.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_harq.cc @@ -66,12 +66,15 @@ bool harq_proc::new_tx(slot_point slot_tx_, return true; } -bool harq_proc::set_tbs(uint32_t tbs) +bool harq_proc::set_tbs(uint32_t tbs, int mcs) { if (empty() or nof_retx() > 0) { return false; } tb[0].tbs = tbs; + if (mcs >= 0) { + tb[0].mcs = mcs; + } return true; } From 344f067c131004d303229195655207247450bd1e Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 7 Oct 2021 15:07:56 +0100 Subject: [PATCH 052/208] sched,nr: increase max R to 0.93 to enable mcs=28 --- srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc index 36f1ccb0a..8650de853 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc @@ -243,7 +243,8 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr // Allocation Successful - int mcs = ue.cfg->ue_cfg()->fixed_dl_mcs; + int mcs = ue.cfg->ue_cfg()->fixed_dl_mcs; + const static float max_R = 0.93; do { // Generate PDCCH pdcch_dl_t& pdcch = bwp_pdcch_slot.dl_pdcchs.back(); @@ -277,7 +278,7 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr } else { srsran_assert(pdsch.sch.grant.tb[0].tbs == (int)ue.h_dl->tbs(), "The TBS did not remain constant in retx"); } - if (bwp_pdsch_slot.pdschs.back().sch.grant.tb[0].R < 0.9 or mcs == 0) { + if (bwp_pdsch_slot.pdschs.back().sch.grant.tb[0].R < max_R or mcs == 0) { break; } // Decrease MCS if rate is too high From 73f1981e5e7c3cc28ad1a319e9f077d9c9ec37fc Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 7 Oct 2021 19:03:51 +0100 Subject: [PATCH 053/208] sched,nr: use R_prime instead of R in scheduler to limit coderate --- srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc index 8650de853..297f89a57 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc @@ -278,7 +278,7 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr } else { srsran_assert(pdsch.sch.grant.tb[0].tbs == (int)ue.h_dl->tbs(), "The TBS did not remain constant in retx"); } - if (bwp_pdsch_slot.pdschs.back().sch.grant.tb[0].R < max_R or mcs == 0) { + if (bwp_pdsch_slot.pdschs.back().sch.grant.tb[0].R_prime < max_R or mcs == 0) { break; } // Decrease MCS if rate is too high From 25bd0d6219c7d2ddb79498f64b5dd27413eff142 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 7 Oct 2021 11:08:05 +0200 Subject: [PATCH 054/208] Added SSB pattern to/from string functions --- lib/include/srsran/phy/common/phy_common_nr.h | 14 ++++++ lib/src/phy/common/phy_common_nr.c | 49 +++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/lib/include/srsran/phy/common/phy_common_nr.h b/lib/include/srsran/phy/common/phy_common_nr.h index f33d2adfa..7347ce934 100644 --- a/lib/include/srsran/phy/common/phy_common_nr.h +++ b/lib/include/srsran/phy/common/phy_common_nr.h @@ -695,6 +695,20 @@ SRSRAN_API int srsran_coreset_zero(uint32_t n_cell_id, uint32_t idx, srsran_coreset_t* coreset); +/** + * @brief Convert SSB pattern to string + * @param pattern + * @return a string describing the SSB pattern + */ +SRSRAN_API const char* srsran_ssb_pattern_to_str(srsran_ssb_patern_t pattern); + +/** + * @brief Convert string to SSB pattern + * @param str String to convert + * @return The pattern, SRSRAN_SSB_PATTERN_INVALID if string is invalid + */ +SRSRAN_API srsran_ssb_patern_t srsran_ssb_pattern_fom_str(const char* str); + #ifdef __cplusplus } #endif diff --git a/lib/src/phy/common/phy_common_nr.c b/lib/src/phy/common/phy_common_nr.c index 9f514ccbf..253b6618d 100644 --- a/lib/src/phy/common/phy_common_nr.c +++ b/lib/src/phy/common/phy_common_nr.c @@ -665,3 +665,52 @@ int srsran_coreset_zero(uint32_t n_cell_id, return SRSRAN_SUCCESS; } + +const char* srsran_ssb_pattern_to_str(srsran_ssb_patern_t pattern) +{ + switch (pattern) { + case SRSRAN_SSB_PATTERN_A: + return "A"; + case SRSRAN_SSB_PATTERN_B: + return "B"; + case SRSRAN_SSB_PATTERN_C: + return "C"; + case SRSRAN_SSB_PATTERN_D: + return "D"; + case SRSRAN_SSB_PATTERN_E: + return "E"; + case SRSRAN_SSB_PATTERN_INVALID: + default: + break; + } + return "Invalid"; +} + +srsran_ssb_patern_t srsran_ssb_pattern_fom_str(const char* str) +{ + if (str == NULL) { + return SRSRAN_SSB_PATTERN_INVALID; + } + + if (strcasecmp(str, "A") == 0) { + return SRSRAN_SSB_PATTERN_A; + } + + if (strcasecmp(str, "B") == 0) { + return SRSRAN_SSB_PATTERN_B; + } + + if (strcasecmp(str, "C") == 0) { + return SRSRAN_SSB_PATTERN_C; + } + + if (strcasecmp(str, "D") == 0) { + return SRSRAN_SSB_PATTERN_D; + } + + if (strcasecmp(str, "E") == 0) { + return SRSRAN_SSB_PATTERN_E; + } + + return SRSRAN_SSB_PATTERN_INVALID; +} From 52e00d6376b35b86cd04e56c4c94e6350e0cc226 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 7 Oct 2021 11:09:27 +0200 Subject: [PATCH 055/208] Fix PBCH encoding and added unit test --- lib/src/phy/phch/pbch_nr.c | 8 ++++++-- lib/src/phy/sync/ssb.c | 6 +++++- lib/src/phy/sync/test/CMakeLists.txt | 24 +++++++++++++++++++----- lib/src/phy/sync/test/ssb_decode_test.c | 23 +++++++++++++++++++---- lib/src/phy/sync/test/ssb_measure_test.c | 24 ++++++++++++++++++++---- 5 files changed, 69 insertions(+), 16 deletions(-) diff --git a/lib/src/phy/phch/pbch_nr.c b/lib/src/phy/phch/pbch_nr.c index a96cea33b..3b20a0aaa 100644 --- a/lib/src/phy/phch/pbch_nr.c +++ b/lib/src/phy/phch/pbch_nr.c @@ -410,9 +410,11 @@ static void pbch_nr_scramble_tx(const srsran_pbch_nr_cfg_t* cfg, uint32_t M_bit = PBCH_NR_E; // Select value v - uint32_t v = (ssb_idx & 0x7U); + // for L max = 8 or L max = 64 , & is the three least significant bits of the SS/PBCH block index + uint32_t v = (ssb_idx & 0b111U); if (cfg->Lmax == 4) { - v = ssb_idx & 0x3U; + // for L max = 4 , & is the two least significant bits of the SS/PBCH block index + v = ssb_idx & 0b11U; } // Advance sequence @@ -435,8 +437,10 @@ static void pbch_nr_scramble_rx(const srsran_pbch_nr_cfg_t* cfg, uint32_t M_bit = PBCH_NR_E; // Select value v + // for L max = 8 or L max = 64 , & is the three least significant bits of the SS/PBCH block index uint32_t v = (ssb_idx & 0b111U); if (cfg->Lmax == 4) { + // for L max = 4 , & is the two least significant bits of the SS/PBCH block index v = ssb_idx & 0b11U; } diff --git a/lib/src/phy/sync/ssb.c b/lib/src/phy/sync/ssb.c index d0462ee09..7ac2352a8 100644 --- a/lib/src/phy/sync/ssb.c +++ b/lib/src/phy/sync/ssb.c @@ -558,10 +558,11 @@ int srsran_ssb_add(srsran_ssb_t* q, uint32_t N_id, const srsran_pbch_msg_nr_t* m // Put PBCH DMRS srsran_dmrs_pbch_cfg_t pbch_dmrs_cfg = {}; pbch_dmrs_cfg.N_id = N_id; - pbch_dmrs_cfg.n_hf = msg->hrf ? 0 : 1; + pbch_dmrs_cfg.n_hf = msg->hrf ? 1 : 0; pbch_dmrs_cfg.ssb_idx = msg->ssb_idx; pbch_dmrs_cfg.L_max = q->Lmax; pbch_dmrs_cfg.beta = 0.0f; + pbch_dmrs_cfg.scs = q->cfg.scs; if (srsran_dmrs_pbch_put(&pbch_dmrs_cfg, ssb_grid) < SRSRAN_SUCCESS) { ERROR("Error putting PBCH DMRS"); return SRSRAN_ERROR; @@ -570,7 +571,10 @@ int srsran_ssb_add(srsran_ssb_t* q, uint32_t N_id, const srsran_pbch_msg_nr_t* m // Put PBCH payload srsran_pbch_nr_cfg_t pbch_cfg = {}; pbch_cfg.N_id = N_id; + pbch_cfg.n_hf = msg->hrf; + pbch_cfg.ssb_idx = msg->ssb_idx; pbch_cfg.Lmax = q->Lmax; + pbch_cfg.beta = 0.0f; if (srsran_pbch_nr_encode(&q->pbch, &pbch_cfg, msg, ssb_grid) < SRSRAN_SUCCESS) { ERROR("Error encoding PBCH"); return SRSRAN_ERROR; diff --git a/lib/src/phy/sync/test/CMakeLists.txt b/lib/src/phy/sync/test/CMakeLists.txt index 6878da0db..776af07e8 100644 --- a/lib/src/phy/sync/test/CMakeLists.txt +++ b/lib/src/phy/sync/test/CMakeLists.txt @@ -137,11 +137,25 @@ target_link_libraries(ssb_decode_test srsran_phy) foreach (SSB_SCS 15 30) # For each supported Cell/Carrier subcarrier spacing foreach (CELL_SCS 15 30) - # Test SSB measurements - add_nr_test(ssb_measure_test_${SSB_SCS}_${CELL_SCS} ssb_measure_test -s ${SSB_SCS} -S ${CELL_SCS}) - - # Test SSB PBCH decoding - add_nr_test(ssb_decode_test_${SSB_SCS}_${CELL_SCS} ssb_decode_test -s ${SSB_SCS} -S ${CELL_SCS}) + # For 1.0 GHz and 3.5 GHz Center frequencies + foreach (CELL_FREQ 1000000000 3500000000) + # For SSB centered at -960, 0 and 960 kHz from the center frequency + foreach (SSB_OFFSET_FREQ -960000 0 960000) + # For patterns A, B, C + foreach (SSB_PATTERN A B C) + # Calculate Actual SSB center frequency + math(EXPR SSB_FREQ "${CELL_FREQ} + ${SSB_OFFSET_FREQ}") + + # Test SSB measurements + add_nr_test(ssb_measure_test_${CELL_FREQ}_${CELL_SCS}_${SSB_FREQ}_${SSB_SCS}_${SSB_PATTERN} ssb_measure_test + -F ${CELL_FREQ} -S ${CELL_SCS} -f ${SSB_FREQ} -s ${SSB_SCS}) + + # Test SSB PBCH decoding + add_nr_test(ssb_decode_test_${CELL_FREQ}_${CELL_SCS}_${SSB_FREQ}_${SSB_SCS}_${SSB_PATTERN} ssb_decode_test + -F ${CELL_FREQ} -S ${CELL_SCS} -f ${SSB_FREQ} -s ${SSB_SCS}) + endforeach () + endforeach () + endforeach () endforeach () endforeach () diff --git a/lib/src/phy/sync/test/ssb_decode_test.c b/lib/src/phy/sync/test/ssb_decode_test.c index 91377ea88..be0fd322f 100644 --- a/lib/src/phy/sync/test/ssb_decode_test.c +++ b/lib/src/phy/sync/test/ssb_decode_test.c @@ -23,7 +23,10 @@ // NR parameters static uint32_t carrier_nof_prb = 52; static srsran_subcarrier_spacing_t carrier_scs = srsran_subcarrier_spacing_15kHz; +static double carrier_freq_hz = 3.5e9 + 960e3; static srsran_subcarrier_spacing_t ssb_scs = srsran_subcarrier_spacing_30kHz; +static double ssb_freq_hz = 3.5e9; +static srsran_ssb_patern_t ssb_pattern = SRSRAN_SSB_PATTERN_A; // Channel parameters static cf_t wideband_gain = 1.0f + 0.5 * I; @@ -42,14 +45,17 @@ static void usage(char* prog) { printf("Usage: %s [v]\n", prog); printf("\t-s SSB subcarrier spacing [default, %s kHz]\n", srsran_subcarrier_spacing_to_str(ssb_scs)); + printf("\t-f SSB center frequency [default, %.3f MHz]\n", ssb_freq_hz / 1e6); printf("\t-S cell/carrier subcarrier spacing [default, %s kHz]\n", srsran_subcarrier_spacing_to_str(carrier_scs)); + printf("\t-F cell/carrier center frequency in Hz [default, %.3f MHz]\n", carrier_freq_hz / 1e6); + printf("\t-P SSB pattern [default, %s]\n", srsran_ssb_pattern_to_str(ssb_pattern)); printf("\t-v [set srsran_verbose to debug, default none]\n"); } static void parse_args(int argc, char** argv) { int opt; - while ((opt = getopt(argc, argv, "Ssv")) != -1) { + while ((opt = getopt(argc, argv, "SsFfv")) != -1) { switch (opt) { case 's': ssb_scs = srsran_subcarrier_spacing_from_str(argv[optind]); @@ -58,6 +64,9 @@ static void parse_args(int argc, char** argv) exit(-1); } break; + case 'f': + ssb_freq_hz = strtod(argv[optind], NULL); + break; case 'S': carrier_scs = srsran_subcarrier_spacing_from_str(argv[optind]); if (carrier_scs == srsran_subcarrier_spacing_invalid) { @@ -65,6 +74,12 @@ static void parse_args(int argc, char** argv) exit(-1); } break; + case 'F': + carrier_freq_hz = strtod(argv[optind], NULL); + break; + case 'P': + ssb_pattern = srsran_ssb_pattern_fom_str(argv[optind]); + break; case 'v': srsran_verbose++; break; @@ -114,10 +129,10 @@ static int test_case_1(srsran_ssb_t* ssb) // SSB configuration srsran_ssb_cfg_t ssb_cfg = {}; ssb_cfg.srate_hz = srate_hz; - ssb_cfg.center_freq_hz = 3.5e9; - ssb_cfg.ssb_freq_hz = 3.5e9 - 960e3; + ssb_cfg.center_freq_hz = carrier_freq_hz; + ssb_cfg.ssb_freq_hz = ssb_freq_hz; ssb_cfg.scs = ssb_scs; - ssb_cfg.pattern = SRSRAN_SSB_PATTERN_C; + ssb_cfg.pattern = ssb_pattern; TESTASSERT(srsran_ssb_set_cfg(ssb, &ssb_cfg) == SRSRAN_SUCCESS); diff --git a/lib/src/phy/sync/test/ssb_measure_test.c b/lib/src/phy/sync/test/ssb_measure_test.c index 830d0a5e9..5ecad89ee 100644 --- a/lib/src/phy/sync/test/ssb_measure_test.c +++ b/lib/src/phy/sync/test/ssb_measure_test.c @@ -21,7 +21,10 @@ // NR parameters static uint32_t carrier_nof_prb = 52; static srsran_subcarrier_spacing_t carrier_scs = srsran_subcarrier_spacing_15kHz; +static double carrier_freq_hz = 3.5e9 + 960e3; static srsran_subcarrier_spacing_t ssb_scs = srsran_subcarrier_spacing_30kHz; +static double ssb_freq_hz = 3.5e9; +static srsran_ssb_patern_t ssb_pattern = SRSRAN_SSB_PATTERN_A; // Channel parameters static int32_t delay_n = 1; @@ -46,14 +49,18 @@ static void usage(char* prog) { printf("Usage: %s [v]\n", prog); printf("\t-s SSB subcarrier spacing [default, %s kHz]\n", srsran_subcarrier_spacing_to_str(ssb_scs)); + printf("\t-f SSB center frequency [default, %.3f MHz]\n", ssb_freq_hz / 1e6); printf("\t-S cell/carrier subcarrier spacing [default, %s kHz]\n", srsran_subcarrier_spacing_to_str(carrier_scs)); + printf("\t-F cell/carrier center frequency in Hz [default, %.3f MHz]\n", carrier_freq_hz / 1e6); + printf("\t-P SSB pattern [default, %s]\n", srsran_ssb_pattern_to_str(ssb_pattern)); printf("\t-v [set srsran_verbose to debug, default none]\n"); } + static void parse_args(int argc, char** argv) { int opt; - while ((opt = getopt(argc, argv, "Ssv")) != -1) { + while ((opt = getopt(argc, argv, "SsFfv")) != -1) { switch (opt) { case 's': ssb_scs = srsran_subcarrier_spacing_from_str(argv[optind]); @@ -62,6 +69,9 @@ static void parse_args(int argc, char** argv) exit(-1); } break; + case 'f': + ssb_freq_hz = strtod(argv[optind], NULL); + break; case 'S': carrier_scs = srsran_subcarrier_spacing_from_str(argv[optind]); if (carrier_scs == srsran_subcarrier_spacing_invalid) { @@ -69,6 +79,12 @@ static void parse_args(int argc, char** argv) exit(-1); } break; + case 'F': + carrier_freq_hz = strtod(argv[optind], NULL); + break; + case 'P': + ssb_pattern = srsran_ssb_pattern_fom_str(argv[optind]); + break; case 'v': srsran_verbose++; break; @@ -114,10 +130,10 @@ static int test_case_1(srsran_ssb_t* ssb) // SSB configuration srsran_ssb_cfg_t ssb_cfg = {}; ssb_cfg.srate_hz = srate_hz; - ssb_cfg.center_freq_hz = 3.5e9; - ssb_cfg.ssb_freq_hz = 3.5e9 - 960e3; + ssb_cfg.center_freq_hz = carrier_freq_hz; + ssb_cfg.ssb_freq_hz = ssb_freq_hz; ssb_cfg.scs = ssb_scs; - ssb_cfg.pattern = SRSRAN_SSB_PATTERN_C; + ssb_cfg.pattern = ssb_pattern; TESTASSERT(srsran_ssb_set_cfg(ssb, &ssb_cfg) == SRSRAN_SUCCESS); From 5afe20e7da92cd71c3cab811bc70be92631e9623 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 7 Oct 2021 11:10:10 +0200 Subject: [PATCH 056/208] UE loads SSB config from helper method --- srsue/src/phy/nr/cc_worker.cc | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index 9d1f04e8e..353ee8af3 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -85,15 +85,8 @@ bool cc_worker::update_cfg() return false; } - srsran_ssb_cfg_t ssb_cfg = {}; + srsran_ssb_cfg_t ssb_cfg = phy.cfg.get_ssb_cfg(); ssb_cfg.srate_hz = srsran_min_symbol_sz_rb(phy.cfg.carrier.nof_prb) * SRSRAN_SUBC_SPACING_NR(phy.cfg.carrier.scs); - ssb_cfg.center_freq_hz = phy.cfg.carrier.dl_center_frequency_hz; - ssb_cfg.ssb_freq_hz = phy.cfg.carrier.ssb_center_freq_hz; - ssb_cfg.scs = phy.cfg.ssb.scs; - ssb_cfg.pattern = phy.cfg.ssb.pattern; - ssb_cfg.duplex_mode = phy.cfg.duplex.mode; - ssb_cfg.periodicity_ms = phy.cfg.ssb.periodicity_ms; - if (srsran_ssb_set_cfg(&ssb, &ssb_cfg) < SRSRAN_SUCCESS) { logger.error("Error setting SSB configuration"); return false; From 954d6f5f8dc466848a6cba0f24e499e174493392 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 7 Oct 2021 11:11:52 +0200 Subject: [PATCH 057/208] Removed sfn_4lsb from debug trace --- srsue/src/phy/nr/cc_worker.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index 353ee8af3..c55eb834a 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -394,7 +394,7 @@ bool cc_worker::measure_csi() if (logger.debug.enabled()) { std::array str = {}; srsran_pbch_msg_nr_mib_info(&mib, str.data(), (uint32_t)str.size()); - logger.debug("PBCH-MIB: sfn_4lsb=%d; %s", (dl_slot_cfg.idx / 10) & 0xf, str.data()); + logger.debug("PBCH-MIB: %s", str.data()); } } else { // CRC shall never fail if the UE is in sync From 9d4fd1c5ccba81ff850cfb907c38d597bb6cf0f6 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 7 Oct 2021 11:23:17 +0200 Subject: [PATCH 058/208] Add NR SFN from SSB assertion and fix dummy SSB scheduling --- srsue/src/phy/nr/cc_worker.cc | 6 +++++- test/phy/dummy_gnb_stack.h | 12 +++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index c55eb834a..ec887cceb 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -388,7 +388,11 @@ bool cc_worker::measure_csi() } // Check if the SFN matches - // ... + if (mib.sfn != dl_slot_cfg.idx / SRSRAN_NSLOTS_PER_FRAME_NR(phy.cfg.carrier.scs)) { + logger.error("PBCH-MIB: NR SFN (%d) does not match current SFN (%d)", + mib.sfn, + dl_slot_cfg.idx / SRSRAN_NSLOTS_PER_FRAME_NR(phy.cfg.carrier.scs)); + } // Log MIB information if (logger.debug.enabled()) { diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index 15b841d0b..5e2fab7e5 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -515,8 +515,18 @@ public: // Schedule SSB for (uint32_t ssb_idx = 0; ssb_idx < SRSRAN_SSB_NOF_CANDIDATES; ssb_idx++) { if (phy_cfg.ssb.position_in_burst[ssb_idx]) { + srsran_mib_nr_t mib = {}; + mib.ssb_idx = ssb_idx; + mib.sfn = slot_cfg.idx / SRSRAN_NSLOTS_PER_FRAME_NR(phy_cfg.carrier.scs); + mib.hrf = (slot_cfg.idx % SRSRAN_NSLOTS_PER_FRAME_NR(phy_cfg.carrier.scs)) >= + SRSRAN_NSLOTS_PER_FRAME_NR(phy_cfg.carrier.scs) / 2; + mac_interface_phy_nr::ssb_t ssb = {}; - ssb.pbch_msg.ssb_idx = (uint32_t)ssb_idx; + if (srsran_pbch_msg_nr_mib_pack(&mib, &ssb.pbch_msg) < SRSRAN_SUCCESS) { + logger.error("Error Packing MIB in slot %d", slot_cfg.idx); + continue; + } + ssb.pbch_msg.ssb_idx = (uint32_t)ssb_idx; dl_sched.ssb.push_back(ssb); } } From 8bb23cc74a2d241b0fb4c73e129b640ce082f4df Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 7 Oct 2021 12:06:20 +0200 Subject: [PATCH 059/208] Correct CMake sign --- lib/src/phy/sync/test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/phy/sync/test/CMakeLists.txt b/lib/src/phy/sync/test/CMakeLists.txt index 776af07e8..d416cdc0b 100644 --- a/lib/src/phy/sync/test/CMakeLists.txt +++ b/lib/src/phy/sync/test/CMakeLists.txt @@ -144,7 +144,7 @@ foreach (SSB_SCS 15 30) # For patterns A, B, C foreach (SSB_PATTERN A B C) # Calculate Actual SSB center frequency - math(EXPR SSB_FREQ "${CELL_FREQ} + ${SSB_OFFSET_FREQ}") + math(EXPR SSB_FREQ "${CELL_FREQ} + (${SSB_OFFSET_FREQ})") # Test SSB measurements add_nr_test(ssb_measure_test_${CELL_FREQ}_${CELL_SCS}_${SSB_FREQ}_${SSB_SCS}_${SSB_PATTERN} ssb_measure_test From 4b77127ed6fbf61617b4bee4c19bef378ebb4f92 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 7 Oct 2021 14:55:27 +0200 Subject: [PATCH 060/208] Added missing SSB pattern to unit test --- lib/src/phy/sync/test/CMakeLists.txt | 8 ++++---- lib/src/phy/sync/test/ssb_decode_test.c | 2 +- lib/src/phy/sync/test/ssb_measure_test.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/src/phy/sync/test/CMakeLists.txt b/lib/src/phy/sync/test/CMakeLists.txt index d416cdc0b..acbde2454 100644 --- a/lib/src/phy/sync/test/CMakeLists.txt +++ b/lib/src/phy/sync/test/CMakeLists.txt @@ -140,19 +140,19 @@ foreach (SSB_SCS 15 30) # For 1.0 GHz and 3.5 GHz Center frequencies foreach (CELL_FREQ 1000000000 3500000000) # For SSB centered at -960, 0 and 960 kHz from the center frequency - foreach (SSB_OFFSET_FREQ -960000 0 960000) + foreach (SSB_OFFSET_FREQ -960000 +0 +960000) # For patterns A, B, C foreach (SSB_PATTERN A B C) # Calculate Actual SSB center frequency - math(EXPR SSB_FREQ "${CELL_FREQ} + (${SSB_OFFSET_FREQ})") + math(EXPR SSB_FREQ "${CELL_FREQ}${SSB_OFFSET_FREQ}") # Test SSB measurements add_nr_test(ssb_measure_test_${CELL_FREQ}_${CELL_SCS}_${SSB_FREQ}_${SSB_SCS}_${SSB_PATTERN} ssb_measure_test - -F ${CELL_FREQ} -S ${CELL_SCS} -f ${SSB_FREQ} -s ${SSB_SCS}) + -F ${CELL_FREQ} -S ${CELL_SCS} -f ${SSB_FREQ} -s ${SSB_SCS} -P ${SSB_PATTERN}) # Test SSB PBCH decoding add_nr_test(ssb_decode_test_${CELL_FREQ}_${CELL_SCS}_${SSB_FREQ}_${SSB_SCS}_${SSB_PATTERN} ssb_decode_test - -F ${CELL_FREQ} -S ${CELL_SCS} -f ${SSB_FREQ} -s ${SSB_SCS}) + -F ${CELL_FREQ} -S ${CELL_SCS} -f ${SSB_FREQ} -s ${SSB_SCS} -P ${SSB_PATTERN}) endforeach () endforeach () endforeach () diff --git a/lib/src/phy/sync/test/ssb_decode_test.c b/lib/src/phy/sync/test/ssb_decode_test.c index be0fd322f..c40e8838d 100644 --- a/lib/src/phy/sync/test/ssb_decode_test.c +++ b/lib/src/phy/sync/test/ssb_decode_test.c @@ -55,7 +55,7 @@ static void usage(char* prog) static void parse_args(int argc, char** argv) { int opt; - while ((opt = getopt(argc, argv, "SsFfv")) != -1) { + while ((opt = getopt(argc, argv, "SsFfPv")) != -1) { switch (opt) { case 's': ssb_scs = srsran_subcarrier_spacing_from_str(argv[optind]); diff --git a/lib/src/phy/sync/test/ssb_measure_test.c b/lib/src/phy/sync/test/ssb_measure_test.c index 5ecad89ee..b202c743d 100644 --- a/lib/src/phy/sync/test/ssb_measure_test.c +++ b/lib/src/phy/sync/test/ssb_measure_test.c @@ -60,7 +60,7 @@ static void usage(char* prog) static void parse_args(int argc, char** argv) { int opt; - while ((opt = getopt(argc, argv, "SsFfv")) != -1) { + while ((opt = getopt(argc, argv, "SsFfPv")) != -1) { switch (opt) { case 's': ssb_scs = srsran_subcarrier_spacing_from_str(argv[optind]); From be870d66ad27359591db52f86e477db648ca3394 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 7 Oct 2021 16:30:03 +0200 Subject: [PATCH 061/208] More relaxed SSB measure assertions and reorder SSB test --- lib/src/phy/sync/test/CMakeLists.txt | 12 ++++++------ lib/src/phy/sync/test/ssb_measure_test.c | 7 ++++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/src/phy/sync/test/CMakeLists.txt b/lib/src/phy/sync/test/CMakeLists.txt index acbde2454..95e9d1644 100644 --- a/lib/src/phy/sync/test/CMakeLists.txt +++ b/lib/src/phy/sync/test/CMakeLists.txt @@ -133,14 +133,14 @@ target_link_libraries(ssb_measure_test srsran_phy) add_executable(ssb_decode_test ssb_decode_test.c) target_link_libraries(ssb_decode_test srsran_phy) -# For each supported SSB subcarrier spacing -foreach (SSB_SCS 15 30) +# For 1.0 GHz and 3.5 GHz Center frequencies +foreach (CELL_FREQ 1000000000 3500000000) # For each supported Cell/Carrier subcarrier spacing foreach (CELL_SCS 15 30) - # For 1.0 GHz and 3.5 GHz Center frequencies - foreach (CELL_FREQ 1000000000 3500000000) - # For SSB centered at -960, 0 and 960 kHz from the center frequency - foreach (SSB_OFFSET_FREQ -960000 +0 +960000) + # For SSB centered at -960, 0 and 960 kHz from the center frequency + foreach (SSB_OFFSET_FREQ -960000 +0 +960000) + # For each supported SSB subcarrier spacing + foreach (SSB_SCS 15 30) # For patterns A, B, C foreach (SSB_PATTERN A B C) # Calculate Actual SSB center frequency diff --git a/lib/src/phy/sync/test/ssb_measure_test.c b/lib/src/phy/sync/test/ssb_measure_test.c index b202c743d..e5210af3d 100644 --- a/lib/src/phy/sync/test/ssb_measure_test.c +++ b/lib/src/phy/sync/test/ssb_measure_test.c @@ -27,7 +27,7 @@ static double ssb_freq_hz = 3.5e9; static srsran_ssb_patern_t ssb_pattern = SRSRAN_SSB_PATTERN_A; // Channel parameters -static int32_t delay_n = 1; +static int32_t delay_n = 2; static float cfo_hz = 100.0f; static float n0_dB = -30.0f; @@ -40,8 +40,8 @@ static cf_t* buffer = NULL; // Base-band buffer #define RSRP_MAX_ERROR 1.0f #define EPRE_MAX_ERROR 1.0f -#define N0_MAX_ERROR 2.5f -#define SNR_MAX_ERROR 2.5f +#define N0_MAX_ERROR 3.0f +#define SNR_MAX_ERROR 3.0f #define CFO_MAX_ERROR (cfo_hz * 0.3f) #define DELAY_MAX_ERROR (delay_us * 0.1f) @@ -235,6 +235,7 @@ int main(int argc, char** argv) if (test_case_1(&ssb) != SRSRAN_SUCCESS) { ERROR("test case failed"); + goto clean_exit; } ret = SRSRAN_SUCCESS; From bd186fab2e7c01806c5a0e7f6e860539e4d6f349 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 7 Oct 2021 16:42:07 +0200 Subject: [PATCH 062/208] Fix CMake SSB frequency addition overflow --- lib/src/phy/sync/test/CMakeLists.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/src/phy/sync/test/CMakeLists.txt b/lib/src/phy/sync/test/CMakeLists.txt index 95e9d1644..83741dd5a 100644 --- a/lib/src/phy/sync/test/CMakeLists.txt +++ b/lib/src/phy/sync/test/CMakeLists.txt @@ -134,11 +134,11 @@ add_executable(ssb_decode_test ssb_decode_test.c) target_link_libraries(ssb_decode_test srsran_phy) # For 1.0 GHz and 3.5 GHz Center frequencies -foreach (CELL_FREQ 1000000000 3500000000) +foreach (CELL_FREQ 1000000 3500000) # For each supported Cell/Carrier subcarrier spacing foreach (CELL_SCS 15 30) # For SSB centered at -960, 0 and 960 kHz from the center frequency - foreach (SSB_OFFSET_FREQ -960000 +0 +960000) + foreach (SSB_OFFSET_FREQ -960 +0 +960) # For each supported SSB subcarrier spacing foreach (SSB_SCS 15 30) # For patterns A, B, C @@ -147,12 +147,12 @@ foreach (CELL_FREQ 1000000000 3500000000) math(EXPR SSB_FREQ "${CELL_FREQ}${SSB_OFFSET_FREQ}") # Test SSB measurements - add_nr_test(ssb_measure_test_${CELL_FREQ}_${CELL_SCS}_${SSB_FREQ}_${SSB_SCS}_${SSB_PATTERN} ssb_measure_test - -F ${CELL_FREQ} -S ${CELL_SCS} -f ${SSB_FREQ} -s ${SSB_SCS} -P ${SSB_PATTERN}) + add_nr_test(ssb_measure_test_${CELL_FREQ}000_${CELL_SCS}_${SSB_FREQ}000_${SSB_SCS}_${SSB_PATTERN} ssb_measure_test + -F ${CELL_FREQ}000 -S ${CELL_SCS} -f ${SSB_FREQ}000 -s ${SSB_SCS} -P ${SSB_PATTERN}) # Test SSB PBCH decoding - add_nr_test(ssb_decode_test_${CELL_FREQ}_${CELL_SCS}_${SSB_FREQ}_${SSB_SCS}_${SSB_PATTERN} ssb_decode_test - -F ${CELL_FREQ} -S ${CELL_SCS} -f ${SSB_FREQ} -s ${SSB_SCS} -P ${SSB_PATTERN}) + add_nr_test(ssb_decode_test_${CELL_FREQ}000_${CELL_SCS}_${SSB_FREQ}000_${SSB_SCS}_${SSB_PATTERN} ssb_decode_test + -F ${CELL_FREQ}000 -S ${CELL_SCS} -f ${SSB_FREQ}000 -s ${SSB_SCS} -P ${SSB_PATTERN}) endforeach () endforeach () endforeach () From 5f17c46098a6b658c5ab1f78aee28175783fb704 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 7 Oct 2021 13:08:40 +0200 Subject: [PATCH 063/208] Modify periodic CSI time offset to UL slot --- lib/src/common/phy_cfg_nr_default.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/common/phy_cfg_nr_default.cc b/lib/src/common/phy_cfg_nr_default.cc index d100c8c83..58c8b1fcb 100644 --- a/lib/src/common/phy_cfg_nr_default.cc +++ b/lib/src/common/phy_cfg_nr_default.cc @@ -477,7 +477,7 @@ phy_cfg_nr_default_t::phy_cfg_nr_default_t(const reference_cfg_t& reference_cfg) csi.reports[0].channel_meas_id = 0; csi.reports[0].type = SRSRAN_CSI_REPORT_TYPE_PERIODIC; csi.reports[0].periodic.period = 20; - csi.reports[0].periodic.offset = 10; + csi.reports[0].periodic.offset = 9; csi.reports[0].periodic.resource.format = SRSRAN_PUCCH_NR_FORMAT_2; csi.reports[0].periodic.resource.starting_prb = 51; csi.reports[0].periodic.resource.format = SRSRAN_PUCCH_NR_FORMAT_2; From 4a327ad17de7e7b03d71e8c1d1c4b57dd9d2bb3f Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 7 Oct 2021 13:09:22 +0200 Subject: [PATCH 064/208] Consider CRC length when calculating real LDPC rate --- lib/src/phy/phch/ra_nr.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/lib/src/phy/phch/ra_nr.c b/lib/src/phy/phch/ra_nr.c index e252e2f43..f265578ea 100644 --- a/lib/src/phy/phch/ra_nr.c +++ b/lib/src/phy/phch/ra_nr.c @@ -12,6 +12,7 @@ #include "srsran/phy/phch/ra_nr.h" #include "srsran/phy/ch_estimation/csi_rs.h" +#include "srsran/phy/fec/cbsegm.h" #include "srsran/phy/phch/csi.h" #include "srsran/phy/phch/pdsch_nr.h" #include "srsran/phy/phch/ra_dl_nr.h" @@ -450,6 +451,28 @@ static int ra_nr_assert_csi_rs_dmrs_collision(const srsran_sch_cfg_nr_t* pdsch_c return SRSRAN_SUCCESS; } +uint32_t ra_nr_nof_crc_bits(uint32_t tbs, double R) +{ + srsran_cbsegm_t cbsegm = {}; + srsran_basegraph_t bg = srsran_sch_nr_select_basegraph(tbs, R); + + if (bg == BG1) { + if (srsran_cbsegm_ldpc_bg1(&cbsegm, tbs) != SRSRAN_SUCCESS) { + // This should never fail + ERROR("Error: calculating LDPC BG1 code block segmentation for tbs=%d", tbs); + return 0; + } + } else { + if (srsran_cbsegm_ldpc_bg2(&cbsegm, tbs) != SRSRAN_SUCCESS) { + // This should never fail + ERROR("Error: calculating LDPC BG1 code block segmentation for tbs=%d", tbs); + return 0; + } + } + + return cbsegm.C * cbsegm.L_cb + cbsegm.L_tb; +} + int srsran_ra_nr_fill_tb(const srsran_sch_cfg_nr_t* pdsch_cfg, const srsran_sch_grant_nr_t* grant, uint32_t mcs_idx, @@ -524,7 +547,7 @@ int srsran_ra_nr_fill_tb(const srsran_sch_cfg_nr_t* pdsch_cfg, // Calculate actual rate tb->R_prime = 0.0; if (tb->nof_re != 0) { - tb->R_prime = (double)tb->tbs / (double)tb->nof_bits; + tb->R_prime = (double)(tb->tbs + ra_nr_nof_crc_bits(tb->tbs, tb->R)) / (double)tb->nof_bits; } return SRSRAN_SUCCESS; @@ -1042,7 +1065,10 @@ int srsran_ra_ul_set_grant_uci_nr(const srsran_carrier_nr_t* carrier, pusch_cfg->grant.tb[i].nof_re * srsran_mod_bits_x_symbol(pusch_cfg->grant.tb[i].mod) - Gack - Gcsi1 - Gcsi2; if (pusch_cfg->grant.tb[i].nof_bits > 0) { - pusch_cfg->grant.tb[i].R_prime = (double)pusch_cfg->grant.tb[i].tbs / (double)pusch_cfg->grant.tb[i].nof_bits; + pusch_cfg->grant.tb[i].R_prime = + (double)(pusch_cfg->grant.tb[i].tbs + + ra_nr_nof_crc_bits(pusch_cfg->grant.tb[i].tbs, pusch_cfg->grant.tb[i].R)) / + (double)pusch_cfg->grant.tb[i].nof_bits; } else { pusch_cfg->grant.tb[i].R_prime = NAN; } From 72622879265fe7cff47a7796ac425ecae3d2c242 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 7 Oct 2021 13:10:26 +0200 Subject: [PATCH 065/208] Zero power UCI bits is not an error but KO --- lib/src/phy/phch/uci_nr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/src/phy/phch/uci_nr.c b/lib/src/phy/phch/uci_nr.c index f7934fe7d..31638d696 100644 --- a/lib/src/phy/phch/uci_nr.c +++ b/lib/src/phy/phch/uci_nr.c @@ -633,9 +633,11 @@ static int uci_nr_decode_3_11_bit(srsran_uci_nr_t* q, // Compute average LLR power float pwr = srsran_vec_avg_power_bf(llr, E); + + // If the power measurement is invalid (zero, NAN, INF) then consider it cannot be decoded if (!isnormal(pwr)) { - ERROR("Received all zeros"); - return SRSRAN_ERROR; + *decoded_ok = false; + return SRSRAN_SUCCESS; } // Decode From d30239f47bb47f9f84d414ba7528cdd804e33336 Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 7 Oct 2021 17:59:33 +0100 Subject: [PATCH 066/208] sched,nr: check existence of rnti before processing feedback --- srsenb/src/stack/mac/nr/sched_nr.cc | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/srsenb/src/stack/mac/nr/sched_nr.cc b/srsenb/src/stack/mac/nr/sched_nr.cc index 441322cdc..270bc998c 100644 --- a/srsenb/src/stack/mac/nr/sched_nr.cc +++ b/srsenb/src/stack/mac/nr/sched_nr.cc @@ -173,18 +173,35 @@ void sched_nr::ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) void sched_nr::ul_sr_info(uint16_t rnti) { - sched_workers->enqueue_event(rnti, [this, rnti]() { ue_db[rnti]->ul_sr_info(); }); + sched_workers->enqueue_event(rnti, [this, rnti]() { + if (ue_db.contains(rnti)) { + ue_db[rnti]->ul_sr_info(); + } else { + logger->warning("Received SR for inexistent rnti=0x%x", rnti); + } + }); } void sched_nr::ul_bsr(uint16_t rnti, uint32_t lcg_id, uint32_t bsr) { - sched_workers->enqueue_event(rnti, [this, rnti, lcg_id, bsr]() { ue_db[rnti]->ul_bsr(lcg_id, bsr); }); + sched_workers->enqueue_event(rnti, [this, rnti, lcg_id, bsr]() { + if (ue_db.contains(rnti)) { + ue_db[rnti]->ul_bsr(lcg_id, bsr); + } else { + logger->warning("Received BSR=%d for inexistent rnti=0x%x", bsr, rnti); + } + }); } void sched_nr::dl_buffer_state(uint16_t rnti, uint32_t lcid, uint32_t newtx, uint32_t retx) { - sched_workers->enqueue_event(rnti, - [this, rnti, lcid, newtx, retx]() { ue_db[rnti]->rlc_buffer_state(lcid, newtx, retx); }); + sched_workers->enqueue_event(rnti, [this, rnti, lcid, newtx, retx]() { + if (ue_db.contains(rnti)) { + ue_db[rnti]->rlc_buffer_state(lcid, newtx, retx); + } else { + logger->warning("Received DL buffer state=%d/%d for inexistent rnti=0x%x", newtx, retx, rnti); + } + }); } #define VERIFY_INPUT(cond, msg, ...) \ From 43a7d822fa26c1b5e903d2be07f3d109bfa63b61 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Thu, 7 Oct 2021 16:32:53 +0200 Subject: [PATCH 067/208] stack,rrc: fix double removal of EPS bearer The EPS bearer was removed twice, causing an error in the logs. Fix issue #3380 Signed-off-by: Carlo Galiotto --- lib/include/srsran/common/bearer_manager.h | 4 ++-- lib/src/common/bearer_manager.cc | 4 ++-- srsenb/src/stack/rrc/rrc_endc.cc | 3 --- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/include/srsran/common/bearer_manager.h b/lib/include/srsran/common/bearer_manager.h index c2bdfc2d4..04cf72bff 100644 --- a/lib/include/srsran/common/bearer_manager.h +++ b/lib/include/srsran/common/bearer_manager.h @@ -51,7 +51,7 @@ public: radio_bearer_t get_radio_bearer(uint32_t eps_bearer_id); - radio_bearer_t get_lcid_bearer(uint32_t lcid); + radio_bearer_t get_eps_bearer_id_for_lcid(uint32_t lcid); private: using eps_rb_map_t = std::map; @@ -119,7 +119,7 @@ public: radio_bearer_t get_lcid_bearer(uint32_t lcid) { srsran::rwlock_read_guard rw_lock(rwlock); - return impl.get_lcid_bearer(lcid); + return impl.get_eps_bearer_id_for_lcid(lcid); } private: diff --git a/lib/src/common/bearer_manager.cc b/lib/src/common/bearer_manager.cc index 8510a1ebe..2c58dac58 100644 --- a/lib/src/common/bearer_manager.cc +++ b/lib/src/common/bearer_manager.cc @@ -58,7 +58,7 @@ ue_bearer_manager_impl::radio_bearer_t ue_bearer_manager_impl::get_radio_bearer( return it != bearers.end() ? it->second : invalid_rb; } -ue_bearer_manager_impl::radio_bearer_t ue_bearer_manager_impl::get_lcid_bearer(uint32_t lcid) +ue_bearer_manager_impl::radio_bearer_t ue_bearer_manager_impl::get_eps_bearer_id_for_lcid(uint32_t lcid) { auto lcid_it = lcid_to_eps_bearer_id.find(lcid); return lcid_it != lcid_to_eps_bearer_id.end() ? bearers.at(lcid_it->second) : invalid_rb; @@ -179,7 +179,7 @@ enb_bearer_manager::radio_bearer_t enb_bearer_manager::get_lcid_bearer(uint16_t if (user_it == users_map.end()) { return srsran::detail::ue_bearer_manager_impl::invalid_rb; } - return user_it->second.get_lcid_bearer(lcid); + return user_it->second.get_eps_bearer_id_for_lcid(lcid); } enb_bearer_manager::radio_bearer_t enb_bearer_manager::get_radio_bearer(uint16_t rnti, uint32_t eps_bearer_id) diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index 8a1ad789e..d99baa5e1 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -280,9 +280,6 @@ void rrc::ue::rrc_endc::handle_sgnb_add_req_ack(wait_sgnb_add_req_resp_st& s, co // TODO: path update procedure with GTPU modify bearer request (for mode 3A and 3X) - // delete EPS bearer mapping over EUTRA PDCP - rrc_enb->bearer_manager.remove_eps_bearer(rrc_ue->rnti, ev.params.eps_bearer_id); - // re-register EPS bearer over NR PDCP rrc_enb->bearer_manager.add_eps_bearer( ev.params.nr_rnti, ev.params.eps_bearer_id, srsran::srsran_rat_t::nr, lcid_drb_nr); From 400d7587c84fecf47a477dc0b1bb96b8af29b8ed Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 8 Oct 2021 09:41:01 +0100 Subject: [PATCH 068/208] lte,rrc,enb: stop rlf timers after the UE performs intra-eNB handover The RLF timers may be triggered before handover, which will lead to the UE getting released after it successfully handovers. To avoid this, we should stop the timers. --- srsenb/src/stack/rrc/rrc_mobility.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index ad35042d1..a356db58a 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -1142,6 +1142,13 @@ void rrc::ue::rrc_mobility::handle_crnti_ce(intraenb_ho_st& s, const user_crnti_ s.last_temp_crnti = ev.temp_crnti; if (is_first_crnti_ce) { + // Stop all running RLF timers + // Note: The RLF timer can be triggered during Handover because the UE did not RLC-ACK the Handover Command + // Once the Handover is complete, to avoid releasing the UE, the RLF timer should stop. + rrc_ue->rlc_rlf_timer.stop(); + rrc_ue->phy_dl_rlf_timer.stop(); + rrc_ue->phy_ul_rlf_timer.stop(); + // Need to reset SNs of bearers. rrc_enb->rlc->reestablish(rrc_ue->rnti); rrc_enb->pdcp->reestablish(rrc_ue->rnti); From c8d6f54dab702e95c5b0acfaf9c1d3382a08f2b9 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 7 Oct 2021 17:07:37 +0200 Subject: [PATCH 069/208] enb,rrc: add radio link monitoring config --- srsenb/hdr/stack/rrc/rrc_nr.h | 1 + srsenb/src/stack/rrc/rrc_nr.cc | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 4fa9b3bfb..9c51c1c9a 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -139,6 +139,7 @@ public: int pack_sp_cell_cfg_ded_init_dl_bwp(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); int pack_sp_cell_cfg_ded_init_dl_bwp_pdcch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); int pack_sp_cell_cfg_ded_init_dl_bwp_pdsch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + int pack_sp_cell_cfg_ded_init_dl_bwp_radio_link_monitoring(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); int pack_sp_cell_cfg_ded_ul_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); int pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 9968128d8..647eb7d64 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -612,6 +612,24 @@ int rrc_nr::ue::pack_sp_cell_cfg_ded_init_dl_bwp(asn1::rrc_nr::cell_group_cfg_s& pack_sp_cell_cfg_ded_init_dl_bwp_pdcch_cfg(cell_group_cfg_pack); pack_sp_cell_cfg_ded_init_dl_bwp_pdsch_cfg(cell_group_cfg_pack); + pack_sp_cell_cfg_ded_init_dl_bwp_radio_link_monitoring(cell_group_cfg_pack); + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_sp_cell_cfg_ded_init_dl_bwp_radio_link_monitoring( + asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.radio_link_monitoring_cfg_present = true; + auto& radio_link_monitoring = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.radio_link_monitoring_cfg; + radio_link_monitoring.set_setup().fail_detection_res_to_add_mod_list_present = true; + + // add resource to detect RLF + radio_link_monitoring.set_setup().fail_detection_res_to_add_mod_list.resize(1); + auto& fail_detec_res_elem = radio_link_monitoring.set_setup().fail_detection_res_to_add_mod_list[0]; + fail_detec_res_elem.radio_link_monitoring_rs_id = 0; + fail_detec_res_elem.purpose = asn1::rrc_nr::radio_link_monitoring_rs_s::purpose_opts::rlf; + fail_detec_res_elem.detection_res.set_ssb_idx() = 0; return SRSRAN_SUCCESS; } From e2ffbd85bc689e24c557b88c74249c5d9966babc Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 7 Oct 2021 17:08:01 +0200 Subject: [PATCH 070/208] enb,rrc: add SIB2 field to display 5G logo ;-) --- srsenb/src/stack/rrc/rrc.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index 283e76a3b..9e478f8ca 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -79,6 +79,14 @@ int32_t rrc::init(const rrc_cfg_t& cfg_, // Loads the PRACH root sequence cfg.sibs[1].sib2().rr_cfg_common.prach_cfg.root_seq_idx = cfg.cell_list[0].root_seq_idx; + if (cfg.num_nr_cells > 0) { + cfg.sibs[1].sib2().ext = true; + cfg.sibs[1].sib2().plmn_info_list_r15.set_present(); + cfg.sibs[1].sib2().plmn_info_list_r15.get()->resize(1); + auto& plmn = cfg.sibs[1].sib2().plmn_info_list_r15.get()->back(); + plmn.upper_layer_ind_r15_present = true; + } + if (generate_sibs() != SRSRAN_SUCCESS) { logger.error("Couldn't generate SIBs."); return false; From 929c6d9fe6b4a28f70a2b515462e9a3b4510072e Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 7 Oct 2021 17:09:06 +0200 Subject: [PATCH 071/208] rrc,endc: avoid sending PHY config dedicated for SCG addition --- srsenb/src/stack/rrc/rrc_endc.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index d99baa5e1..abd997fe5 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -129,6 +129,9 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn conn_recfg->rr_cfg_ded.drb_to_release_list.resize(1); conn_recfg->rr_cfg_ded.drb_to_release_list[0] = 1; + // don't send EUTRA dedicated config again + conn_recfg->rr_cfg_ded.phys_cfg_ded_present = false; + // only add reconfigure EN-DC extension/release 15.10 field if ENDC activation is active conn_recfg->non_crit_ext_present = true; conn_recfg->non_crit_ext.non_crit_ext_present = true; From 93acf57e1aadfad838569d14c19aea637b48d3cc Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 7 Oct 2021 17:09:43 +0200 Subject: [PATCH 072/208] rrc_nr: set cellGroupId and groupId --- srsenb/src/stack/rrc/rrc_nr.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 647eb7d64..52d51cf04 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -1260,6 +1260,8 @@ int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common(asn1::rrc_nr::cell_group int rrc_nr::ue::pack_recfg_with_sync(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) { // Reconfig with Sync + cell_group_cfg_pack.cell_group_id = 1; // 0 identifies the MCG. Other values identify SCGs. + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync_present = true; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.new_ue_id = rnti; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.t304 = recfg_with_sync_s::t304_opts::ms1000; @@ -1273,6 +1275,7 @@ int rrc_nr::ue::pack_secondary_cell_group_sp_cell_cfg(asn1::rrc_nr::cell_group_c { cell_group_cfg_pack.sp_cell_cfg_present = true; cell_group_cfg_pack.sp_cell_cfg.serv_cell_idx_present = true; + cell_group_cfg_pack.sp_cell_cfg.serv_cell_idx = 1; // Serving cell ID of a PSCell. The PCell of the MCG uses ID 0. pack_sp_cell_cfg_ded(cell_group_cfg_pack); pack_recfg_with_sync(cell_group_cfg_pack); From c463ccd961d3b9bb518a3af48c7b832c42654079 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 7 Oct 2021 20:09:15 +0200 Subject: [PATCH 073/208] rrc_endc: pack MAC main config dedicated with DC PHR config --- srsenb/src/stack/rrc/rrc_endc.cc | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index abd997fe5..47d5f6991 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -132,6 +132,29 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn // don't send EUTRA dedicated config again conn_recfg->rr_cfg_ded.phys_cfg_ded_present = false; + // set MAC main config dedicated + conn_recfg->rr_cfg_ded.mac_main_cfg_present = true; + conn_recfg->rr_cfg_ded.mac_main_cfg.set_explicit_value(); + + auto& mac_main_cfg = conn_recfg->rr_cfg_ded.mac_main_cfg.explicit_value(); + + mac_main_cfg.ext = true; + mac_main_cfg.time_align_timer_ded = time_align_timer_opts::infinity; + mac_main_cfg.phr_cfg_present = true; + mac_main_cfg.phr_cfg.set_setup(); + mac_main_cfg.phr_cfg.setup().dl_pathloss_change = + asn1::rrc::mac_main_cfg_s::phr_cfg_c_::setup_s_::dl_pathloss_change_opts::db3; + mac_main_cfg.phr_cfg.setup().periodic_phr_timer = + asn1::rrc::mac_main_cfg_s::phr_cfg_c_::setup_s_::periodic_phr_timer_opts::sf500; + mac_main_cfg.phr_cfg.setup().prohibit_phr_timer = + asn1::rrc::mac_main_cfg_s::phr_cfg_c_::setup_s_::prohibit_phr_timer_opts::sf200; + + mac_main_cfg.mac_main_cfg_v1020.set_present(); + mac_main_cfg.dual_connect_phr.set_present(); + mac_main_cfg.dual_connect_phr.get()->set_setup(); + mac_main_cfg.dual_connect_phr.get()->setup().phr_mode_other_cg_r12 = + asn1::rrc::mac_main_cfg_s::dual_connect_phr_c_::setup_s_::phr_mode_other_cg_r12_opts::real; + // only add reconfigure EN-DC extension/release 15.10 field if ENDC activation is active conn_recfg->non_crit_ext_present = true; conn_recfg->non_crit_ext.non_crit_ext_present = true; From eaf87140e1158175aa11adf15ac1255b9cec31c9 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 7 Oct 2021 22:49:12 +0200 Subject: [PATCH 074/208] rrc_nr: add TAG and PHR config in MAC (but keep it disabled) --- srsenb/src/stack/rrc/rrc_nr.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 52d51cf04..562ffba38 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -601,7 +601,23 @@ int rrc_nr::ue::pack_secondary_cell_group_mac_cfg(asn1::rrc_nr::cell_group_cfg_s mac_cell_group.bsr_cfg_present = true; mac_cell_group.bsr_cfg.periodic_bsr_timer = asn1::rrc_nr::bsr_cfg_s::periodic_bsr_timer_opts::sf20; mac_cell_group.bsr_cfg.retx_bsr_timer = asn1::rrc_nr::bsr_cfg_s::retx_bsr_timer_opts::sf320; + // Skip TAG and PHR config + mac_cell_group.tag_cfg_present = false; + mac_cell_group.tag_cfg.tag_to_add_mod_list_present = true; + mac_cell_group.tag_cfg.tag_to_add_mod_list.resize(1); + mac_cell_group.tag_cfg.tag_to_add_mod_list[0].tag_id = 0; + mac_cell_group.tag_cfg.tag_to_add_mod_list[0].time_align_timer = time_align_timer_opts::infinity; + + mac_cell_group.phr_cfg_present = false; + mac_cell_group.phr_cfg.set_setup(); + mac_cell_group.phr_cfg.setup().phr_periodic_timer = asn1::rrc_nr::phr_cfg_s::phr_periodic_timer_opts::sf500; + mac_cell_group.phr_cfg.setup().phr_prohibit_timer = asn1::rrc_nr::phr_cfg_s::phr_prohibit_timer_opts::sf200; + mac_cell_group.phr_cfg.setup().phr_tx_pwr_factor_change = asn1::rrc_nr::phr_cfg_s::phr_tx_pwr_factor_change_opts::db3; + mac_cell_group.phr_cfg.setup().multiple_phr = true; + mac_cell_group.phr_cfg.setup().dummy = false; + mac_cell_group.phr_cfg.setup().phr_type2_other_cell = false; + mac_cell_group.phr_cfg.setup().phr_mode_other_cg = asn1::rrc_nr::phr_cfg_s::phr_mode_other_cg_opts::real; return SRSRAN_SUCCESS; } From 8118c368d900908f5bc8c828a934fc6ce9652c0e Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 7 Oct 2021 22:49:52 +0200 Subject: [PATCH 075/208] rrc_nr: add missing PRACH config part --- srsenb/src/stack/rrc/rrc_nr.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 562ffba38..15b7b2275 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -1130,6 +1130,10 @@ int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bw rach_cfg_common_pack.setup().prach_root_seq_idx.set_l839() = 0; // matches value in phy_cfg_nr_default_t() rach_cfg_common_pack.setup().restricted_set_cfg = asn1::rrc_nr::rach_cfg_common_s::restricted_set_cfg_opts::unrestricted_set; + rach_cfg_common_pack.setup().ssb_per_rach_occasion_and_cb_preambs_per_ssb_present = true; + rach_cfg_common_pack.setup().ssb_per_rach_occasion_and_cb_preambs_per_ssb.set_one(); + rach_cfg_common_pack.setup().ssb_per_rach_occasion_and_cb_preambs_per_ssb.one() = + asn1::rrc_nr::rach_cfg_common_s::ssb_per_rach_occasion_and_cb_preambs_per_ssb_c_::one_opts::n8; return SRSRAN_SUCCESS; } From b8976ca463a34edd8ffc0d8a530b238186db2598 Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 7 Oct 2021 14:34:58 +0100 Subject: [PATCH 076/208] nr,ue,rrc: avoid configuring the CSI until NR RA is complete --- srsue/hdr/stack/mac_nr/mac_nr.h | 1 + srsue/hdr/stack/mac_nr/mac_nr_interfaces.h | 9 +++---- srsue/hdr/stack/mac_nr/proc_ra_nr.h | 24 +++++++++---------- srsue/src/stack/mac_nr/mac_nr.cc | 5 ++++ srsue/src/stack/mac_nr/proc_ra_nr.cc | 13 +++++----- .../src/stack/mac_nr/test/proc_ra_nr_test.cc | 7 +++--- srsue/src/stack/rrc/rrc_nr.cc | 16 +++++++++++-- 7 files changed, 48 insertions(+), 27 deletions(-) diff --git a/srsue/hdr/stack/mac_nr/mac_nr.h b/srsue/hdr/stack/mac_nr/mac_nr.h index e7e5e03db..ee32663d5 100644 --- a/srsue/hdr/stack/mac_nr/mac_nr.h +++ b/srsue/hdr/stack/mac_nr/mac_nr.h @@ -108,6 +108,7 @@ public: /// RRC void rrc_ra_problem(); + void rrc_ra_completed(); /// stack interface void process_pdus(); diff --git a/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h b/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h index 9d0302122..6421dcd7d 100644 --- a/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h +++ b/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h @@ -24,9 +24,9 @@ class mac_interface_proc_ra_nr { public: // Functions for identity handling, e.g., contention id and c-rnti - virtual uint64_t get_contention_id() = 0; - virtual uint16_t get_crnti() = 0; - virtual bool set_crnti(uint16_t c_rnti) = 0; + virtual uint64_t get_contention_id() = 0; + virtual uint16_t get_crnti() = 0; + virtual bool set_crnti(uint16_t c_rnti) = 0; // Functions for msg3 manipulation which shall be transparent to the procedure virtual bool msg3_is_transmitted() = 0; @@ -35,7 +35,8 @@ public: virtual bool msg3_is_empty() = 0; // RRC functions - virtual void rrc_ra_problem() = 0; + virtual void rrc_ra_problem() = 0; + virtual void rrc_ra_completed() = 0; }; /** diff --git a/srsue/hdr/stack/mac_nr/proc_ra_nr.h b/srsue/hdr/stack/mac_nr/proc_ra_nr.h index 3658c0c59..0e8ee707f 100644 --- a/srsue/hdr/stack/mac_nr/proc_ra_nr.h +++ b/srsue/hdr/stack/mac_nr/proc_ra_nr.h @@ -35,8 +35,8 @@ public: void set_config(const srsran::rach_nr_cfg_t& rach_cfg); bool is_contention_resolution(); - bool is_rar_opportunity(uint32_t tti); - bool has_rar_rnti(); + bool is_rar_opportunity(uint32_t tti); + bool has_rar_rnti(); uint16_t get_rar_rnti(); bool has_temp_crnti(); uint16_t get_temp_crnti(); @@ -61,9 +61,9 @@ private: srsran::ext_task_sched_handle* task_sched = nullptr; srsran::task_multiqueue::queue_handle task_queue; - int ra_window_length = -1, ra_window_start = -1; - uint16_t rar_rnti = SRSRAN_INVALID_RNTI; - uint16_t temp_crnti = SRSRAN_INVALID_RNTI; + int ra_window_length = -1, ra_window_start = -1; + uint16_t rar_rnti = SRSRAN_INVALID_RNTI; + uint16_t temp_crnti = SRSRAN_INVALID_RNTI; std::mutex mutex; srsran::rach_nr_cfg_t rach_cfg = {}; @@ -90,18 +90,18 @@ private: srsran::timer_handler::unique_timer backoff_timer; // 38.321 5.1.1 Variables - uint32_t preamble_index = 0; - uint32_t preamble_transmission_counter = 0; + uint32_t preamble_index = 0; + uint32_t preamble_transmission_counter = 0; uint32_t preamble_backoff = 0; // in ms - uint32_t preamble_power_ramping_step = 0; - int preamble_received_target_power = 0; - uint32_t scaling_factor_bi = 0; + uint32_t preamble_power_ramping_step = 0; + int preamble_received_target_power = 0; + uint32_t scaling_factor_bi = 0; // uint32_t temporary_c_rnti; uint32_t power_offset_2step_ra = 0; // not explicty mentioned uint32_t preambleTransMax = 0; - uint32_t prach_occasion = 0; + uint32_t prach_occasion = 0; uint32_t current_ta = 0; void timer_expired(uint32_t timer_id); @@ -112,7 +112,7 @@ private: void ra_response_reception(const mac_interface_phy_nr::tb_action_dl_result_t& tb); void ra_contention_resolution(); void ra_contention_resolution(uint64_t rx_contention_id); - void ra_completion(); + void ra_completion(); void ra_error(); }; } // namespace srsue diff --git a/srsue/src/stack/mac_nr/mac_nr.cc b/srsue/src/stack/mac_nr/mac_nr.cc index 49a4dd325..a5d0fd09b 100644 --- a/srsue/src/stack/mac_nr/mac_nr.cc +++ b/srsue/src/stack/mac_nr/mac_nr.cc @@ -506,6 +506,11 @@ void mac_nr::rrc_ra_problem() rrc->ra_problem(); } +void mac_nr::rrc_ra_completed() +{ + rrc->ra_completed(); +} + /** * Called from the main stack thread to process received PDUs */ diff --git a/srsue/src/stack/mac_nr/proc_ra_nr.cc b/srsue/src/stack/mac_nr/proc_ra_nr.cc index 745216473..1c088c5f0 100644 --- a/srsue/src/stack/mac_nr/proc_ra_nr.cc +++ b/srsue/src/stack/mac_nr/proc_ra_nr.cc @@ -128,7 +128,7 @@ void proc_ra_nr::timer_expired(uint32_t timer_id) { if (prach_send_timer.id() == timer_id) { logger.warning("PRACH Send timer expired. PRACH was not transmitted within %d ttis by phy. (TODO)", - prach_send_timer.duration()); + prach_send_timer.duration()); ra_error(); } else if (rar_timeout_timer.id() == timer_id) { logger.warning("RAR Timer expired. RA response not received within the response window"); @@ -149,10 +149,10 @@ void proc_ra_nr::ra_procedure_initialization() { mac.msg3_flush(); preamble_transmission_counter = 1; - preamble_power_ramping_step = rach_cfg.powerRampingStep; - scaling_factor_bi = 1; + preamble_power_ramping_step = rach_cfg.powerRampingStep; + scaling_factor_bi = 1; preamble_backoff = 0; - preambleTransMax = rach_cfg.preambleTransMax; + preambleTransMax = rach_cfg.preambleTransMax; ra_resource_selection(); } @@ -278,6 +278,7 @@ void proc_ra_nr::ra_completion() srsran::console("Random Access Complete. c-rnti=0x%x, ta=%d\n", mac.get_crnti(), current_ta); logger.info("Random Access Complete. c-rnti=0x%x, ta=%d", mac.get_crnti(), current_ta); temp_crnti = SRSRAN_INVALID_RNTI; + mac.rrc_ra_completed(); reset(); } @@ -293,9 +294,9 @@ void proc_ra_nr::ra_error() if (preamble_transmission_counter >= rach_cfg.preambleTransMax + 1) { logger.warning("Maximum number of transmissions reached (%d)", rach_cfg.preambleTransMax); // if the Random Access Preamble is transmitted on the SpCell assumption (TODO) - mac.rrc_ra_problem(); // indicate a Random Access problem to upper layers; + mac.rrc_ra_problem(); // indicate a Random Access problem to upper layers; if (started_by == initiators_t::MAC) { // if this Random Access procedure was triggered for SI request - ra_procedure_completed = true; // consider the Random Access procedure unsuccessfully completed. + ra_procedure_completed = true; // consider the Random Access procedure unsuccessfully completed. reset(); } } else { diff --git a/srsue/src/stack/mac_nr/test/proc_ra_nr_test.cc b/srsue/src/stack/mac_nr/test/proc_ra_nr_test.cc index fabf2632e..de994fea7 100644 --- a/srsue/src/stack/mac_nr/test/proc_ra_nr_test.cc +++ b/srsue/src/stack/mac_nr/test/proc_ra_nr_test.cc @@ -73,6 +73,7 @@ public: void msga_flush(){}; // RRC RA problem void rrc_ra_problem() { logger.warning("Dummy MAC RRC ra problem"); } + void rrc_ra_completed() { logger.info("Dummy MAC RRC ra completed"); } private: uint16_t crnti = SRSRAN_INVALID_RNTI; @@ -127,10 +128,10 @@ int proc_ra_normal_test() mac_interface_phy_nr::mac_nr_grant_dl_t grant; grant.rnti = 0x16; grant.tti = rach_cfg.ra_responseWindow + tti_start + 3; - grant.pid = 0x0; + grant.pid = 0x0; uint8_t mac_dl_rar_pdu[] = {0x40, 0x06, 0x68, 0x03, 0x21, 0x46, 0x46, 0x02, 0x00, 0x00, 0x00}; - mac_interface_phy_nr::tb_action_dl_result_t result = {}; - result.payload = srsran::make_byte_buffer(); + mac_interface_phy_nr::tb_action_dl_result_t result = {}; + result.payload = srsran::make_byte_buffer(); TESTASSERT(result.payload != nullptr); result.payload.get()->append_bytes(mac_dl_rar_pdu, sizeof(mac_dl_rar_pdu)); proc_ra_nr.handle_rar_pdu(result); diff --git a/srsue/src/stack/rrc/rrc_nr.cc b/srsue/src/stack/rrc/rrc_nr.cc index af12af83d..e0e59c991 100644 --- a/srsue/src/stack/rrc/rrc_nr.cc +++ b/srsue/src/stack/rrc/rrc_nr.cc @@ -1143,6 +1143,7 @@ bool rrc_nr::apply_sp_cell_ded_ul_pusch(const asn1::rrc_nr::pusch_cfg_s& pusch_c bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg) { + srsran_csi_hl_cfg_t prev_csi = phy_cfg.csi; if (sp_cell_cfg.recfg_with_sync_present) { const recfg_with_sync_s& recfg_with_sync = sp_cell_cfg.recfg_with_sync; mac->set_crnti(recfg_with_sync.new_ue_id); @@ -1305,7 +1306,14 @@ bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg) logger.warning("Option sp_cell_cfg_ded not present"); return false; } - phy->set_config(phy_cfg); + + // Configure PHY + // Note: CSI config is deferred to when RA is complete. See TS 38.331, Section 5.3.5.3 + srsran::phy_cfg_nr_t current_phycfg = phy_cfg; + current_phycfg.csi = prev_csi; + phy->set_config(current_phycfg); + + // Start RA procedure mac->start_ra_procedure(); return true; } @@ -1501,7 +1509,11 @@ void rrc_nr::max_retx_attempted() {} void rrc_nr::protocol_failure() {} // MAC interface -void rrc_nr::ra_completed() {} +void rrc_nr::ra_completed() +{ + logger.info("RA completed. Applying remaining CSI configuration."); + phy->set_config(phy_cfg); +} void rrc_nr::ra_problem() { rrc_eutra->nr_scg_failure_information(scg_failure_cause_t::random_access_problem); From 43b12b9ffb47afe50aefdac24e4cb0ffbfae059a Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 8 Oct 2021 12:04:29 +0100 Subject: [PATCH 077/208] rrc,nr: transfer SSB config to both UE and NR scheduler --- lib/include/srsran/asn1/rrc_nr_utils.h | 4 +- lib/src/asn1/rrc_nr_utils.cc | 4 +- srsenb/hdr/stack/rrc/nr/cell_asn1_config.h | 2 +- srsenb/hdr/stack/rrc/rrc_nr.h | 4 +- srsenb/src/stack/rrc/nr/cell_asn1_config.cc | 65 ++++++++++++++++++++- srsenb/src/stack/rrc/rrc_nr.cc | 60 +++++-------------- 6 files changed, 84 insertions(+), 55 deletions(-) diff --git a/lib/include/srsran/asn1/rrc_nr_utils.h b/lib/include/srsran/asn1/rrc_nr_utils.h index 4a12bf14f..04477dd80 100644 --- a/lib/include/srsran/asn1/rrc_nr_utils.h +++ b/lib/include/srsran/asn1/rrc_nr_utils.h @@ -114,8 +114,8 @@ bool make_phy_carrier_cfg(const asn1::rrc_nr::freq_info_dl_s& freq_info_dl, srsr bool make_phy_ssb_cfg(const srsran_carrier_nr_t& carrier, const asn1::rrc_nr::serving_cell_cfg_common_s& serv_cell_cfg, phy_cfg_nr_t::ssb_cfg_t* ssb); -bool make_pdsch_cfg_from_serv_cell(asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_sch_hl_cfg_nr_t* sch_hl); -bool make_csi_cfg_from_serv_cell(asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_csi_hl_cfg_t* csi_hl); +bool make_pdsch_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_sch_hl_cfg_nr_t* sch_hl); +bool make_csi_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_csi_hl_cfg_t* csi_hl); /*************************** * MAC Config diff --git a/lib/src/asn1/rrc_nr_utils.cc b/lib/src/asn1/rrc_nr_utils.cc index 98ae4abba..751f8e3a5 100644 --- a/lib/src/asn1/rrc_nr_utils.cc +++ b/lib/src/asn1/rrc_nr_utils.cc @@ -1475,7 +1475,7 @@ bool make_phy_ssb_cfg(const srsran_carrier_nr_t& carrier, return true; } -bool make_pdsch_cfg_from_serv_cell(asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_sch_hl_cfg_nr_t* sch_hl) +bool make_pdsch_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_sch_hl_cfg_nr_t* sch_hl) { if (serv_cell.csi_meas_cfg_present and serv_cell.csi_meas_cfg.type().value == @@ -1518,7 +1518,7 @@ bool make_pdsch_cfg_from_serv_cell(asn1::rrc_nr::serving_cell_cfg_s& serv_cell, return true; } -bool make_csi_cfg_from_serv_cell(asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_csi_hl_cfg_t* csi_hl) +bool make_csi_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_csi_hl_cfg_t* csi_hl) { if (serv_cell.csi_meas_cfg_present and serv_cell.csi_meas_cfg.type().value == diff --git a/srsenb/hdr/stack/rrc/nr/cell_asn1_config.h b/srsenb/hdr/stack/rrc/nr/cell_asn1_config.h index 0c59c3990..f204cfd3b 100644 --- a/srsenb/hdr/stack/rrc/nr/cell_asn1_config.h +++ b/srsenb/hdr/stack/rrc/nr/cell_asn1_config.h @@ -18,7 +18,7 @@ namespace srsenb { -int fill_serv_cell_from_enb_cfg(const rrc_nr_cfg_t& cfg, asn1::rrc_nr::serving_cell_cfg_s& serv_cell); +int fill_sp_cell_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, asn1::rrc_nr::sp_cell_cfg_s& sp_cell); } diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 9c51c1c9a..4d8466c86 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -117,7 +117,7 @@ public: bool is_inactive() { return state == rrc_nr_state_t::RRC_INACTIVE; } bool is_endc() { return endc; } uint16_t get_eutra_rnti() { return eutra_rnti; } - void get_metrics(rrc_ue_metrics_t& ue_metrics) { ue_metrics = {}; /*TODO fill RRC metrics*/ }; + void get_metrics(rrc_ue_metrics_t& ue_metrics) { ue_metrics = {}; /*TODO fill RRC metrics*/ }; // setters int pack_rrc_reconfiguration(); @@ -172,8 +172,6 @@ public: int pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bwp_pusch_cfg_common( asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_recfg_with_sync_sp_cell_cfg_common_ssb_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_recfg_with_sync_sp_cell_cfg_common_tdd_ul_dl_cfg_common(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); diff --git a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc index a70d0256b..978de0cda 100644 --- a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc +++ b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc @@ -14,6 +14,11 @@ using namespace asn1::rrc_nr; +#define HANDLE_ERROR(ret) \ + if ((ret) != SRSRAN_SUCCESS) { \ + return SRSRAN_ERROR; \ + } + namespace srsenb { srslog::basic_logger& get_logger(const rrc_nr_cfg_t& cfg) @@ -220,11 +225,67 @@ int fill_csi_meas_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas int fill_serv_cell_from_enb_cfg(const rrc_nr_cfg_t& cfg, serving_cell_cfg_s& serv_cell) { serv_cell.csi_meas_cfg_present = true; - if (fill_csi_meas_from_enb_cfg(cfg, serv_cell.csi_meas_cfg.set_setup()) != SRSRAN_SUCCESS) { + HANDLE_ERROR(fill_csi_meas_from_enb_cfg(cfg, serv_cell.csi_meas_cfg.set_setup())); + + // TODO: remaining fields + + return SRSRAN_SUCCESS; +} + +/// Fill ServingCellConfigCommon with gNB config +int fill_serv_cell_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, serving_cell_cfg_common_s& serv_common) +{ + auto& cell_cfg = cfg.cell_list.at(cc); + + serv_common.ss_pbch_block_pwr = 0; + serv_common.n_timing_advance_offset = asn1::rrc_nr::serving_cell_cfg_common_s::n_timing_advance_offset_opts::n0; + serv_common.dmrs_type_a_position = asn1::rrc_nr::serving_cell_cfg_common_s::dmrs_type_a_position_opts::pos2; + + serv_common.pci_present = true; + serv_common.pci = cell_cfg.phy_cell.carrier.pci; + + serv_common.ssb_periodicity_serving_cell_present = true; + if (not asn1::number_to_enum(serv_common.ssb_periodicity_serving_cell, cell_cfg.ssb_cfg.periodicity_ms)) { + get_logger(cfg).error("Config Error: Invalid SSB periodicity = %d\n", cell_cfg.ssb_cfg.periodicity_ms); return SRSRAN_ERROR; } - // TODO: remaining fields + // Fill SSB config + serv_common.ssb_positions_in_burst_present = true; + if (cfg.cell_list[cc].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { + serv_common.ssb_positions_in_burst.set_short_bitmap().from_number(0b1000); + } else { + serv_common.ssb_positions_in_burst.set_medium_bitmap().from_number(0b10000000); + } + + // Set SSB SCS + serv_common.ssb_subcarrier_spacing_present = true; + if (cfg.cell_list[cc].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { + serv_common.ssb_subcarrier_spacing = subcarrier_spacing_opts::khz15; + } else { + serv_common.ssb_subcarrier_spacing = subcarrier_spacing_opts::khz30; + } + + return SRSRAN_SUCCESS; +} + +/// Fill reconfigurationWithSync with gNB config +int fill_recfg_with_sync_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, recfg_with_sync_s& sync) +{ + sync.sp_cell_cfg_common_present = true; + HANDLE_ERROR(fill_serv_cell_common_from_enb_cfg(cfg, cc, sync.sp_cell_cfg_common)); + + return SRSRAN_SUCCESS; +} + +/// Fill spCellConfig with gNB config +int fill_sp_cell_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, sp_cell_cfg_s& sp_cell) +{ + sp_cell.recfg_with_sync_present = true; + HANDLE_ERROR(fill_recfg_with_sync_from_enb_cfg(cfg, cc, sp_cell.recfg_with_sync)); + + sp_cell.sp_cell_cfg_ded_present = true; + HANDLE_ERROR(fill_serv_cell_from_enb_cfg(cfg, sp_cell.sp_cell_cfg_ded)); return SRSRAN_SUCCESS; } diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 15b7b2275..9901657fc 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -243,10 +243,16 @@ void rrc_nr::config_mac() std::vector sched_cells_cfg = {srsenb::get_default_cells_cfg(1)}; sched_nr_interface::cell_cfg_t& cell = sched_cells_cfg[0]; - asn1::rrc_nr::serving_cell_cfg_s serv_cell; - int ret = fill_serv_cell_from_enb_cfg(cfg, serv_cell); + // Derive ASN1 from config + asn1::rrc_nr::sp_cell_cfg_s sp_cell; + int ret = fill_sp_cell_cfg_from_enb_cfg(cfg, UE_PSCELL_CC_IDX, sp_cell); srsran_assert(ret == SRSRAN_SUCCESS, "Failed to configure cell"); - bool ret2 = srsran::make_pdsch_cfg_from_serv_cell(serv_cell, &cell.bwps[0].pdsch); + + // Derive cell config from ASN1 + bool ret2 = srsran::make_pdsch_cfg_from_serv_cell(sp_cell.sp_cell_cfg_ded, &cell.bwps[0].pdsch); + srsran_assert(ret2, "Invalid NR cell configuration."); + ret2 = srsran::make_phy_ssb_cfg( + cfg.cell_list[0].phy_cell.carrier, sp_cell.recfg_with_sync.sp_cell_cfg_common, &cell.ssb); srsran_assert(ret2, "Invalid NR cell configuration."); // FIXME: entire SI configuration, etc needs to be ported to NR @@ -941,8 +947,10 @@ int rrc_nr::ue::pack_sp_cell_cfg_ded(asn1::rrc_nr::cell_group_cfg_s& cell_group_ // Serving cell config (only to setup) pack_sp_cell_cfg_ded_pdcch_serving_cell_cfg(cell_group_cfg_pack); - // CSI meas config - fill_serv_cell_from_enb_cfg(parent->cfg, cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded); + // spCellConfig + if (fill_sp_cell_cfg_from_enb_cfg(parent->cfg, UE_PSCELL_CC_IDX, cell_group_cfg_pack.sp_cell_cfg) != SRSRAN_SUCCESS) { + parent->logger.error("Failed to pack spCellConfig for rnti=0x%x", rnti); + } return SRSRAN_SUCCESS; } @@ -1086,7 +1094,7 @@ int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_freq_info_ freq_info_ul.freq_band_list_present = true; freq_info_ul.freq_band_list.push_back(parent->cfg.cell_list[0].band); freq_info_ul.absolute_freq_point_a_present = true; - freq_info_ul.absolute_freq_point_a = parent->cfg.cell_list[0].ul_absolute_freq_point_a; + freq_info_ul.absolute_freq_point_a = parent->cfg.cell_list[0].ul_absolute_freq_point_a; freq_info_ul.scs_specific_carrier_list.resize(1); auto& ul_carrier = freq_info_ul.scs_specific_carrier_list[0]; @@ -1202,26 +1210,6 @@ int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common( return SRSRAN_SUCCESS; } -int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_ssb_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - // SSB config (optional) - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_positions_in_burst_present = true; - auto& ssb_pos_in_burst = cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_positions_in_burst; - - if (parent->cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { - ssb_pos_in_burst.set_short_bitmap().from_number(0b1000); - } else { - ssb_pos_in_burst.set_medium_bitmap().from_number(0b10000000); - } - - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_periodicity_serving_cell_present = true; - // TODO: get periodicitiy from cell config - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_periodicity_serving_cell = - serving_cell_cfg_common_s::ssb_periodicity_serving_cell_opts::ms10; - - return SRSRAN_SUCCESS; -} - int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_tdd_ul_dl_cfg_common( asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) { @@ -1242,23 +1230,8 @@ int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common(asn1::rrc_nr::cell_group { auto& pscell_cfg = parent->cfg.cell_list.at(UE_PSCELL_CC_IDX); - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common_present = true; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ss_pbch_block_pwr = 0; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.n_timing_advance_offset = - asn1::rrc_nr::serving_cell_cfg_common_s::n_timing_advance_offset_opts::n0; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dmrs_type_a_position = - asn1::rrc_nr::serving_cell_cfg_common_s::dmrs_type_a_position_opts::pos2; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.pci_present = true; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.pci = pscell_cfg.phy_cell.carrier.pci; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_subcarrier_spacing_present = true; - - if (parent->cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_subcarrier_spacing = - subcarrier_spacing_opts::khz15; - } else { + if (pscell_cfg.duplex_mode == SRSRAN_DUPLEX_MODE_TDD) { cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.smtc.release(); - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_subcarrier_spacing = - subcarrier_spacing_opts::khz30; } // DL config @@ -1267,9 +1240,6 @@ int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common(asn1::rrc_nr::cell_group // UL config pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common(cell_group_cfg_pack); - // SSB config (optional) - pack_recfg_with_sync_sp_cell_cfg_common_ssb_cfg(cell_group_cfg_pack); - if (parent->cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_TDD) { pack_recfg_with_sync_sp_cell_cfg_common_tdd_ul_dl_cfg_common(cell_group_cfg_pack); } From 2e71dc17a5a06fb4eaea822826682630632d735d Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 8 Oct 2021 12:10:10 +0100 Subject: [PATCH 078/208] rrc,nr: transfer SSB config to ue phy_cfg in the scheduler --- srsenb/src/stack/rrc/rrc_nr.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 9901657fc..4c206ae87 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -1395,8 +1395,12 @@ void rrc_nr::ue::crnti_ce_received() uecfg.ue_bearers[drb.lc_ch_id].group = drb.mac_lc_ch_cfg.ul_specific_params.lc_ch_group; } + // Update UE phy params srsran::make_pdsch_cfg_from_serv_cell(cell_group_cfg.sp_cell_cfg.sp_cell_cfg_ded, &uecfg.phy_cfg.pdsch); srsran::make_csi_cfg_from_serv_cell(cell_group_cfg.sp_cell_cfg.sp_cell_cfg_ded, &uecfg.phy_cfg.csi); + srsran::make_phy_ssb_cfg(parent->cfg.cell_list[0].phy_cell.carrier, + cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common, + &uecfg.phy_cfg.ssb); parent->mac->ue_cfg(rnti, uecfg); } From 9dcfa8fdb136e0ce3f7877ce22d76e71365508bb Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 8 Oct 2021 18:02:10 +0100 Subject: [PATCH 079/208] nr,gnb,rrc: pass default rrc_nr_cfg_t to rrc_nr_test --- srsenb/test/rrc/CMakeLists.txt | 4 +-- srsenb/test/rrc/rrc_nr_test.cc | 8 ++--- srsenb/test/rrc/test_helpers.cc | 59 +++++++++++++++++++++------------ srsenb/test/rrc/test_helpers.h | 2 ++ 4 files changed, 45 insertions(+), 28 deletions(-) diff --git a/srsenb/test/rrc/CMakeLists.txt b/srsenb/test/rrc/CMakeLists.txt index 8b440b28c..5cf376160 100644 --- a/srsenb/test/rrc/CMakeLists.txt +++ b/srsenb/test/rrc/CMakeLists.txt @@ -10,8 +10,8 @@ add_library(test_helpers test_helpers.cc) target_link_libraries(test_helpers srsenb_rrc srsenb_common rrc_asn1 rrc_nr_asn1 s1ap_asn1 srsran_common enb_cfg_parser ${LIBCONFIGPP_LIBRARIES}) add_executable(rrc_nr_test rrc_nr_test.cc) -target_link_libraries(rrc_nr_test srsgnb_rrc srsran_common rrc_nr_asn1 ${ATOMIC_LIBS}) -add_test(rrc_nr_test rrc_nr_test) +target_link_libraries(rrc_nr_test srsgnb_rrc test_helpers rrc_nr_asn1 ${ATOMIC_LIBS}) +add_test(rrc_nr_test rrc_nr_test -i ${CMAKE_CURRENT_SOURCE_DIR}/../..) add_executable(rrc_meascfg_test rrc_meascfg_test.cc) target_link_libraries(rrc_meascfg_test test_helpers ${ATOMIC_LIBS}) diff --git a/srsenb/test/rrc/rrc_nr_test.cc b/srsenb/test/rrc/rrc_nr_test.cc index 717f2a643..84e096755 100644 --- a/srsenb/test/rrc/rrc_nr_test.cc +++ b/srsenb/test/rrc/rrc_nr_test.cc @@ -13,6 +13,7 @@ #include "srsenb/hdr/stack/rrc/rrc_nr.h" #include "srsenb/test/common/dummy_classes_common.h" #include "srsenb/test/common/dummy_classes_nr.h" +#include "srsenb/test/rrc/test_helpers.h" #include "srsran/common/test_common.h" #include "srsran/interfaces/gnb_rrc_nr_interfaces.h" #include @@ -75,11 +76,10 @@ int test_rrc_setup() rrc_nr rrc_obj(&task_sched); // set cfg - rrc_nr_cfg_t default_cfg = {}; - rrc_cell_cfg_nr_t cell_cfg = {}; - rrc_nr_cfg_t rrc_cfg_nr = rrc_obj.update_default_cfg(default_cfg); + rrc_cell_cfg_nr_t cell_cfg = {}; + rrc_nr_cfg_t rrc_cfg_nr = rrc_obj.update_default_cfg(rrc_nr_cfg_t{}); + test_helpers::parse_default_cfg(&rrc_cfg_nr); rrc_cfg_nr.cell_list.push_back(cell_cfg); - TESTASSERT(rrc_obj.init(rrc_cfg_nr, &phy_obj, &mac_obj, &rlc_obj, &pdcp_obj, nullptr, nullptr, nullptr) == SRSRAN_SUCCESS); diff --git a/srsenb/test/rrc/test_helpers.cc b/srsenb/test/rrc/test_helpers.cc index a3c890a50..7b1c9e882 100644 --- a/srsenb/test/rrc/test_helpers.cc +++ b/srsenb/test/rrc/test_helpers.cc @@ -46,30 +46,45 @@ int parse_default_cfg_phy(rrc_cfg_t* rrc_cfg, phy_cfg_t* phy_cfg, srsenb::all_ar int parse_default_cfg(rrc_cfg_t* rrc_cfg, srsenb::all_args_t& args) { - args = {}; - *rrc_cfg = {}; - args.enb_files.sib_config = argparse::repository_dir + "/sib.conf.example"; - args.enb_files.rr_config = argparse::repository_dir + "/rr.conf.example"; - args.enb_files.rb_config = argparse::repository_dir + "/rb.conf.example"; - srslog::fetch_basic_logger("TEST").debug("sib file path=%s", args.enb_files.sib_config.c_str()); - - args.enb.enb_id = 0x19B; - args.enb.dl_earfcn = 3400; - args.enb.n_prb = 50; - TESTASSERT(srsran::string_to_mcc("001", &args.stack.s1ap.mcc)); - TESTASSERT(srsran::string_to_mnc("01", &args.stack.s1ap.mnc)); - args.enb.transmission_mode = 1; - args.enb.nof_ports = 1; - args.general.eia_pref_list = "EIA2, EIA1, EIA0"; - args.general.eea_pref_list = "EEA0, EEA2, EEA1"; - args.stack.mac.nof_prealloc_ues = 2; - - args.general.rrc_inactivity_timer = 60000; - - phy_cfg_t phy_cfg; + phy_cfg_t phy_cfg; rrc_nr_cfg_t rrc_cfg_nr; + return parse_default_cfg(&args, rrc_cfg, &phy_cfg, &rrc_cfg_nr); +} - return enb_conf_sections::parse_cfg_files(&args, rrc_cfg, &rrc_cfg_nr, &phy_cfg); +int parse_default_cfg(rrc_nr_cfg_t* rrc_nr_cfg) +{ + srsenb::all_args_t args; + phy_cfg_t phy_cfg; + rrc_cfg_t rrc_cfg; + return parse_default_cfg(&args, &rrc_cfg, &phy_cfg, rrc_nr_cfg); +} + +int parse_default_cfg(srsenb::all_args_t* args, rrc_cfg_t* rrc_cfg, phy_cfg_t* phy_cfg, rrc_nr_cfg_t* rrc_nr_cfg) +{ + *args = {}; + *rrc_cfg = {}; + *phy_cfg = {}; + *rrc_nr_cfg = {}; + + args->enb_files.sib_config = argparse::repository_dir + "/sib.conf.example"; + args->enb_files.rr_config = argparse::repository_dir + "/rr.conf.example"; + args->enb_files.rb_config = argparse::repository_dir + "/rb.conf.example"; + srslog::fetch_basic_logger("TEST").debug("sib file path=%s", args->enb_files.sib_config.c_str()); + + args->enb.enb_id = 0x19B; + args->enb.dl_earfcn = 3400; + args->enb.n_prb = 50; + TESTASSERT(srsran::string_to_mcc("001", &args->stack.s1ap.mcc)); + TESTASSERT(srsran::string_to_mnc("01", &args->stack.s1ap.mnc)); + args->enb.transmission_mode = 1; + args->enb.nof_ports = 1; + args->general.eia_pref_list = "EIA2, EIA1, EIA0"; + args->general.eea_pref_list = "EEA0, EEA2, EEA1"; + args->stack.mac.nof_prealloc_ues = 2; + + args->general.rrc_inactivity_timer = 60000; + + return enb_conf_sections::parse_cfg_files(args, rrc_cfg, rrc_nr_cfg, phy_cfg); } int bring_rrc_to_reconf_state(srsenb::rrc& rrc, srsran::timer_handler& timers, uint16_t rnti) diff --git a/srsenb/test/rrc/test_helpers.h b/srsenb/test/rrc/test_helpers.h index 44d652a96..172194b90 100644 --- a/srsenb/test/rrc/test_helpers.h +++ b/srsenb/test/rrc/test_helpers.h @@ -205,7 +205,9 @@ public: namespace test_helpers { +int parse_default_cfg(srsenb::all_args_t* args, rrc_cfg_t* rrc_cfg, phy_cfg_t* phy_cfg, rrc_nr_cfg_t* rrc_nr_cfg); int parse_default_cfg(rrc_cfg_t* rrc_cfg, srsenb::all_args_t& args); +int parse_default_cfg(rrc_nr_cfg_t* rrc_nr_cfg); int parse_default_cfg_phy(rrc_cfg_t* rrc_cfg, phy_cfg_t* phy_cfg, srsenb::all_args_t& args); template From 479df127751fddc0713db7893cb4de3a749f1156 Mon Sep 17 00:00:00 2001 From: Francisco Date: Sat, 9 Oct 2021 11:46:52 +0100 Subject: [PATCH 080/208] fix rrc_nr_test bad config --- srsenb/test/rrc/CMakeLists.txt | 2 +- srsenb/test/rrc/rrc_nr_test.cc | 27 ++++++++++++++++++++++----- srsenb/test/rrc/test_helpers.cc | 7 +++---- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/srsenb/test/rrc/CMakeLists.txt b/srsenb/test/rrc/CMakeLists.txt index 5cf376160..6861842bd 100644 --- a/srsenb/test/rrc/CMakeLists.txt +++ b/srsenb/test/rrc/CMakeLists.txt @@ -10,7 +10,7 @@ add_library(test_helpers test_helpers.cc) target_link_libraries(test_helpers srsenb_rrc srsenb_common rrc_asn1 rrc_nr_asn1 s1ap_asn1 srsran_common enb_cfg_parser ${LIBCONFIGPP_LIBRARIES}) add_executable(rrc_nr_test rrc_nr_test.cc) -target_link_libraries(rrc_nr_test srsgnb_rrc test_helpers rrc_nr_asn1 ${ATOMIC_LIBS}) +target_link_libraries(rrc_nr_test srsgnb_rrc test_helpers ${ATOMIC_LIBS}) add_test(rrc_nr_test rrc_nr_test -i ${CMAKE_CURRENT_SOURCE_DIR}/../..) add_executable(rrc_meascfg_test rrc_meascfg_test.cc) diff --git a/srsenb/test/rrc/rrc_nr_test.cc b/srsenb/test/rrc/rrc_nr_test.cc index 84e096755..8f012f556 100644 --- a/srsenb/test/rrc/rrc_nr_test.cc +++ b/srsenb/test/rrc/rrc_nr_test.cc @@ -10,6 +10,7 @@ * */ +#include "srsenb/hdr/enb.h" #include "srsenb/hdr/stack/rrc/rrc_nr.h" #include "srsenb/test/common/dummy_classes_common.h" #include "srsenb/test/common/dummy_classes_nr.h" @@ -76,10 +77,15 @@ int test_rrc_setup() rrc_nr rrc_obj(&task_sched); // set cfg - rrc_cell_cfg_nr_t cell_cfg = {}; - rrc_nr_cfg_t rrc_cfg_nr = rrc_obj.update_default_cfg(rrc_nr_cfg_t{}); - test_helpers::parse_default_cfg(&rrc_cfg_nr); - rrc_cfg_nr.cell_list.push_back(cell_cfg); + all_args_t args{}; + phy_cfg_t phy_cfg{}; + rrc_nr_cfg_t rrc_cfg_nr = rrc_obj.update_default_cfg(rrc_nr_cfg_t{}); + rrc_cfg_nr.cell_list.emplace_back(); + rrc_cfg_nr.cell_list[0].phy_cell.carrier.pci = 500; + rrc_cfg_nr.cell_list[0].dl_arfcn = 634240; + rrc_cfg_nr.cell_list[0].band = 78; + args.enb.n_prb = 50; + enb_conf_sections::set_derived_args_nr(&args, &rrc_cfg_nr, &phy_cfg); TESTASSERT(rrc_obj.init(rrc_cfg_nr, &phy_obj, &mac_obj, &rlc_obj, &pdcp_obj, nullptr, nullptr, nullptr) == SRSRAN_SUCCESS); @@ -96,8 +102,19 @@ int test_rrc_setup() } // namespace srsenb -int main() +int main(int argc, char** argv) { + auto& logger = srslog::fetch_basic_logger("ASN1"); + logger.set_level(srslog::basic_levels::info); + + srslog::init(); + + if (argc < 3) { + argparse::usage(argv[0]); + return -1; + } + argparse::parse_args(argc, argv); + // FIXME: disabled temporarily until SIB generation is fixed // TESTASSERT(srsenb::test_sib_generation() == SRSRAN_SUCCESS); TESTASSERT(srsenb::test_rrc_setup() == SRSRAN_SUCCESS); diff --git a/srsenb/test/rrc/test_helpers.cc b/srsenb/test/rrc/test_helpers.cc index 7b1c9e882..0af028974 100644 --- a/srsenb/test/rrc/test_helpers.cc +++ b/srsenb/test/rrc/test_helpers.cc @@ -61,10 +61,9 @@ int parse_default_cfg(rrc_nr_cfg_t* rrc_nr_cfg) int parse_default_cfg(srsenb::all_args_t* args, rrc_cfg_t* rrc_cfg, phy_cfg_t* phy_cfg, rrc_nr_cfg_t* rrc_nr_cfg) { - *args = {}; - *rrc_cfg = {}; - *phy_cfg = {}; - *rrc_nr_cfg = {}; + *args = {}; + *rrc_cfg = {}; + *phy_cfg = {}; args->enb_files.sib_config = argparse::repository_dir + "/sib.conf.example"; args->enb_files.rr_config = argparse::repository_dir + "/rr.conf.example"; From 877b995a4d6a99ce280558f870f6c979080d8362 Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 8 Oct 2021 18:05:38 +0100 Subject: [PATCH 081/208] gnb,nr: add metrics for ack'd TBS in the gNB. --- srsenb/hdr/stack/gnb_stack_nr.h | 4 ++- srsenb/hdr/stack/mac/nr/mac_nr.h | 8 +++++ srsenb/hdr/stack/mac/nr/sched_nr.h | 2 +- srsenb/hdr/stack/mac/nr/sched_nr_interface.h | 14 ++++---- srsenb/hdr/stack/mac/nr/sched_nr_ue.h | 4 +++ srsenb/hdr/stack/mac/nr/sched_nr_worker.h | 7 ++-- srsenb/src/stack/gnb_stack_nr.cc | 35 +++++++++++--------- srsenb/src/stack/mac/mac.cc | 8 ++--- srsenb/src/stack/mac/nr/mac_nr.cc | 33 ++++++++++++++++-- srsenb/src/stack/mac/nr/sched_nr.cc | 15 +++++++-- srsenb/src/stack/mac/nr/sched_nr_harq.cc | 2 +- srsenb/src/stack/mac/nr/sched_nr_worker.cc | 25 +++++++++++++- srsenb/test/mac/nr/sched_nr_test.cc | 4 +-- 13 files changed, 122 insertions(+), 39 deletions(-) diff --git a/srsenb/hdr/stack/gnb_stack_nr.h b/srsenb/hdr/stack/gnb_stack_nr.h index 0a48d1201..83fe9317f 100644 --- a/srsenb/hdr/stack/gnb_stack_nr.h +++ b/srsenb/hdr/stack/gnb_stack_nr.h @@ -123,7 +123,9 @@ private: srsran::task_multiqueue::queue_handle sync_task_queue, ue_task_queue, gtpu_task_queue, mac_task_queue, metrics_task_queue; - srsran::dyn_blocking_queue pending_stack_metrics; + // metrics waiting condition + std::mutex metrics_mutex; + std::condition_variable metrics_cvar; // derived srsenb::mac_nr mac; diff --git a/srsenb/hdr/stack/mac/nr/mac_nr.h b/srsenb/hdr/stack/mac/nr/mac_nr.h index 18bb2a0ee..08af3976a 100644 --- a/srsenb/hdr/stack/mac/nr/mac_nr.h +++ b/srsenb/hdr/stack/mac/nr/mac_nr.h @@ -82,6 +82,9 @@ private: // PDU processing int handle_pdu(srsran::unique_byte_buffer_t pdu); + // Metrics processing + void get_metrics_nolock(srsenb::mac_metrics_t& metrics); + // Encoding srsran::byte_buffer_t* assemble_rar(srsran::const_span grants); srsran::unique_byte_buffer_t rar_pdu_buffer = nullptr; @@ -124,6 +127,11 @@ private: // Number of rach preambles detected for a CC std::vector detected_rachs; + + // Metrics + std::mutex metrics_mutex; + std::condition_variable metrics_condvar; + srsenb::mac_metrics_t* metrics_pending = nullptr; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/mac/nr/sched_nr.h b/srsenb/hdr/stack/mac/nr/sched_nr.h index 8608f7e00..659eb90cf 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr.h @@ -51,7 +51,7 @@ public: void ul_bsr(uint16_t rnti, uint32_t lcg_id, uint32_t bsr) override; void dl_buffer_state(uint16_t rnti, uint32_t lcid, uint32_t newtx, uint32_t retx); - int get_dl_sched(slot_point pdsch_tti, uint32_t cc, dl_sched_res_t& result) override; + int run_slot(slot_point pdsch_tti, uint32_t cc, dl_sched_res_t& result, mac_metrics_t* metrics = nullptr) override; int get_ul_sched(slot_point pusch_tti, uint32_t cc, ul_sched_t& result) override; private: diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index c0813aa5d..4b38a8bc5 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -33,6 +33,8 @@ const static size_t SCHED_NR_MAX_BWP_PER_CELL = 2; const static size_t SCHED_NR_MAX_LCID = 32; const static size_t SCHED_NR_MAX_LC_GROUP = 7; +struct mac_metrics_t; + class sched_nr_interface { public: @@ -119,12 +121,12 @@ public: }; virtual ~sched_nr_interface() = default; - virtual int config(const sched_cfg_t& sched_cfg, srsran::const_span ue_cfg) = 0; - virtual void ue_cfg(uint16_t rnti, const ue_cfg_t& ue_cfg) = 0; - virtual void ue_rem(uint16_t rnti) = 0; - virtual bool ue_exists(uint16_t rnti) = 0; - virtual int get_dl_sched(slot_point slot_rx, uint32_t cc, dl_sched_res_t& result) = 0; - virtual int get_ul_sched(slot_point slot_rx, uint32_t cc, ul_sched_t& result) = 0; + virtual int config(const sched_cfg_t& sched_cfg, srsran::const_span ue_cfg) = 0; + virtual void ue_cfg(uint16_t rnti, const ue_cfg_t& ue_cfg) = 0; + virtual void ue_rem(uint16_t rnti) = 0; + virtual bool ue_exists(uint16_t rnti) = 0; + virtual int run_slot(slot_point slot_rx, uint32_t cc, dl_sched_res_t& result, mac_metrics_t* metrics = nullptr) = 0; + virtual int get_ul_sched(slot_point slot_rx, uint32_t cc, ul_sched_t& result) = 0; virtual void dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) = 0; virtual void ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) = 0; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h index 3887e23ff..b02d14db0 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h @@ -16,6 +16,7 @@ #include "sched_nr_cfg.h" #include "sched_nr_harq.h" #include "sched_nr_interface.h" +#include "srsenb/hdr/stack/mac/common/mac_metrics.h" #include "srsenb/hdr/stack/mac/common/ue_buffer_manager.h" #include "srsran/adt/circular_map.h" #include "srsran/adt/move_callback.h" @@ -73,6 +74,9 @@ public: harq_entity harq_ent; + // metrics + mac_ue_metrics_t metrics = {}; + private: bwp_ue_cfg bwp_cfg; const sched_cell_params& cell_params; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_worker.h b/srsenb/hdr/stack/mac/nr/sched_nr_worker.h index d87404002..47ba12c8b 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_worker.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_worker.h @@ -25,6 +25,9 @@ #include namespace srsenb { + +struct mac_metrics_t; + namespace sched_nr_impl { using dl_sched_t = sched_nr_interface::dl_sched_t; @@ -92,7 +95,7 @@ public: sched_worker_manager(sched_worker_manager&&) = delete; ~sched_worker_manager(); - void run_slot(slot_point slot_tx, uint32_t cc, dl_sched_res_t& dl_res, ul_sched_t& ul_res); + void run_slot(slot_point slot_tx, uint32_t cc, dl_sched_res_t& dl_res, ul_sched_t& ul_res, mac_metrics_t* metrics); void enqueue_event(uint16_t rnti, srsran::move_callback ev); void enqueue_cc_event(uint32_t cc, srsran::move_callback ev); @@ -103,7 +106,7 @@ public: private: void update_ue_db(slot_point slot_tx, bool locked_context); - + void get_metrics(mac_metrics_t& metrics); bool save_sched_result(slot_point pdcch_slot, uint32_t cc, dl_sched_res_t& dl_res, ul_sched_t& ul_res); const sched_params& cfg; diff --git a/srsenb/src/stack/gnb_stack_nr.cc b/srsenb/src/stack/gnb_stack_nr.cc index 62016bd32..417f936a9 100644 --- a/srsenb/src/stack/gnb_stack_nr.cc +++ b/srsenb/src/stack/gnb_stack_nr.cc @@ -25,7 +25,6 @@ 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)), - pending_stack_metrics(64), mac(&task_sched), rrc(&task_sched), pdcp(&task_sched, pdcp_logger), @@ -54,7 +53,7 @@ int gnb_stack_nr::init(const gnb_stack_args_t& args_, x2_interface* x2_) { args = args_; - phy = phy_; + phy = phy_; // setup logging mac_logger.set_level(srslog::str_to_basic_level(args.log.mac_level)); @@ -141,22 +140,28 @@ void gnb_stack_nr::process_pdus() {} bool gnb_stack_nr::get_metrics(srsenb::stack_metrics_t* metrics) { - // use stack thread to query metrics - auto ret = metrics_task_queue.try_push([this]() { - srsenb::stack_metrics_t metrics{}; - mac.get_metrics(metrics.mac); - rrc.get_metrics(metrics.rrc); - if (not pending_stack_metrics.try_push(std::move(metrics))) { - stack_logger.error("Unable to push metrics to queue"); + bool metrics_ready = false; + + // use stack thread to query RRC metrics + auto ret = metrics_task_queue.try_push([this, metrics, &metrics_ready]() { + rrc.get_metrics(metrics->rrc); + { + std::lock_guard lock(metrics_mutex); + metrics_ready = true; } + metrics_cvar.notify_one(); }); - - if (ret.has_value()) { - // wait for result - *metrics = pending_stack_metrics.pop_blocking(); - return true; + if (not ret.has_value()) { + return false; } - return false; + + // obtain MAC metrics (do not use stack thread) + mac.get_metrics(metrics->mac); + + // wait for RRC result + std::unique_lock lock(metrics_mutex); + metrics_cvar.wait(lock, [&metrics_ready]() { return metrics_ready; }); + return true; } // Temporary GW interface diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index 8e66ef59d..88c919f8f 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -588,7 +588,7 @@ int mac::get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res_list) return 0; } - trace_threshold_complete_event("mac::get_dl_sched", "total_time", std::chrono::microseconds(100)); + trace_threshold_complete_event("mac::run_slot", "total_time", std::chrono::microseconds(100)); logger.set_context(TTI_SUB(tti_tx_dl, FDD_HARQ_DELAY_UL_MS)); if (do_padding) { add_padding(); @@ -832,9 +832,9 @@ int mac::get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res int requested_bytes = (mcs_data.tbs / 8 > (int)mch.mtch_sched[mtch_index].lcid_buffer_size) ? (mch.mtch_sched[mtch_index].lcid_buffer_size) : ((mcs_data.tbs / 8) - 2); - int bytes_received = ue_db[SRSRAN_MRNTI]->read_pdu(current_lcid, mtch_payload_buffer, requested_bytes); - mch.pdu[0].lcid = current_lcid; - mch.pdu[0].nbytes = bytes_received; + int bytes_received = ue_db[SRSRAN_MRNTI]->read_pdu(current_lcid, mtch_payload_buffer, requested_bytes); + mch.pdu[0].lcid = current_lcid; + mch.pdu[0].nbytes = bytes_received; mch.mtch_sched[0].mtch_payload = mtch_payload_buffer; dl_sched_res->pdsch[0].dci.rnti = SRSRAN_MRNTI; if (bytes_received) { diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 30654c232..edeb2ac1c 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -76,7 +76,18 @@ void mac_nr::stop() } } +/// Called from metrics thread void mac_nr::get_metrics(srsenb::mac_metrics_t& metrics) +{ + // Requests asynchronously MAC metrics + std::unique_lock lock(metrics_mutex); + metrics_pending = &metrics; + + // Blocks waiting for results + metrics_condvar.wait(lock, [this]() { return metrics_pending == nullptr; }); +} + +void mac_nr::get_metrics_nolock(srsenb::mac_metrics_t& metrics) { srsran::rwlock_read_guard lock(rwlock); metrics.ues.reserve(ue_db.size()); @@ -274,9 +285,25 @@ int mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched slot_point pdsch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx}; sched_nr_interface::dl_sched_res_t dl_res; - int ret = sched.get_dl_sched(pdsch_slot, 0, dl_res); - if (ret != SRSRAN_SUCCESS) { - return ret; + + // Get metrics if requested + { + std::unique_lock metrics_lock(metrics_mutex); + if (metrics_pending != nullptr) { + get_metrics_nolock(*metrics_pending); + } + + // Run Scheduler + int ret = sched.run_slot(pdsch_slot, 0, dl_res, metrics_pending); + + // Notify metrics are filled, if requested + if (metrics_pending != nullptr) { + metrics_pending = nullptr; + metrics_condvar.notify_one(); + } + if (ret != SRSRAN_SUCCESS) { + return ret; + } } dl_sched = dl_res.dl_sched; diff --git a/srsenb/src/stack/mac/nr/sched_nr.cc b/srsenb/src/stack/mac/nr/sched_nr.cc index 270bc998c..827b4bb85 100644 --- a/srsenb/src/stack/mac/nr/sched_nr.cc +++ b/srsenb/src/stack/mac/nr/sched_nr.cc @@ -11,6 +11,7 @@ */ #include "srsenb/hdr/stack/mac/nr/sched_nr.h" +#include "srsenb/hdr/stack/mac/common/mac_metrics.h" #include "srsenb/hdr/stack/mac/nr/harq_softbuffer.h" #include "srsenb/hdr/stack/mac/nr/sched_nr_cell.h" #include "srsenb/hdr/stack/mac/nr/sched_nr_worker.h" @@ -123,13 +124,13 @@ void sched_nr::ue_cfg_impl(uint16_t rnti, const ue_cfg_t& uecfg) } /// Generate {pdcch_slot,cc} scheduling decision -int sched_nr::get_dl_sched(slot_point slot_dl, uint32_t cc, dl_sched_res_t& result) +int sched_nr::run_slot(slot_point slot_dl, uint32_t cc, dl_sched_res_t& result, mac_metrics_t* metrics) { // Copy UL results to intermediate buffer ul_sched_t& ul_res = pending_results->add_ul_result(slot_dl, cc); // Generate {slot_idx,cc} result - sched_workers->run_slot(slot_dl, cc, result, ul_res); + sched_workers->run_slot(slot_dl, cc, result, ul_res, metrics); return SRSRAN_SUCCESS; } @@ -156,7 +157,15 @@ int sched_nr::dl_rach_info(uint32_t cc, const dl_sched_rar_info_t& rar_info) void sched_nr::dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) { sched_workers->enqueue_cc_feedback(rnti, cc, [this, pid, tb_idx, ack](ue_carrier& ue_cc) { - if (ue_cc.harq_ent.dl_ack_info(pid, tb_idx, ack) != SRSRAN_SUCCESS) { + int tbs = ue_cc.harq_ent.dl_ack_info(pid, tb_idx, ack); + if (tbs >= 0) { + if (ack) { + ue_cc.metrics.tx_brate += tbs * 8; + } else { + ue_cc.metrics.tx_errors++; + } + ue_cc.metrics.tx_pkts++; + } else { logger->warning("SCHED: rnti=0x%x, received DL HARQ-ACK for empty pid=%d", ue_cc.rnti, pid); } }); diff --git a/srsenb/src/stack/mac/nr/sched_nr_harq.cc b/srsenb/src/stack/mac/nr/sched_nr_harq.cc index 19800cc0f..0b184f38f 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_harq.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_harq.cc @@ -25,7 +25,7 @@ int harq_proc::ack_info(uint32_t tb_idx, bool ack) if (ack) { tb[tb_idx].active = false; } - return SRSRAN_SUCCESS; + return tb[tb_idx].tbs; } void harq_proc::new_slot(slot_point slot_rx) diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc index d2f0fe44e..8b533511a 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_worker.cc @@ -11,6 +11,7 @@ */ #include "srsenb/hdr/stack/mac/nr/sched_nr_worker.h" +#include "srsenb/hdr/stack/mac/common/mac_metrics.h" #include "srsenb/hdr/stack/mac/nr/sched_nr_signalling.h" #include "srsran/common/string_helpers.h" @@ -255,7 +256,11 @@ void sched_worker_manager::update_ue_db(slot_point slot_tx, bool locked_context) } } -void sched_worker_manager::run_slot(slot_point slot_tx, uint32_t cc, dl_sched_res_t& dl_res, ul_sched_t& ul_res) +void sched_worker_manager::run_slot(slot_point slot_tx, + uint32_t cc, + dl_sched_res_t& dl_res, + ul_sched_t& ul_res, + mac_metrics_t* metrics) { // Fill DL signalling messages that do not depend on UEs state serv_cell_manager& serv_cell = *cells[cc]; @@ -284,6 +289,11 @@ void sched_worker_manager::run_slot(slot_point slot_tx, uint32_t cc, dl_sched_re } update_ue_db(slot_tx, true); + // Obtain MAC metrics if requested + if (metrics != nullptr) { + get_metrics(*metrics); + } + // mark the start of slot. awake remaining workers if locking on the mutex current_slot = slot_tx; worker_count.store(static_cast(cc_worker_list.size()), std::memory_order_relaxed); @@ -359,5 +369,18 @@ bool sched_worker_manager::save_sched_result(slot_point pdcch_slot, return true; } +void sched_worker_manager::get_metrics(mac_metrics_t& metrics) +{ + for (mac_ue_metrics_t& ue_metric : metrics.ues) { + if (ue_db.contains(ue_metric.rnti) and ue_db[ue_metric.rnti]->carriers[0] != nullptr) { + auto& ue_cc = *ue_db[ue_metric.rnti]->carriers[0]; + ue_metric.tx_brate = ue_cc.metrics.tx_brate; + ue_metric.tx_errors = ue_cc.metrics.tx_errors; + ue_metric.tx_pkts = ue_cc.metrics.tx_pkts; + ue_cc.metrics = {}; + } + } +} + } // namespace sched_nr_impl } // namespace srsenb diff --git a/srsenb/test/mac/nr/sched_nr_test.cc b/srsenb/test/mac/nr/sched_nr_test.cc index 8b79a3edb..51f995f6d 100644 --- a/srsenb/test/mac/nr/sched_nr_test.cc +++ b/srsenb/test/mac/nr/sched_nr_test.cc @@ -103,7 +103,7 @@ void sched_nr_cfg_serialized_test() sched_nr_interface::dl_sched_res_t dl_res; sched_nr_interface::ul_sched_t ul_res; auto tp1 = std::chrono::steady_clock::now(); - TESTASSERT(sched_tester.get_sched()->get_dl_sched(slot_tx, cc, dl_res) == SRSRAN_SUCCESS); + TESTASSERT(sched_tester.get_sched()->run_slot(slot_tx, cc, dl_res) == SRSRAN_SUCCESS); TESTASSERT(sched_tester.get_sched()->get_ul_sched(slot_tx, cc, ul_res) == SRSRAN_SUCCESS); auto tp2 = std::chrono::steady_clock::now(); count_per_cc[cc] += std::chrono::duration_cast(tp2 - tp1).count(); @@ -155,7 +155,7 @@ void sched_nr_cfg_parallel_cc_test() sched_nr_interface::dl_sched_res_t dl_res; sched_nr_interface::ul_sched_t ul_res; auto tp1 = std::chrono::steady_clock::now(); - TESTASSERT(sched_tester.get_sched()->get_dl_sched(slot_tx, cc, dl_res) == SRSRAN_SUCCESS); + TESTASSERT(sched_tester.get_sched()->run_slot(slot_tx, cc, dl_res) == SRSRAN_SUCCESS); TESTASSERT(sched_tester.get_sched()->get_ul_sched(slot_tx, cc, ul_res) == SRSRAN_SUCCESS); auto tp2 = std::chrono::steady_clock::now(); nano_count[cc].fetch_add(std::chrono::duration_cast(tp2 - tp1).count(), From 37215238100605c3f1cf81369640cb6226e2a70c Mon Sep 17 00:00:00 2001 From: Francisco Date: Sun, 10 Oct 2021 19:45:04 +0100 Subject: [PATCH 082/208] pdcp,lte: fix debug logging in PDCP, to avoid segmentation fault and crash --- lib/src/pdcp/pdcp_entity_lte.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/src/pdcp/pdcp_entity_lte.cc b/lib/src/pdcp/pdcp_entity_lte.cc index d4be424e1..017b45123 100644 --- a/lib/src/pdcp/pdcp_entity_lte.cc +++ b/lib/src/pdcp/pdcp_entity_lte.cc @@ -472,10 +472,14 @@ void pdcp_entity_lte::update_rx_counts_queue(uint32_t rx_count) rx_counts_info.pop_back(); fmc++; } - logger.debug("Queue too large. Updating. New FMC=%d, new back=%d, new queue_size=%zu", - fmc, - rx_counts_info.back(), - rx_counts_info.size()); + if (not rx_counts_info.empty()) { + logger.debug("Queue too large. Updating. New FMC=%d, new back=%d, new queue_size=%zu", + fmc, + rx_counts_info.back(), + rx_counts_info.size()); + } else { + logger.debug("Queue too large. Updating. New FMC=%d, new queue_size=%zu", fmc, rx_counts_info.size()); + } } if (rx_counts_info.empty()) { From 78f8302839fec2fe5dc274bf03258f89a521f818 Mon Sep 17 00:00:00 2001 From: Francisco Date: Mon, 11 Oct 2021 10:32:17 +0100 Subject: [PATCH 083/208] sched,lte: addition of extra logs in sched ue configuration --- srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc index b29acdbba..355059ee1 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc @@ -98,6 +98,7 @@ void sched_ue_cell::set_ue_cfg(const sched_interface::ue_cfg_t& ue_cfg_) if (ue_cc_idx != prev_ue_cc_idx) { clear_feedback(); harq_ent.reset(); + logger.info("SCHED: Resetting rnti=0x%x, cc=%d HARQs and feedback state", rnti, cell_cfg->enb_cc_idx); } // Update carrier state From 7e0fd2721dc001a3f04c21b6aa5c405ab45b2baa Mon Sep 17 00:00:00 2001 From: Francisco Date: Mon, 11 Oct 2021 10:42:54 +0100 Subject: [PATCH 084/208] sched,lte: disable all SRBs UL during intraenb Handover --- srsenb/src/stack/rrc/mac_controller.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/stack/rrc/mac_controller.cc b/srsenb/src/stack/rrc/mac_controller.cc index 1b4925508..af7a2e174 100644 --- a/srsenb/src/stack/rrc/mac_controller.cc +++ b/srsenb/src/stack/rrc/mac_controller.cc @@ -282,7 +282,7 @@ void mac_controller::handle_intraenb_ho_cmd(const asn1::rrc::rrc_conn_recfg_r8_i set_drb_activation(false); // Stop any SRB UL (including SRs) - for (uint32_t i = srb_to_lcid(lte_srb::srb1); i <= srb_to_lcid(lte_srb::srb2); ++i) { + for (uint32_t i = srb_to_lcid(lte_srb::srb0); i <= srb_to_lcid(lte_srb::srb2); ++i) { current_sched_ue_cfg.ue_bearers[i].direction = mac_lc_ch_cfg_t::DL; } From 1b595b6eff31a0ddbb1b24bf48359904b7b6c143 Mon Sep 17 00:00:00 2001 From: Francisco Date: Mon, 11 Oct 2021 12:01:18 +0100 Subject: [PATCH 085/208] nr,gnb: if no nr cell is initiated, do not enable endc in the LTE RRC --- .../srsran/interfaces/enb_x2_interfaces.h | 5 +++- srsenb/hdr/enb.h | 5 ++-- srsenb/hdr/x2_adapter.h | 25 ++++++++----------- srsenb/src/enb.cc | 12 ++++++--- 4 files changed, 25 insertions(+), 22 deletions(-) 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; } From 2b41efaa23c1017f22d5b3664dcbcca3535c57b3 Mon Sep 17 00:00:00 2001 From: Francisco Date: Mon, 11 Oct 2021 13:19:55 +0100 Subject: [PATCH 086/208] nr,phy,gnb: enable PUSCH debug logging --- srsenb/src/phy/nr/slot_worker.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/srsenb/src/phy/nr/slot_worker.cc b/srsenb/src/phy/nr/slot_worker.cc index 00fc13f2d..fed1aa6e5 100644 --- a/srsenb/src/phy/nr/slot_worker.cc +++ b/srsenb/src/phy/nr/slot_worker.cc @@ -238,7 +238,13 @@ bool slot_worker::work_ul() std::array str; srsran_gnb_ul_pusch_info(&gnb_ul, &pusch.sch, &pusch_info.pusch_data, str.data(), (uint32_t)str.size()); - logger.info("PUSCH: %s", str.data()); + if (logger.debug.enabled()) { + std::array str_extra; + srsran_sch_cfg_nr_info(&pusch.sch, str_extra.data(), (uint32_t)str_extra.size()); + logger.info("PUSCH: %s\n%s", str.data(), str_extra.data()); + } else { + logger.info("PUSCH: %s", str.data()); + } } } From af0bc36de9f2dee1c1c442cd81e4182e6889dc6d Mon Sep 17 00:00:00 2001 From: Francisco Date: Mon, 11 Oct 2021 14:14:18 +0100 Subject: [PATCH 087/208] nr,sched: ensure scheduled RAR grants are reset every slot --- srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc index 297f89a57..671461187 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc @@ -49,6 +49,7 @@ void bwp_slot_grid::reset() pucch.clear(); ssb.clear(); nzp_csi_rs.clear(); + rar.clear(); } bwp_res_grid::bwp_res_grid(const bwp_params& bwp_cfg_) : cfg(&bwp_cfg_) From 4e49508d8f66e0d8a855a51c3e00f6a5099f36f8 Mon Sep 17 00:00:00 2001 From: Francisco Date: Mon, 11 Oct 2021 15:17:11 +0100 Subject: [PATCH 088/208] nr,gnb,mac: fix RAR encoding by resetting the RAR buffer --- lib/src/mac/mac_rar_pdu_nr.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/mac/mac_rar_pdu_nr.cc b/lib/src/mac/mac_rar_pdu_nr.cc index 559954fde..381663b05 100644 --- a/lib/src/mac/mac_rar_pdu_nr.cc +++ b/lib/src/mac/mac_rar_pdu_nr.cc @@ -214,7 +214,8 @@ int mac_rar_pdu_nr::init_tx(byte_buffer_t* buffer_, uint32_t pdu_len_) logger.error("Invalid buffer"); return SRSRAN_ERROR; } - buffer = buffer_; + buffer = buffer_; + buffer->N_bytes = 0; subpdus.clear(); pdu_len = pdu_len_; remaining_len = pdu_len_; From 5910d8847a5d692774291c9cf51551a402e6aaff Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Fri, 17 Sep 2021 17:28:35 +0200 Subject: [PATCH 089/208] Split NAS security ctxt --- srsue/hdr/stack/upper/nas.h | 4 +- srsue/hdr/stack/upper/nas_base.h | 25 +++-- srsue/src/stack/upper/nas.cc | 181 ++++++++++++++++-------------- srsue/src/stack/upper/nas_5g.cc | 38 ++++--- srsue/src/stack/upper/nas_base.cc | 42 +++---- 5 files changed, 155 insertions(+), 135 deletions(-) diff --git a/srsue/hdr/stack/upper/nas.h b/srsue/hdr/stack/upper/nas.h index 010e5978f..3832c0259 100644 --- a/srsue/hdr/stack/upper/nas.h +++ b/srsue/hdr/stack/upper/nas.h @@ -222,8 +222,8 @@ private: void enter_emm_deregistered_initiated(); // security context persistence file - bool read_ctxt_file(nas_sec_ctxt* ctxt); - bool write_ctxt_file(nas_sec_ctxt ctxt_); + bool read_ctxt_file(nas_sec_ctxt* ctxt_, nas_sec_base_ctxt* ctxt_base_); + bool write_ctxt_file(nas_sec_ctxt ctxt_, nas_sec_base_ctxt ctxt_base_); // ctxt file helpers std::string hex_to_string(uint8_t* hex, int size); diff --git a/srsue/hdr/stack/upper/nas_base.h b/srsue/hdr/stack/upper/nas_base.h index 00b719548..5bcc61c03 100644 --- a/srsue/hdr/stack/upper/nas_base.h +++ b/srsue/hdr/stack/upper/nas_base.h @@ -38,28 +38,33 @@ protected: srsran::nas_pcap* pcap = nullptr; // Security context + // Base context applies for LTE and 5G + struct nas_sec_base_ctxt { + uint8_t k_nas_enc[32] = {}; + uint8_t k_nas_int[32] = {}; + srsran::CIPHERING_ALGORITHM_ID_ENUM cipher_algo; + srsran::INTEGRITY_ALGORITHM_ID_ENUM integ_algo; + uint32_t tx_count; + uint32_t rx_count; + }; + + // Only applies for LTE struct nas_sec_ctxt { uint8_t ksi; uint8_t k_asme[32]; - uint32_t tx_count; - uint32_t rx_count; uint32_t k_enb_count; - srsran::CIPHERING_ALGORITHM_ID_ENUM cipher_algo; - srsran::INTEGRITY_ALGORITHM_ID_ENUM integ_algo; LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT guti; }; + // Only applies for 5G struct nas_5g_sec_ctxt { uint8_t ksi; uint8_t k_amf[32]; - uint32_t tx_count; - uint32_t rx_count; }; - nas_sec_ctxt ctxt = {}; - nas_5g_sec_ctxt ctxt_5g = {}; - uint8_t k_nas_enc[32] = {}; - uint8_t k_nas_int[32] = {}; + nas_sec_base_ctxt ctxt_base = {}; + nas_sec_ctxt ctxt = {}; + nas_5g_sec_ctxt ctxt_5g = {}; int parse_security_algorithm_list(std::string algorithm_string, bool* algorithm_caps); diff --git a/srsue/src/stack/upper/nas.cc b/srsue/src/stack/upper/nas.cc index 934da0441..7f6bb8983 100644 --- a/srsue/src/stack/upper/nas.cc +++ b/srsue/src/stack/upper/nas.cc @@ -81,10 +81,11 @@ int nas::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_n cfg = cfg_; - if ((read_ctxt_file(&ctxt))) { - usim->generate_nas_keys(ctxt.k_asme, k_nas_enc, k_nas_int, ctxt.cipher_algo, ctxt.integ_algo); - logger.debug(k_nas_enc, 32, "NAS encryption key - k_nas_enc"); - logger.debug(k_nas_int, 32, "NAS integrity key - k_nas_int"); + if ((read_ctxt_file(&ctxt, &ctxt_base))) { + usim->generate_nas_keys( + ctxt.k_asme, ctxt_base.k_nas_enc, ctxt_base.k_nas_int, ctxt_base.cipher_algo, ctxt_base.integ_algo); + logger.debug(ctxt_base.k_nas_enc, 32, "NAS encryption key - k_nas_enc"); + logger.debug(ctxt_base.k_nas_int, 32, "NAS integrity key - k_nas_int"); } // Configure timers @@ -108,7 +109,7 @@ nas::~nas() {} void nas::stop() { running = false; - write_ctxt_file(ctxt); + write_ctxt_file(ctxt, ctxt_base); } void nas::get_metrics(nas_metrics_t* m) @@ -715,8 +716,12 @@ int nas::apply_security_config(srsran::unique_byte_buffer_t& pdu, uint8_t sec_hd cipher_encrypt(pdu.get()); } if (sec_hdr_type >= LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY) { - integrity_generate( - &k_nas_int[16], ctxt.tx_count, SECURITY_DIRECTION_UPLINK, &pdu->msg[5], pdu->N_bytes - 5, &pdu->msg[1]); + integrity_generate(&ctxt_base.k_nas_int[16], + ctxt_base.tx_count, + SECURITY_DIRECTION_UPLINK, + &pdu->msg[5], + pdu->N_bytes - 5, + &pdu->msg[1]); } } else { logger.error("Invalid PDU size %d", pdu->N_bytes); @@ -1010,7 +1015,7 @@ void nas::parse_attach_accept(uint32_t lcid, unique_byte_buffer_t pdu) enter_emm_deregistered(emm_state_t::deregistered_substate_t::plmn_search); } - ctxt.rx_count++; + ctxt_base.rx_count++; } void nas::parse_attach_reject(uint32_t lcid, unique_byte_buffer_t pdu) @@ -1065,7 +1070,7 @@ void nas::parse_authentication_request(uint32_t lcid, unique_byte_buffer_t pdu, logger.info("Received Authentication Request"); liblte_mme_unpack_authentication_request_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &auth_req); - ctxt.rx_count++; + ctxt_base.rx_count++; // Generate authentication response using RAND, AUTN & KSI-ASME uint16 mcc, mnc; @@ -1121,7 +1126,7 @@ void nas::parse_identity_request(unique_byte_buffer_t pdu, const uint8_t sec_hdr liblte_mme_unpack_identity_request_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &id_req); logger.info("Received Identity Request. ID type: %d", id_req.id_type); - ctxt.rx_count++; + ctxt_base.rx_count++; // do not respond if request is not protected (TS 24.301 Sec. 4.4.4.2) if (sec_hdr_type >= LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY || @@ -1178,27 +1183,31 @@ void nas::parse_security_mode_command(uint32_t lcid, unique_byte_buffer_t pdu) // Reset counters (as per 24.301 5.4.3.2), only needed for initial security mode command if (auth_request) { - ctxt.rx_count = 0; - ctxt.tx_count = 0; + ctxt_base.rx_count = 0; + ctxt_base.tx_count = 0; auth_request = false; } - ctxt.cipher_algo = (CIPHERING_ALGORITHM_ID_ENUM)sec_mode_cmd.selected_nas_sec_algs.type_of_eea; - ctxt.integ_algo = (INTEGRITY_ALGORITHM_ID_ENUM)sec_mode_cmd.selected_nas_sec_algs.type_of_eia; + ctxt_base.cipher_algo = (CIPHERING_ALGORITHM_ID_ENUM)sec_mode_cmd.selected_nas_sec_algs.type_of_eea; + ctxt_base.integ_algo = (INTEGRITY_ALGORITHM_ID_ENUM)sec_mode_cmd.selected_nas_sec_algs.type_of_eia; // Check capabilities - if (!eea_caps[ctxt.cipher_algo] || !eia_caps[ctxt.integ_algo]) { + if (!eea_caps[ctxt_base.cipher_algo] || !eia_caps[ctxt_base.integ_algo]) { logger.warning("Sending Security Mode Reject due to security capabilities mismatch"); send_security_mode_reject(LIBLTE_MME_EMM_CAUSE_UE_SECURITY_CAPABILITIES_MISMATCH); return; } // Generate NAS keys - usim->generate_nas_keys(ctxt.k_asme, k_nas_enc, k_nas_int, ctxt.cipher_algo, ctxt.integ_algo); - logger.info(k_nas_enc, 32, "NAS encryption key - k_nas_enc"); - logger.info(k_nas_int, 32, "NAS integrity key - k_nas_int"); + usim->generate_nas_keys( + ctxt.k_asme, ctxt_base.k_nas_enc, ctxt_base.k_nas_int, ctxt_base.cipher_algo, ctxt_base.integ_algo); + logger.info(ctxt_base.k_nas_enc, 32, "NAS encryption key - k_nas_enc"); + logger.info(ctxt_base.k_nas_int, 32, "NAS integrity key - k_nas_int"); - logger.debug("Generating integrity check. integ_algo:%d, count_dl:%d, lcid:%d", ctxt.integ_algo, ctxt.rx_count, lcid); + logger.debug("Generating integrity check. integ_algo:%d, count_dl:%d, lcid:%d", + ctxt_base.integ_algo, + ctxt_base.rx_count, + lcid); if (not integrity_check(pdu.get())) { logger.warning("Sending Security Mode Reject due to integrity check failure"); @@ -1206,7 +1215,7 @@ void nas::parse_security_mode_command(uint32_t lcid, unique_byte_buffer_t pdu) return; } - ctxt.rx_count++; + ctxt_base.rx_count++; LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sec_mode_comp = {}; if (sec_mode_cmd.imeisv_req_present && LIBLTE_MME_IMEISV_REQUESTED == sec_mode_cmd.imeisv_req) { @@ -1226,7 +1235,7 @@ void nas::parse_security_mode_command(uint32_t lcid, unique_byte_buffer_t pdu) // Pack and send response pdu->clear(); liblte_mme_pack_security_mode_complete_msg( - &sec_mode_comp, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); + &sec_mode_comp, current_sec_hdr, ctxt_base.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); if (pcap != nullptr) { pcap->write_nas(pdu->msg, pdu->N_bytes); } @@ -1237,9 +1246,9 @@ void nas::parse_security_mode_command(uint32_t lcid, unique_byte_buffer_t pdu) } logger.info( - "Sending Security Mode Complete nas_current_ctxt.tx_count=%d, RB=%s", ctxt.tx_count, rrc->get_rb_name(lcid)); + "Sending Security Mode Complete ctxt_base.tx_count=%d, RB=%s", ctxt_base.tx_count, rrc->get_rb_name(lcid)); rrc->write_sdu(std::move(pdu)); - ctxt.tx_count++; + ctxt_base.tx_count++; // switch security header for all following messages current_sec_hdr = LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED; @@ -1278,7 +1287,7 @@ void nas::parse_esm_information_request(uint32_t lcid, unique_byte_buffer_t pdu) logger.info("ESM information request received for beaser=%d, transaction_id=%d", esm_info_req.eps_bearer_id, esm_info_req.proc_transaction_id); - ctxt.rx_count++; + ctxt_base.rx_count++; // send response send_esm_information_response(esm_info_req.proc_transaction_id); @@ -1291,14 +1300,14 @@ void nas::parse_emm_information(uint32_t lcid, unique_byte_buffer_t pdu) std::string str = emm_info_str(&emm_info); logger.info("Received EMM Information: %s", str.c_str()); srsran::console("%s\n", str.c_str()); - ctxt.rx_count++; + ctxt_base.rx_count++; } void nas::parse_detach_request(uint32_t lcid, unique_byte_buffer_t pdu) { LIBLTE_MME_DETACH_REQUEST_MSG_STRUCT detach_request; liblte_mme_unpack_detach_request_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &detach_request); - ctxt.rx_count++; + ctxt_base.rx_count++; logger.info("Received detach request (type=%d). NAS State: %s", detach_request.detach_type.type_of_detach, @@ -1339,7 +1348,7 @@ void nas::parse_activate_dedicated_eps_bearer_context_request(uint32_t lcid, uni request.linked_eps_bearer_id, request.proc_transaction_id); - ctxt.rx_count++; + ctxt_base.rx_count++; LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft = &request.tft; logger.info("Traffic Flow Template: TFT OP code 0x%x, Filter list size %d, Parameter list size %d", tft->tft_op_code, @@ -1390,7 +1399,7 @@ void nas::parse_deactivate_eps_bearer_context_request(unique_byte_buffer_t pdu) request.proc_transaction_id, request.esm_cause); - ctxt.rx_count++; + ctxt_base.rx_count++; // check if bearer exists if (eps_bearer.find(request.eps_bearer_id) == eps_bearer.end()) { @@ -1421,7 +1430,7 @@ void nas::parse_modify_eps_bearer_context_request(srsran::unique_byte_buffer_t p request.eps_bearer_id, request.proc_transaction_id); - ctxt.rx_count++; + ctxt_base.rx_count++; // check if bearer exists const auto it = eps_bearer.find(request.eps_bearer_id); @@ -1452,7 +1461,7 @@ void nas::parse_activate_test_mode(uint32_t lcid, unique_byte_buffer_t pdu) { logger.info("Received Activate test mode"); - ctxt.rx_count++; + ctxt_base.rx_count++; send_activate_test_mode_complete(); } @@ -1475,7 +1484,7 @@ void nas::parse_close_ue_test_loop(uint32_t lcid, unique_byte_buffer_t pdu) break; } - ctxt.rx_count++; + ctxt_base.rx_count++; send_close_ue_test_loop_complete(); } @@ -1484,7 +1493,7 @@ void nas::parse_emm_status(uint32_t lcid, unique_byte_buffer_t pdu) { LIBLTE_MME_EMM_STATUS_MSG_STRUCT emm_status; liblte_mme_unpack_emm_status_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &emm_status); - ctxt.rx_count++; + ctxt_base.rx_count++; switch (emm_status.emm_cause) { case LIBLTE_MME_ESM_CAUSE_INVALID_EPS_BEARER_IDENTITY: @@ -1578,7 +1587,7 @@ void nas::gen_attach_request(srsran::unique_byte_buffer_t& msg) // According to Sec 4.4.5, the attach request is always unciphered, even if a context exists liblte_mme_pack_attach_request_msg( - &attach_req, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)msg.get()); + &attach_req, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY, ctxt_base.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)msg.get()); if (apply_security_config(msg, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY)) { logger.error("Error applying NAS security."); @@ -1598,8 +1607,8 @@ void nas::gen_attach_request(srsran::unique_byte_buffer_t& msg) } if (have_ctxt) { - set_k_enb_count(ctxt.tx_count); - ctxt.tx_count++; + set_k_enb_count(ctxt_base.tx_count); + ctxt_base.tx_count++; } // stop T3411 and T3402 @@ -1631,11 +1640,11 @@ void nas::gen_service_request(srsran::unique_byte_buffer_t& msg) msg->msg[0] = (LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST << 4u) | (LIBLTE_MME_PD_EPS_MOBILITY_MANAGEMENT); msg->N_bytes++; msg->msg[1] = (ctxt.ksi & 0x07u) << 5u; - msg->msg[1] |= ctxt.tx_count & 0x1Fu; + msg->msg[1] |= ctxt_base.tx_count & 0x1Fu; msg->N_bytes++; uint8_t mac[4]; - integrity_generate(&k_nas_int[16], ctxt.tx_count, SECURITY_DIRECTION_UPLINK, &msg->msg[0], 2, &mac[0]); + integrity_generate(&ctxt_base.k_nas_int[16], ctxt_base.tx_count, SECURITY_DIRECTION_UPLINK, &msg->msg[0], 2, &mac[0]); // Set the short MAC msg->msg[2] = mac[2]; msg->N_bytes++; @@ -1645,8 +1654,8 @@ void nas::gen_service_request(srsran::unique_byte_buffer_t& msg) if (pcap != nullptr) { pcap->write_nas(msg->msg, msg->N_bytes); } - set_k_enb_count(ctxt.tx_count); - ctxt.tx_count++; + set_k_enb_count(ctxt_base.tx_count); + ctxt_base.tx_count++; } void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT* msg) @@ -1750,8 +1759,10 @@ void nas::send_detach_request(bool switch_off) detach_request.nas_ksi.tsc_flag = LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE; detach_request.nas_ksi.nas_ksi = ctxt.ksi; logger.info("Sending detach request with GUTI"); // If sent as an Initial UE message, it cannot be ciphered - liblte_mme_pack_detach_request_msg( - &detach_request, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); + liblte_mme_pack_detach_request_msg(&detach_request, + LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY, + ctxt_base.tx_count, + (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); if (pcap != nullptr) { pcap->write_nas(pdu->msg, pdu->N_bytes); @@ -1768,7 +1779,7 @@ void nas::send_detach_request(bool switch_off) usim->get_imsi_vec(detach_request.eps_mobile_id.imsi, 15); logger.info("Sending detach request with IMSI"); liblte_mme_pack_detach_request_msg( - &detach_request, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); + &detach_request, current_sec_hdr, ctxt_base.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); if (pcap != nullptr) { pcap->write_nas(pdu->msg, pdu->N_bytes); @@ -1794,7 +1805,7 @@ void nas::send_detach_request(bool switch_off) } } - ctxt.tx_count++; + ctxt_base.tx_count++; } void nas::send_attach_complete(const uint8_t& transaction_id_, const uint8_t& eps_bearer_id) @@ -1815,7 +1826,7 @@ void nas::send_attach_complete(const uint8_t& transaction_id_, const uint8_t& ep return; } liblte_mme_pack_attach_complete_msg( - &attach_complete, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); + &attach_complete, current_sec_hdr, ctxt_base.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); // Write NAS pcap if (pcap != nullptr) { pcap->write_nas(pdu->msg, pdu->N_bytes); @@ -1831,7 +1842,7 @@ void nas::send_attach_complete(const uint8_t& transaction_id_, const uint8_t& ep logger.info("Sending Attach Complete"); rrc->write_sdu(std::move(pdu)); - ctxt.tx_count++; + ctxt_base.tx_count++; } void nas::send_detach_accept() @@ -1844,7 +1855,8 @@ void nas::send_detach_accept() LIBLTE_MME_DETACH_ACCEPT_MSG_STRUCT detach_accept; bzero(&detach_accept, sizeof(detach_accept)); - liblte_mme_pack_detach_accept_msg(&detach_accept, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); + liblte_mme_pack_detach_accept_msg( + &detach_accept, current_sec_hdr, ctxt_base.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); if (pcap != nullptr) { pcap->write_nas(pdu->msg, pdu->N_bytes); @@ -1874,7 +1886,7 @@ void nas::send_authentication_response(const uint8_t* res, const size_t res_len) } auth_res.res_len = res_len; liblte_mme_pack_authentication_response_msg( - &auth_res, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); + &auth_res, current_sec_hdr, ctxt_base.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); if (pcap != nullptr) { pcap->write_nas(pdu->msg, pdu->N_bytes); @@ -1887,7 +1899,7 @@ void nas::send_authentication_response(const uint8_t* res, const size_t res_len) logger.info("Sending Authentication Response"); rrc->write_sdu(std::move(pdu)); - ctxt.tx_count++; + ctxt_base.tx_count++; } void nas::send_authentication_failure(const uint8_t cause, const uint8_t* auth_fail_param) @@ -1946,7 +1958,8 @@ void nas::send_identity_response(const uint8 id_type) return; } - liblte_mme_pack_identity_response_msg(&id_resp, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); + liblte_mme_pack_identity_response_msg( + &id_resp, current_sec_hdr, ctxt_base.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); // add security if needed if (apply_security_config(pdu, current_sec_hdr)) { @@ -1959,7 +1972,7 @@ void nas::send_identity_response(const uint8 id_type) } rrc->write_sdu(std::move(pdu)); - ctxt.tx_count++; + ctxt_base.tx_count++; } void nas::send_service_request() @@ -1974,11 +1987,11 @@ void nas::send_service_request() msg->msg[0] = (LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST << 4u) | (LIBLTE_MME_PD_EPS_MOBILITY_MANAGEMENT); msg->N_bytes++; msg->msg[1] = (ctxt.ksi & 0x07u) << 5u; - msg->msg[1] |= ctxt.tx_count & 0x1Fu; + msg->msg[1] |= ctxt_base.tx_count & 0x1Fu; msg->N_bytes++; uint8_t mac[4]; - integrity_generate(&k_nas_int[16], ctxt.tx_count, SECURITY_DIRECTION_UPLINK, &msg->msg[0], 2, &mac[0]); + integrity_generate(&ctxt_base.k_nas_int[16], ctxt_base.tx_count, SECURITY_DIRECTION_UPLINK, &msg->msg[0], 2, &mac[0]); // Set the short MAC msg->msg[2] = mac[2]; msg->N_bytes++; @@ -1991,7 +2004,7 @@ void nas::send_service_request() logger.info("Sending service request"); rrc->write_sdu(std::move(msg)); - ctxt.tx_count++; + ctxt_base.tx_count++; } void nas::send_esm_information_response(const uint8 proc_transaction_id) @@ -2091,7 +2104,7 @@ void nas::send_esm_information_response(const uint8 proc_transaction_id) } if (liblte_mme_pack_esm_information_response_msg( - &esm_info_resp, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { + &esm_info_resp, current_sec_hdr, ctxt_base.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { logger.error("Error packing ESM information response."); return; } @@ -2108,7 +2121,7 @@ void nas::send_esm_information_response(const uint8 proc_transaction_id) logger.info(pdu->msg, pdu->N_bytes, "Sending ESM information response"); rrc->write_sdu(std::move(pdu)); - ctxt.tx_count++; + ctxt_base.tx_count++; chap_id++; } @@ -2127,7 +2140,7 @@ void nas::send_activate_dedicated_eps_bearer_context_accept(const uint8_t& proc_ accept.proc_transaction_id = proc_transaction_id; if (liblte_mme_pack_activate_dedicated_eps_bearer_context_accept_msg( - &accept, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { + &accept, current_sec_hdr, ctxt_base.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { logger.error("Error packing Activate Dedicated EPS Bearer context accept."); return; } @@ -2148,7 +2161,7 @@ void nas::send_activate_dedicated_eps_bearer_context_accept(const uint8_t& proc_ accept.proc_transaction_id); rrc->write_sdu(std::move(pdu)); - ctxt.tx_count++; + ctxt_base.tx_count++; } void nas::send_deactivate_eps_bearer_context_accept(const uint8_t& proc_transaction_id, const uint8_t& eps_bearer_id) @@ -2165,7 +2178,7 @@ void nas::send_deactivate_eps_bearer_context_accept(const uint8_t& proc_transact accept.proc_transaction_id = proc_transaction_id; if (liblte_mme_pack_deactivate_eps_bearer_context_accept_msg( - &accept, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { + &accept, current_sec_hdr, ctxt_base.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { logger.error("Error packing Activate EPS Bearer context accept."); return; } @@ -2186,7 +2199,7 @@ void nas::send_deactivate_eps_bearer_context_accept(const uint8_t& proc_transact accept.proc_transaction_id); rrc->write_sdu(std::move(pdu)); - ctxt.tx_count++; + ctxt_base.tx_count++; } void nas::send_modify_eps_bearer_context_accept(const uint8_t& proc_transaction_id, const uint8_t& eps_bearer_id) @@ -2203,7 +2216,7 @@ void nas::send_modify_eps_bearer_context_accept(const uint8_t& proc_transaction_ accept.proc_transaction_id = proc_transaction_id; if (liblte_mme_pack_modify_eps_bearer_context_accept_msg( - &accept, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { + &accept, current_sec_hdr, ctxt_base.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { logger.error("Error packing Modify EPS Bearer context accept."); return; } @@ -2224,7 +2237,7 @@ void nas::send_modify_eps_bearer_context_accept(const uint8_t& proc_transaction_ accept.proc_transaction_id); rrc->write_sdu(std::move(pdu)); - ctxt.tx_count++; + ctxt_base.tx_count++; } void nas::send_activate_test_mode_complete() @@ -2236,7 +2249,7 @@ void nas::send_activate_test_mode_complete() } if (liblte_mme_pack_activate_test_mode_complete_msg( - (LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), current_sec_hdr, ctxt.tx_count)) { + (LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), current_sec_hdr, ctxt_base.tx_count)) { logger.error("Error packing activate test mode complete."); return; } @@ -2253,7 +2266,7 @@ void nas::send_activate_test_mode_complete() logger.info(pdu->msg, pdu->N_bytes, "Sending Activate test mode complete"); rrc->write_sdu(std::move(pdu)); - ctxt.tx_count++; + ctxt_base.tx_count++; } void nas::send_close_ue_test_loop_complete() @@ -2265,7 +2278,7 @@ void nas::send_close_ue_test_loop_complete() } if (liblte_mme_pack_close_ue_test_loop_complete_msg( - (LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), current_sec_hdr, ctxt.tx_count)) { + (LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), current_sec_hdr, ctxt_base.tx_count)) { logger.error("Error packing close UE test loop complete."); return; } @@ -2282,17 +2295,17 @@ void nas::send_close_ue_test_loop_complete() logger.info(pdu->msg, pdu->N_bytes, "Sending Close UE test loop complete"); rrc->write_sdu(std::move(pdu)); - ctxt.tx_count++; + ctxt_base.tx_count++; } /******************************************************************************* * Security context persistence file ******************************************************************************/ -bool nas::read_ctxt_file(nas_sec_ctxt* ctxt_) +bool nas::read_ctxt_file(nas_sec_ctxt* ctxt_, nas_sec_base_ctxt* ctxt_base_) { std::ifstream file; - if (ctxt_ == nullptr) { + if (ctxt_ == nullptr || ctxt_base_ == nullptr) { return false; } @@ -2318,16 +2331,16 @@ bool nas::read_ctxt_file(nas_sec_ctxt* ctxt_) if (!readvar(file, "mme_code=", &ctxt_->guti.mme_code)) { return false; } - if (!readvar(file, "tx_count=", &ctxt_->tx_count)) { + if (!readvar(file, "tx_count=", &ctxt_base_->tx_count)) { return false; } - if (!readvar(file, "rx_count=", &ctxt_->rx_count)) { + if (!readvar(file, "rx_count=", &ctxt_base_->rx_count)) { return false; } - if (!readvar(file, "int_alg=", &ctxt_->integ_algo)) { + if (!readvar(file, "int_alg=", &ctxt_base_->integ_algo)) { return false; } - if (!readvar(file, "enc_alg=", &ctxt_->cipher_algo)) { + if (!readvar(file, "enc_alg=", &ctxt_base_->cipher_algo)) { return false; } if (!readvar(file, "ksi=", &ctxt_->ksi)) { @@ -2350,10 +2363,10 @@ bool nas::read_ctxt_file(nas_sec_ctxt* ctxt_) "ksi: %x, k_asme: %s, tx_count: %x, rx_count: %x, int_alg: %d, enc_alg: %d", ctxt_->ksi, hex_to_string(ctxt_->k_asme, 32).c_str(), - ctxt_->tx_count, - ctxt_->rx_count, - ctxt_->integ_algo, - ctxt_->cipher_algo); + ctxt_base_->tx_count, + ctxt_base_->rx_count, + ctxt_base_->integ_algo, + ctxt_base_->cipher_algo); have_guti = true; have_ctxt = true; @@ -2369,7 +2382,7 @@ bool nas::read_ctxt_file(nas_sec_ctxt* ctxt_) return false; } -bool nas::write_ctxt_file(nas_sec_ctxt ctxt_) +bool nas::write_ctxt_file(nas_sec_ctxt ctxt_, nas_sec_base_ctxt ctxt_base_) { if (!have_guti || !have_ctxt) { return false; @@ -2382,10 +2395,10 @@ bool nas::write_ctxt_file(nas_sec_ctxt ctxt_) file << "mnc=" << (int)ctxt_.guti.mnc << std::endl; file << "mme_group_id=" << (int)ctxt_.guti.mme_group_id << std::endl; file << "mme_code=" << (int)ctxt_.guti.mme_code << std::endl; - file << "tx_count=" << (int)ctxt_.tx_count << std::endl; - file << "rx_count=" << (int)ctxt_.rx_count << std::endl; - file << "int_alg=" << (int)ctxt_.integ_algo << std::endl; - file << "enc_alg=" << (int)ctxt_.cipher_algo << std::endl; + file << "tx_count=" << (int)ctxt_base_.tx_count << std::endl; + file << "rx_count=" << (int)ctxt_base_.rx_count << std::endl; + file << "int_alg=" << (int)ctxt_base_.integ_algo << std::endl; + file << "enc_alg=" << (int)ctxt_base_.cipher_algo << std::endl; file << "ksi=" << (int)ctxt_.ksi << std::endl; file << "k_asme=" << hex_to_string(ctxt_.k_asme, 32) << std::endl; @@ -2401,10 +2414,10 @@ bool nas::write_ctxt_file(nas_sec_ctxt ctxt_) "ksi: %x, k_asme: %s, tx_count: %x, rx_count: %x, int_alg: %d, enc_alg: %d", ctxt_.ksi, hex_to_string(ctxt_.k_asme, 32).c_str(), - ctxt_.tx_count, - ctxt_.rx_count, - ctxt_.integ_algo, - ctxt_.cipher_algo); + ctxt_base_.tx_count, + ctxt_base_.rx_count, + ctxt_base_.integ_algo, + ctxt_base_.cipher_algo); file.close(); return true; } diff --git a/srsue/src/stack/upper/nas_5g.cc b/srsue/src/stack/upper/nas_5g.cc index 4e226b2b8..29a59266e 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -428,7 +428,7 @@ int nas_5g::send_security_mode_complete(const srsran::nas_5g::security_mode_comm nas_msg.hdr.security_header_type = nas_5gs_hdr::security_header_type_opts::integrity_protected_and_ciphered_with_new_5G_nas_context; - nas_msg.hdr.sequence_number = ctxt.tx_count; + nas_msg.hdr.sequence_number = ctxt_base.tx_count; if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { logger.error("Failed to pack security mode complete"); @@ -436,8 +436,8 @@ int nas_5g::send_security_mode_complete(const srsran::nas_5g::security_mode_comm } cipher_encrypt(pdu.get()); - integrity_generate(&k_nas_int[16], - ctxt.tx_count, + integrity_generate(&ctxt_base.k_nas_int[16], + ctxt_base.tx_count, SECURITY_DIRECTION_UPLINK, &pdu->msg[SEQ_5G_OFFSET], pdu->N_bytes - SEQ_5G_OFFSET, @@ -449,7 +449,7 @@ int nas_5g::send_security_mode_complete(const srsran::nas_5g::security_mode_comm logger.info("Sending Security Mode Complete"); rrc_nr->write_sdu(std::move(pdu)); - ctxt.tx_count++; + ctxt_base.tx_count++; return SRSRAN_SUCCESS; } @@ -545,7 +545,7 @@ int nas_5g::send_pdu_session_establishment_request(uint32_t tran env_nas_msg.hdr.security_header_type = nas_5gs_hdr::security_header_type_opts::integrity_protected_and_ciphered; // TODO move that seq number setting to the security part - env_nas_msg.hdr.sequence_number = ctxt.tx_count; + env_nas_msg.hdr.sequence_number = ctxt_base.tx_count; ul_nas_transport_t& ul_nas_msg = env_nas_msg.set_ul_nas_transport(); ul_nas_msg.payload_container_type.payload_container_type.value = @@ -583,8 +583,8 @@ int nas_5g::send_pdu_session_establishment_request(uint32_t tran } cipher_encrypt(pdu.get()); - integrity_generate(&k_nas_int[16], - ctxt.tx_count, + integrity_generate(&ctxt_base.k_nas_int[16], + ctxt_base.tx_count, SECURITY_DIRECTION_UPLINK, &pdu->msg[SEQ_5G_OFFSET], pdu->N_bytes - SEQ_5G_OFFSET, @@ -853,10 +853,11 @@ int nas_5g::handle_security_mode_command(security_mode_command_t& security_m srsran::unique_byte_buffer_t pdu) { logger.info("Handling Security Mode Command"); - ctxt.cipher_algo = + ctxt_base.cipher_algo = (CIPHERING_ALGORITHM_ID_ENUM)security_mode_command.selected_nas_security_algorithms.ciphering_algorithm.value; - ctxt.integ_algo = (INTEGRITY_ALGORITHM_ID_ENUM) - security_mode_command.selected_nas_security_algorithms.integrity_protection_algorithm.value; + ctxt_base.integ_algo = + (INTEGRITY_ALGORITHM_ID_ENUM) + security_mode_command.selected_nas_security_algorithms.integrity_protection_algorithm.value; // Check replayed ue security capabilities if (!check_replayed_ue_security_capabilities(security_mode_command.replayed_ue_security_capabilities)) { @@ -868,20 +869,21 @@ int nas_5g::handle_security_mode_command(security_mode_command_t& security_m initial_sec_command = false; // TODO if (initial_sec_command) { - ctxt.rx_count = 0; - ctxt.tx_count = 0; + ctxt_base.rx_count = 0; + ctxt_base.tx_count = 0; initial_sec_command = false; } // Generate NAS keys logger.debug(ctxt_5g.k_amf, 32, "K AMF"); - logger.debug("cipher_algo %d, integ_algo %d", ctxt.cipher_algo, ctxt.integ_algo); + logger.debug("cipher_algo %d, integ_algo %d", ctxt_base.cipher_algo, ctxt_base.integ_algo); - usim->generate_nas_keys_5g(ctxt_5g.k_amf, k_nas_enc, k_nas_int, ctxt.cipher_algo, ctxt.integ_algo); - logger.info(k_nas_enc, 32, "NAS encryption key - k_nas_enc"); - logger.info(k_nas_int, 32, "NAS integrity key - k_nas_int"); + usim->generate_nas_keys_5g( + ctxt_5g.k_amf, ctxt_base.k_nas_enc, ctxt_base.k_nas_int, ctxt_base.cipher_algo, ctxt_base.integ_algo); + logger.info(ctxt_base.k_nas_enc, 32, "NAS encryption key - k_nas_enc"); + logger.info(ctxt_base.k_nas_int, 32, "NAS integrity key - k_nas_int"); - logger.debug("Generating integrity check. integ_algo:%d, count_dl:%d", ctxt.integ_algo, ctxt.rx_count); + logger.debug("Generating integrity check. integ_algo:%d, count_dl:%d", ctxt_base.integ_algo, ctxt_base.rx_count); if (not integrity_check(pdu.get())) { logger.warning("Sending Security Mode Reject due to integrity check failure"); @@ -890,7 +892,7 @@ int nas_5g::handle_security_mode_command(security_mode_command_t& security_m } send_security_mode_complete(security_mode_command); - ctxt.rx_count++; + ctxt_base.rx_count++; return SRSRAN_SUCCESS; } diff --git a/srsue/src/stack/upper/nas_base.cc b/srsue/src/stack/upper/nas_base.cc index dc18463c3..4fc180b6d 100644 --- a/srsue/src/stack/upper/nas_base.cc +++ b/srsue/src/stack/upper/nas_base.cc @@ -49,7 +49,7 @@ void nas_base::integrity_generate(uint8_t* key_128, uint32_t msg_len, uint8_t* mac) { - switch (ctxt.integ_algo) { + switch (ctxt_base.integ_algo) { case INTEGRITY_ALGORITHM_ID_EIA0: break; case INTEGRITY_ALGORITHM_ID_128_EIA1: @@ -80,8 +80,8 @@ bool nas_base::integrity_check(byte_buffer_t* pdu) uint8_t* mac = &pdu->msg[mac_offset]; // generate expected MAC - uint32_t count_est = (ctxt.rx_count & 0x00FFFF00u) | pdu->msg[seq_offset]; - integrity_generate(&k_nas_int[16], + uint32_t count_est = (ctxt_base.rx_count & 0x00FFFF00u) | pdu->msg[seq_offset]; + integrity_generate(&ctxt_base.k_nas_int[16], count_est, SECURITY_DIRECTION_DOWNLINK, &pdu->msg[seq_offset], @@ -115,9 +115,9 @@ bool nas_base::integrity_check(byte_buffer_t* pdu) mac[3]); // Updated local count (according to TS 24.301 Sec. 4.4.3.3) - if (count_est != ctxt.rx_count) { + if (count_est != ctxt_base.rx_count) { logger.info("Update local count to estimated count %d", count_est); - ctxt.rx_count = count_est; + ctxt_base.rx_count = count_est; } return true; } else { @@ -130,16 +130,16 @@ void nas_base::cipher_encrypt(byte_buffer_t* pdu) { byte_buffer_t pdu_tmp; - if (ctxt.cipher_algo != CIPHERING_ALGORITHM_ID_EEA0) { - logger.debug("Encrypting PDU. count=%d", ctxt.tx_count); + if (ctxt_base.cipher_algo != CIPHERING_ALGORITHM_ID_EEA0) { + logger.debug("Encrypting PDU. count=%d", ctxt_base.tx_count); } - switch (ctxt.cipher_algo) { + switch (ctxt_base.cipher_algo) { case CIPHERING_ALGORITHM_ID_EEA0: break; case CIPHERING_ALGORITHM_ID_128_EEA1: - security_128_eea1(&k_nas_enc[16], - ctxt.tx_count, + security_128_eea1(&ctxt_base.k_nas_enc[16], + ctxt_base.tx_count, bearer_id, SECURITY_DIRECTION_UPLINK, &pdu->msg[seq_offset + 1], @@ -148,8 +148,8 @@ void nas_base::cipher_encrypt(byte_buffer_t* pdu) memcpy(&pdu->msg[seq_offset + 1], &pdu_tmp.msg[seq_offset + 1], pdu->N_bytes - seq_offset + 1); break; case CIPHERING_ALGORITHM_ID_128_EEA2: - security_128_eea2(&k_nas_enc[16], - ctxt.tx_count, + security_128_eea2(&ctxt_base.k_nas_enc[16], + ctxt_base.tx_count, bearer_id, SECURITY_DIRECTION_UPLINK, &pdu->msg[seq_offset + 1], @@ -158,8 +158,8 @@ void nas_base::cipher_encrypt(byte_buffer_t* pdu) memcpy(&pdu->msg[seq_offset + 1], &pdu_tmp.msg[seq_offset + 1], pdu->N_bytes - seq_offset + 1); break; case CIPHERING_ALGORITHM_ID_128_EEA3: - security_128_eea3(&k_nas_enc[16], - ctxt.tx_count, + security_128_eea3(&ctxt_base.k_nas_enc[16], + ctxt_base.tx_count, bearer_id, SECURITY_DIRECTION_UPLINK, &pdu->msg[seq_offset + 1], @@ -177,16 +177,16 @@ void nas_base::cipher_decrypt(byte_buffer_t* pdu) { byte_buffer_t tmp_pdu; - uint32_t count_est = (ctxt.rx_count & 0x00FFFF00u) | pdu->msg[5]; - if (ctxt.cipher_algo != CIPHERING_ALGORITHM_ID_EEA0) { - logger.debug("Decrypting PDU. Local: count=%d, Received: count=%d", ctxt.rx_count, count_est); + uint32_t count_est = (ctxt_base.rx_count & 0x00FFFF00u) | pdu->msg[5]; + if (ctxt_base.cipher_algo != CIPHERING_ALGORITHM_ID_EEA0) { + logger.debug("Decrypting PDU. Local: count=%d, Received: count=%d", ctxt_base.rx_count, count_est); } - switch (ctxt.cipher_algo) { + switch (ctxt_base.cipher_algo) { case CIPHERING_ALGORITHM_ID_EEA0: break; case CIPHERING_ALGORITHM_ID_128_EEA1: - security_128_eea1(&k_nas_enc[16], + security_128_eea1(&ctxt_base.k_nas_enc[16], count_est, bearer_id, SECURITY_DIRECTION_DOWNLINK, @@ -196,7 +196,7 @@ void nas_base::cipher_decrypt(byte_buffer_t* pdu) memcpy(&pdu->msg[seq_offset + 1], &tmp_pdu.msg[seq_offset + 1], pdu->N_bytes - seq_offset + 1); break; case CIPHERING_ALGORITHM_ID_128_EEA2: - security_128_eea2(&k_nas_enc[16], + security_128_eea2(&ctxt_base.k_nas_enc[16], count_est, bearer_id, SECURITY_DIRECTION_DOWNLINK, @@ -207,7 +207,7 @@ void nas_base::cipher_decrypt(byte_buffer_t* pdu) memcpy(&pdu->msg[seq_offset + 1], &tmp_pdu.msg[seq_offset + 1], pdu->N_bytes - seq_offset + 1); break; case CIPHERING_ALGORITHM_ID_128_EEA3: - security_128_eea3(&k_nas_enc[16], + security_128_eea3(&ctxt_base.k_nas_enc[16], count_est, bearer_id, SECURITY_DIRECTION_DOWNLINK, From 59e847ba0814618a4bb985e54d388fbbe356f636 Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Fri, 17 Sep 2021 15:23:49 +0200 Subject: [PATCH 090/208] Added NAS 5G args --- srsue/hdr/stack/upper/nas_5g.h | 12 ++++++++---- srsue/hdr/stack/upper/nas_config.h | 17 +++++++++++++++++ srsue/src/stack/upper/nas_5g.cc | 2 +- srsue/src/stack/upper/test/nas_5g_test.cc | 19 +++++++++++++------ 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/srsue/hdr/stack/upper/nas_5g.h b/srsue/hdr/stack/upper/nas_5g.h index 3278ddad8..138ade151 100644 --- a/srsue/hdr/stack/upper/nas_5g.h +++ b/srsue/hdr/stack/upper/nas_5g.h @@ -49,7 +49,10 @@ class nas_5g : public nas_base, public nas_5g_interface_rrc_nr, public nas_5g_in public: explicit nas_5g(srslog::basic_logger& logger_, srsran::task_sched_handle task_sched_); virtual ~nas_5g(); - int init(usim_interface_nas* usim_, rrc_nr_interface_nas_5g* rrc_nr_, gw_interface_nas* gw_, const nas_args_t& cfg_); + int init(usim_interface_nas* usim_, + rrc_nr_interface_nas_5g* rrc_nr_, + gw_interface_nas* gw_, + const nas_5g_args_t& cfg_); void stop(); void run_tti(); @@ -80,8 +83,8 @@ private: srsran::nas_5g::nas_5gs_msg initial_registration_request_stored; - nas_args_t cfg = {}; - mm5g_state_t state; + nas_5g_args_t cfg = {}; + mm5g_state_t state; // Security bool ia5g_caps[8] = {}; @@ -125,7 +128,8 @@ private: int send_registration_request(); int send_authentication_response(const uint8_t res[16]); int send_security_mode_reject(const srsran::nas_5g::cause_5gmm_t::cause_5gmm_type_::options cause); - int send_authentication_failure(const srsran::nas_5g::cause_5gmm_t::cause_5gmm_type_::options cause, const uint8_t res_star[16]); + int send_authentication_failure(const srsran::nas_5g::cause_5gmm_t::cause_5gmm_type_::options cause, + const uint8_t res_star[16]); int send_security_mode_complete(const srsran::nas_5g::security_mode_command_t& security_mode_command); int send_registration_complete(); int send_pdu_session_establishment_request(uint32_t transaction_identity, diff --git a/srsue/hdr/stack/upper/nas_config.h b/srsue/hdr/stack/upper/nas_config.h index c0444725b..4d6216956 100644 --- a/srsue/hdr/stack/upper/nas_config.h +++ b/srsue/hdr/stack/upper/nas_config.h @@ -43,5 +43,22 @@ public: std::vector pdu_session_cfgs; }; +class nas_5g_args_t +{ +public: + nas_5g_args_t() : force_imsi_attach(false) {} + ~nas_5g_args_t() = default; + bool force_imsi_attach; + + // Need EPS sec capabilities in 5G + std::string eia; + std::string eea; + + // 5G Security capabilities + std::string ia5g; + std::string ea5g; + std::vector pdu_session_cfgs; +}; + } // namespace srsue #endif // SRSUE_NAS_COMMON_H diff --git a/srsue/src/stack/upper/nas_5g.cc b/srsue/src/stack/upper/nas_5g.cc index 29a59266e..8d594c783 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -69,7 +69,7 @@ void nas_5g::stop() int nas_5g::init(usim_interface_nas* usim_, rrc_nr_interface_nas_5g* rrc_nr_, gw_interface_nas* gw_, - const nas_args_t& cfg_) + const nas_5g_args_t& cfg_) { usim = usim_; rrc_nr = rrc_nr_; diff --git a/srsue/src/stack/upper/test/nas_5g_test.cc b/srsue/src/stack/upper/test/nas_5g_test.cc index 5a48ead48..d7e6f01f7 100644 --- a/srsue/src/stack/upper/test/nas_5g_test.cc +++ b/srsue/src/stack/upper/test/nas_5g_test.cc @@ -42,11 +42,18 @@ int amf_attach_request_test(srsran::nas_pcap* pcap) args.op = "63BFA50EE6523365FF14C1F45F88737D"; usim.init(&args); - nas_args_t nas_cfg; - nas_cfg.force_imsi_attach = true; - nas_cfg.apn_name = "test123"; - nas_cfg.ia5g = "0,1,2,3"; - nas_cfg.ea5g = "0,1,2,3"; + nas_5g_args_t nas_5g_cfg; + nas_5g_cfg.force_imsi_attach = true; + pdu_session_cfg_t pdu_session; + pdu_session.apn_name = "test123"; + + nas_5g_cfg.pdu_session_cfgs.push_back(pdu_session); + + nas_5g_cfg.eia = "0,1,2,3"; + nas_5g_cfg.eea = "0,1,2,3"; + + nas_5g_cfg.ia5g = "0,1,2,3"; + nas_5g_cfg.ea5g = "0,1,2,3"; test_stack_dummy stack(&pdcp_dummy); srsue::nas_5g nas_5g(srslog::fetch_basic_logger("NAS-5G"), &stack.task_sched); @@ -64,7 +71,7 @@ int amf_attach_request_test(srsran::nas_pcap* pcap) gw.init(gw_args, &stack); stack.init(&nas_5g); - nas_5g.init(&usim, &rrc_nr_dummy, &gw, nas_cfg); + nas_5g.init(&usim, &rrc_nr_dummy, &gw, nas_5g_cfg); rrc_nr_dummy.init(&nas_5g); // trigger test From 5c44d774d05d04a4d0b45e5fff3e95890063a9e8 Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Fri, 17 Sep 2021 17:47:44 +0200 Subject: [PATCH 091/208] Added 5G Metrics --- srsue/hdr/stack/upper/nas_5g.h | 4 ++++ srsue/hdr/stack/upper/nas_5g_metrics.h | 2 +- srsue/src/stack/upper/nas_5g.cc | 18 +++++++++++++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/srsue/hdr/stack/upper/nas_5g.h b/srsue/hdr/stack/upper/nas_5g.h index 138ade151..3d916bdc1 100644 --- a/srsue/hdr/stack/upper/nas_5g.h +++ b/srsue/hdr/stack/upper/nas_5g.h @@ -71,6 +71,9 @@ public: int disable_data(); int start_service_request(); + // Metrics getter + void get_metrics(nas_5g_metrics_t& metrics); + private: rrc_nr_interface_nas_5g* rrc_nr = nullptr; usim_interface_nas* usim = nullptr; @@ -179,6 +182,7 @@ private: bool unestablished_pdu_sessions(); int get_unestablished_pdu_session(uint16_t& pdu_session_id, pdu_session_cfg_t& pdu_session_cfg); int reset_pdu_sessions(); + uint32_t num_of_est_pdu_sessions(); struct pdu_session_t { bool configured; diff --git a/srsue/hdr/stack/upper/nas_5g_metrics.h b/srsue/hdr/stack/upper/nas_5g_metrics.h index 3dc7b425b..79cd049a3 100644 --- a/srsue/hdr/stack/upper/nas_5g_metrics.h +++ b/srsue/hdr/stack/upper/nas_5g_metrics.h @@ -18,7 +18,7 @@ namespace srsue { struct nas_5g_metrics_t { - uint32_t nof_active_5g_bearers; + uint32_t nof_active_pdu_sessions; mm5g_state_t::state_t state; }; diff --git a/srsue/src/stack/upper/nas_5g.cc b/srsue/src/stack/upper/nas_5g.cc index 8d594c783..8253a57db 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -1018,10 +1018,15 @@ int nas_5g::reset_pdu_sessions() pdu_session.established = false; pdu_session.pdu_session_id = 0; } - return SRSRAN_SUCCESS; } +void nas_5g::get_metrics(nas_5g_metrics_t& metrics) +{ + metrics.nof_active_pdu_sessions = num_of_est_pdu_sessions(); + metrics.state = state.get_state(); +} + /******************************************************************************* * Helpers ******************************************************************************/ @@ -1135,6 +1140,17 @@ int nas_5g::init_pdu_sessions(std::vector pdu_session_cfgs) return SRSRAN_SUCCESS; } +uint32_t nas_5g::num_of_est_pdu_sessions() +{ + uint32_t i = 0; + for (auto pdu_session : pdu_sessions) { + if (pdu_session.established == true) { + i++; + } + } + return i; +} + int nas_5g::configure_pdu_session(uint16_t pdu_session_id) { for (auto pdu_session : pdu_sessions) { From 9efc3e05f364baa7cb46f20f7b3507afdad14479 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 12 Oct 2021 10:35:11 +0100 Subject: [PATCH 092/208] nr,sched: enable real mac and scheduler in nr_phy_test traffic tests --- test/phy/CMakeLists.txt | 108 ++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 55 deletions(-) diff --git a/test/phy/CMakeLists.txt b/test/phy/CMakeLists.txt index 518a9b53c..795b68829 100644 --- a/test/phy/CMakeLists.txt +++ b/test/phy/CMakeLists.txt @@ -10,6 +10,7 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) # gNb options set(NR_PHY_TEST_GNB_NOF_THREADS 1) set(NR_PHY_TEST_GNB_PHY_LOG_LEVEL "error") + set(NR_PHY_TEST_GNB_STACK_LOG_LEVEL "error") # UE options set(NR_PHY_TEST_UE_NOF_THREADS 1) @@ -17,9 +18,11 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) # Build common arguments set(NR_PHY_TEST_COMMON_ARGS - --gnb.phy.nof_threads=${NR_PHY_TEST_GNB_NOF_THREADS} - --ue.phy.nof_threads=${NR_PHY_TEST_UE_NOF_THREADS} - --ue.phy.log.level=${NR_PHY_TEST_UE_PHY_LOG_LEVEL}) + --gnb.phy.nof_threads=${NR_PHY_TEST_GNB_NOF_THREADS} + --ue.phy.nof_threads=${NR_PHY_TEST_UE_NOF_THREADS} + --ue.phy.log.level=${NR_PHY_TEST_UE_PHY_LOG_LEVEL} + --gnb.phy.log.level=${NR_PHY_TEST_GNB_PHY_LOG_LEVEL} + --gnb.stack.log.level=${NR_PHY_TEST_GNB_STACK_LOG_LEVEL}) add_executable(nr_phy_test nr_phy_test.cc) target_link_libraries(nr_phy_test @@ -37,68 +40,63 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) ${ATOMIC_LIBS}) # For each supported bandwidth foreach (NR_PHY_TEST_BW "10MHz" "20MHz") - # For each supported frame structure - foreach (NR_PHY_TEST_DUPLEX "FDD" "6D+4U" "FR1.15-1") - set(NR_PHY_TEST_DURATION_MS 50) + # For dummy and real scheduler + foreach (NR_PHY_TEST_MAC_DUMMY "dummymac" "realmac") + if(${NR_PHY_TEST_MAC_DUMMY} EQUAL "dummymac") + set(NR_PHY_TEST_MAC_DUMMY_FLAG true) + else() + set(NR_PHY_TEST_MAC_DUMMY_FLAG false) + endif() + # For each supported frame structure + foreach (NR_PHY_TEST_DUPLEX "FDD" "6D+4U" "FR1.15-1") + set(NR_PHY_TEST_DURATION_MS 50) - # DL flooding only - foreach (NR_PHY_TEST_PDSCH "default" "ts38101/5.2-1") - add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_${NR_PHY_TEST_DUPLEX}_dl_${NR_PHY_TEST_PDSCH} nr_phy_test - --reference=carrier=${NR_PHY_TEST_BW},duplex=${NR_PHY_TEST_DUPLEX},pdsch=${NR_PHY_TEST_PDSCH} + # DL flooding only + foreach (NR_PHY_TEST_PDSCH "default" "ts38101/5.2-1") + add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_${NR_PHY_TEST_MAC_DUMMY}_${NR_PHY_TEST_DUPLEX}_dl_${NR_PHY_TEST_PDSCH} nr_phy_test + --reference=carrier=${NR_PHY_TEST_BW},duplex=${NR_PHY_TEST_DUPLEX},pdsch=${NR_PHY_TEST_PDSCH} + --duration=${NR_PHY_TEST_DURATION_MS} + --gnb.stack.pdsch.slots=all + --gnb.stack.pdsch.start=0 # Start at RB 0 + --gnb.stack.pdsch.length=52 # Full 10 MHz BW + --gnb.stack.pdsch.mcs=27 # Maximum MCS + --gnb.stack.pusch.slots=none + --gnb.stack.use_dummy_sched=${NR_PHY_TEST_MAC_DUMMY_FLAG} # Use real/dummy NR MAC + ${NR_PHY_TEST_COMMON_ARGS} + ) + endforeach () + + # UL flooding + add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_${NR_PHY_TEST_MAC_DUMMY}_${NR_PHY_TEST_DUPLEX}_ul_only nr_phy_test + --reference=carrier=${NR_PHY_TEST_BW},duplex=${NR_PHY_TEST_DUPLEX} + --duration=${NR_PHY_TEST_DURATION_MS} + --gnb.stack.pdsch.slots=none + --gnb.stack.pusch.slots=all + --gnb.stack.pusch.start=0 # Start at RB 0 + --gnb.stack.pusch.length=52 # Full 10 MHz BW + --gnb.stack.pusch.mcs=28 # Maximum MCS + --gnb.stack.use_dummy_sched=${NR_PHY_TEST_MAC_DUMMY_FLAG} # Use real/dummy NR MAC + ${NR_PHY_TEST_COMMON_ARGS} + ) + + # DL and UL flooding + add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_${NR_PHY_TEST_MAC_DUMMY}_${NR_PHY_TEST_DUPLEX}_bidir nr_phy_test + --reference=carrier=${NR_PHY_TEST_BW},duplex=${NR_PHY_TEST_DUPLEX} --duration=${NR_PHY_TEST_DURATION_MS} --gnb.stack.pdsch.slots=all --gnb.stack.pdsch.start=0 # Start at RB 0 --gnb.stack.pdsch.length=52 # Full 10 MHz BW - --gnb.stack.pdsch.mcs=27 # Maximum MCS - --gnb.stack.pusch.slots=none + --gnb.stack.pdsch.mcs=28 # Maximum MCS + --gnb.stack.pusch.slots=all + --gnb.stack.pusch.start=0 # Start at RB 0 + --gnb.stack.pusch.length=52 # Full 10 MHz BW + --gnb.stack.pusch.mcs=28 # Maximum MCS + --gnb.stack.use_dummy_sched=${NR_PHY_TEST_MAC_DUMMY_FLAG} # Use real/dummy NR MAC ${NR_PHY_TEST_COMMON_ARGS} ) endforeach () - - # UL flooding - add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_${NR_PHY_TEST_DUPLEX}_ul_only nr_phy_test - --reference=carrier=${NR_PHY_TEST_BW},duplex=${NR_PHY_TEST_DUPLEX} - --duration=${NR_PHY_TEST_DURATION_MS} - --gnb.stack.pdsch.slots=none - --gnb.stack.pusch.slots=all - --gnb.stack.pusch.start=0 # Start at RB 0 - --gnb.stack.pusch.length=52 # Full 10 MHz BW - --gnb.stack.pusch.mcs=28 # Maximum MCS - ${NR_PHY_TEST_COMMON_ARGS} - ) - - # DL and UL flooding - add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_${NR_PHY_TEST_DUPLEX}_bidir nr_phy_test - --reference=carrier=${NR_PHY_TEST_BW},duplex=${NR_PHY_TEST_DUPLEX} - --duration=${NR_PHY_TEST_DURATION_MS} - --gnb.stack.pdsch.slots=all - --gnb.stack.pdsch.start=0 # Start at RB 0 - --gnb.stack.pdsch.length=52 # Full 10 MHz BW - --gnb.stack.pdsch.mcs=28 # Maximum MCS - --gnb.stack.pusch.slots=all - --gnb.stack.pusch.start=0 # Start at RB 0 - --gnb.stack.pusch.length=52 # Full 10 MHz BW - --gnb.stack.pusch.mcs=28 # Maximum MCS - ${NR_PHY_TEST_COMMON_ARGS} - ) endforeach () - add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_bidir_sched nr_phy_test - --reference=carrier=${NR_PHY_TEST_BW} - --duration=100 # 100 slots - --rnti=17921 # 0x4601 - --gnb.stack.pdsch.slots=0,1,2,3,4,5 # All possible DL slots - --gnb.stack.pdsch.start=0 # Start at RB 0 - --gnb.stack.pdsch.length=52 # Full 10 MHz BW - --gnb.stack.pdsch.mcs=28 # Maximum MCS - --gnb.stack.pusch.slots=6,7,8,9 # All possible UL slots - --gnb.stack.pusch.start=0 # Start at RB 0 - --gnb.stack.pusch.length=52 # Full 10 MHz BW - --gnb.stack.pusch.mcs=28 # Maximum MCS - --gnb.stack.use_dummy_sched=false # Use real NR scheduler - ${NR_PHY_TEST_COMMON_ARGS} - ) - # Test PRACH transmission and detection add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_prach_fdd nr_phy_test --reference=carrier=${NR_PHY_TEST_BW},duplex=FDD From 6617b9c558d4a9c0eff56a7e80733d2f5e860808 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 12 Oct 2021 10:48:11 +0100 Subject: [PATCH 093/208] nr,sched: simplify command line arg to enable real mac in nr_phy_test --- test/phy/CMakeLists.txt | 11 +++-------- test/phy/dummy_gnb_stack.h | 26 +++++++++++++------------- test/phy/nr_phy_test.cc | 2 +- 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/test/phy/CMakeLists.txt b/test/phy/CMakeLists.txt index 795b68829..2488cbbf0 100644 --- a/test/phy/CMakeLists.txt +++ b/test/phy/CMakeLists.txt @@ -42,11 +42,6 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) foreach (NR_PHY_TEST_BW "10MHz" "20MHz") # For dummy and real scheduler foreach (NR_PHY_TEST_MAC_DUMMY "dummymac" "realmac") - if(${NR_PHY_TEST_MAC_DUMMY} EQUAL "dummymac") - set(NR_PHY_TEST_MAC_DUMMY_FLAG true) - else() - set(NR_PHY_TEST_MAC_DUMMY_FLAG false) - endif() # For each supported frame structure foreach (NR_PHY_TEST_DUPLEX "FDD" "6D+4U" "FR1.15-1") set(NR_PHY_TEST_DURATION_MS 50) @@ -61,7 +56,7 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) --gnb.stack.pdsch.length=52 # Full 10 MHz BW --gnb.stack.pdsch.mcs=27 # Maximum MCS --gnb.stack.pusch.slots=none - --gnb.stack.use_dummy_sched=${NR_PHY_TEST_MAC_DUMMY_FLAG} # Use real/dummy NR MAC + --gnb.stack.use_dummy_mac=${NR_PHY_TEST_MAC_DUMMY} # Use real/dummy NR MAC ${NR_PHY_TEST_COMMON_ARGS} ) endforeach () @@ -75,7 +70,7 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) --gnb.stack.pusch.start=0 # Start at RB 0 --gnb.stack.pusch.length=52 # Full 10 MHz BW --gnb.stack.pusch.mcs=28 # Maximum MCS - --gnb.stack.use_dummy_sched=${NR_PHY_TEST_MAC_DUMMY_FLAG} # Use real/dummy NR MAC + --gnb.stack.use_dummy_mac=${NR_PHY_TEST_MAC_DUMMY} # Use real/dummy NR MAC ${NR_PHY_TEST_COMMON_ARGS} ) @@ -91,7 +86,7 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) --gnb.stack.pusch.start=0 # Start at RB 0 --gnb.stack.pusch.length=52 # Full 10 MHz BW --gnb.stack.pusch.mcs=28 # Maximum MCS - --gnb.stack.use_dummy_sched=${NR_PHY_TEST_MAC_DUMMY_FLAG} # Use real/dummy NR MAC + --gnb.stack.use_dummy_mac=${NR_PHY_TEST_MAC_DUMMY} # Use real/dummy NR MAC ${NR_PHY_TEST_COMMON_ARGS} ) endforeach () diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index 5e2fab7e5..c853b5598 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -61,13 +61,13 @@ public: uint32_t cqi_count = 0; ///< CQI opportunity counter uint32_t cqi_valid_count = 0; ///< Valid CQI counter pucch_metrics_t pucch = {}; - pucch_metrics_t pusch = {}; + pucch_metrics_t pusch = {}; }; private: - srslog::basic_logger& logger = srslog::fetch_basic_logger("GNB STK"); - bool use_dummy_sched = true; - const uint16_t rnti = 0x1234; + srslog::basic_logger& logger = srslog::fetch_basic_logger("GNB STK"); + bool use_dummy_mac = true; + const uint16_t rnti = 0x1234; struct { srsran::circular_array dci_location = {}; uint32_t mcs = 0; @@ -329,8 +329,8 @@ private: public: struct args_t { - srsran::phy_cfg_nr_t phy_cfg; ///< Physical layer configuration - bool use_dummy_sched = true; ///< Use dummy or real NR scheduler + srsran::phy_cfg_nr_t phy_cfg; ///< Physical layer configuration + std::string use_dummy_mac = "dummymac"; ///< Use dummy or real NR scheduler bool wait_preamble = false; ///< Whether a UE is created automatically or the stack waits for a PRACH uint16_t rnti = 0x1234; ///< C-RNTI uint32_t ss_id = 1; ///< Search Space identifier @@ -350,7 +350,7 @@ public: rnti(args.rnti), phy_cfg(args.phy_cfg), ss_id(args.ss_id), - use_dummy_sched(args.use_dummy_sched), + use_dummy_mac(args.use_dummy_mac == "dummymac"), sched_logger(srslog::fetch_basic_logger("MAC")) { logger.set_level(srslog::str_to_basic_level(args.log_level)); @@ -369,7 +369,7 @@ public: mac->cell_cfg(cells_cfg); // add UE to scheduler - if (not use_dummy_sched and not args.wait_preamble) { + if (not use_dummy_mac and not args.wait_preamble) { mac->reserve_rnti(0); srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1, phy_cfg); @@ -461,7 +461,7 @@ public: logger.set_context(slot_cfg.idx); sched_logger.set_context(slot_cfg.idx); - if (not use_dummy_sched) { + if (not use_dummy_mac) { if (autofill_pdsch_bsr) { mac->rlc_buffer_state(rnti, 0, 10000, 0); } @@ -539,7 +539,7 @@ public: logger.set_context(slot_cfg.idx); sched_logger.set_context(slot_cfg.idx); - if (not use_dummy_sched) { + if (not use_dummy_mac) { int ret = mac->get_ul_sched(slot_cfg, ul_sched); return ret; @@ -618,7 +618,7 @@ public: int pucch_info(const srsran_slot_cfg_t& slot_cfg, const pucch_info_t& pucch_info) override { - if (not use_dummy_sched) { + if (not use_dummy_mac) { mac->pucch_info(slot_cfg, pucch_info); return SRSRAN_SUCCESS; } @@ -655,7 +655,7 @@ public: int pusch_info(const srsran_slot_cfg_t& slot_cfg, pusch_info_t& pusch_info) override { - if (not use_dummy_sched) { + if (not use_dummy_mac) { mac->pusch_info(slot_cfg, pusch_info); } @@ -693,7 +693,7 @@ public: void rach_detected(const rach_info_t& rach_info) override { - if (not use_dummy_sched) { + if (not use_dummy_mac) { mac->rach_detected(rach_info); task_sched.run_pending_tasks(); diff --git a/test/phy/nr_phy_test.cc b/test/phy/nr_phy_test.cc index 57ed9a069..bbc744744 100644 --- a/test/phy/nr_phy_test.cc +++ b/test/phy/nr_phy_test.cc @@ -68,7 +68,7 @@ test_bench::args_t::args_t(int argc, char** argv) ("gnb.stack.pusch.slots", bpo::value(&gnb_stack.pusch.slots)->default_value(gnb_stack.pusch.slots), "Slots enabled for PUSCH") ("gnb.stack.pusch.mcs", bpo::value(&gnb_stack.pusch.mcs)->default_value(gnb_stack.pusch.mcs), "PUSCH scheduling modulation code scheme") ("gnb.stack.log.level", bpo::value(&gnb_stack.log_level)->default_value(gnb_stack.log_level), "Stack log level") - ("gnb.stack.use_dummy_sched", bpo::value(&gnb_stack.use_dummy_sched)->default_value(true), "Use dummy or real NR scheduler") + ("gnb.stack.use_dummy_mac", bpo::value(&gnb_stack.use_dummy_mac)->default_value("dummymac"), "Use dummy or real NR scheduler (dummymac or realmac)") ; options_gnb_phy.add_options() From 510e9f47a7f9909b5f9d768e3d3fd0d413dd5e73 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 12 Oct 2021 12:09:06 +0100 Subject: [PATCH 094/208] sched,nr: simplify metrics extraction from MAC Allow some level of mutex contention between metrics and worker threads in accessing internal scheduler variables. --- srsenb/hdr/stack/mac/nr/mac_nr.h | 6 +--- srsenb/hdr/stack/mac/nr/sched_nr.h | 4 ++- srsenb/hdr/stack/mac/nr/sched_nr_interface.h | 14 ++++---- srsenb/hdr/stack/mac/nr/sched_nr_worker.h | 6 ++-- srsenb/src/stack/mac/nr/mac_nr.cc | 34 ++++++-------------- srsenb/src/stack/mac/nr/sched_nr.cc | 9 ++++-- srsenb/src/stack/mac/nr/sched_nr_worker.cc | 19 +++++------ test/phy/dummy_gnb_stack.h | 9 ++++-- 8 files changed, 45 insertions(+), 56 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/mac_nr.h b/srsenb/hdr/stack/mac/nr/mac_nr.h index 08af3976a..f0687f27e 100644 --- a/srsenb/hdr/stack/mac/nr/mac_nr.h +++ b/srsenb/hdr/stack/mac/nr/mac_nr.h @@ -48,6 +48,7 @@ public: rrc_interface_mac_nr* rrc_); void stop(); + /// Called from metrics thread. void get_metrics(srsenb::mac_metrics_t& metrics); // MAC interface for RRC @@ -127,11 +128,6 @@ private: // Number of rach preambles detected for a CC std::vector detected_rachs; - - // Metrics - std::mutex metrics_mutex; - std::condition_variable metrics_condvar; - srsenb::mac_metrics_t* metrics_pending = nullptr; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/mac/nr/sched_nr.h b/srsenb/hdr/stack/mac/nr/sched_nr.h index 659eb90cf..7ec69419e 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr.h @@ -51,9 +51,11 @@ public: void ul_bsr(uint16_t rnti, uint32_t lcg_id, uint32_t bsr) override; void dl_buffer_state(uint16_t rnti, uint32_t lcid, uint32_t newtx, uint32_t retx); - int run_slot(slot_point pdsch_tti, uint32_t cc, dl_sched_res_t& result, mac_metrics_t* metrics = nullptr) override; + int run_slot(slot_point pdsch_tti, uint32_t cc, dl_sched_res_t& result) override; int get_ul_sched(slot_point pusch_tti, uint32_t cc, ul_sched_t& result) override; + void get_metrics(mac_metrics_t& metrics); + private: void ue_cfg_impl(uint16_t rnti, const ue_cfg_t& cfg); diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index 4b38a8bc5..19943040b 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -33,8 +33,6 @@ const static size_t SCHED_NR_MAX_BWP_PER_CELL = 2; const static size_t SCHED_NR_MAX_LCID = 32; const static size_t SCHED_NR_MAX_LC_GROUP = 7; -struct mac_metrics_t; - class sched_nr_interface { public: @@ -121,12 +119,12 @@ public: }; virtual ~sched_nr_interface() = default; - virtual int config(const sched_cfg_t& sched_cfg, srsran::const_span ue_cfg) = 0; - virtual void ue_cfg(uint16_t rnti, const ue_cfg_t& ue_cfg) = 0; - virtual void ue_rem(uint16_t rnti) = 0; - virtual bool ue_exists(uint16_t rnti) = 0; - virtual int run_slot(slot_point slot_rx, uint32_t cc, dl_sched_res_t& result, mac_metrics_t* metrics = nullptr) = 0; - virtual int get_ul_sched(slot_point slot_rx, uint32_t cc, ul_sched_t& result) = 0; + virtual int config(const sched_cfg_t& sched_cfg, srsran::const_span ue_cfg) = 0; + virtual void ue_cfg(uint16_t rnti, const ue_cfg_t& ue_cfg) = 0; + virtual void ue_rem(uint16_t rnti) = 0; + virtual bool ue_exists(uint16_t rnti) = 0; + virtual int run_slot(slot_point slot_rx, uint32_t cc, dl_sched_res_t& result) = 0; + virtual int get_ul_sched(slot_point slot_rx, uint32_t cc, ul_sched_t& result) = 0; virtual void dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) = 0; virtual void ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) = 0; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_worker.h b/srsenb/hdr/stack/mac/nr/sched_nr_worker.h index 47ba12c8b..7154414db 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_worker.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_worker.h @@ -95,7 +95,9 @@ public: sched_worker_manager(sched_worker_manager&&) = delete; ~sched_worker_manager(); - void run_slot(slot_point slot_tx, uint32_t cc, dl_sched_res_t& dl_res, ul_sched_t& ul_res, mac_metrics_t* metrics); + void run_slot(slot_point slot_tx, uint32_t cc, dl_sched_res_t& dl_res, ul_sched_t& ul_res); + + void get_metrics(mac_metrics_t& metrics); void enqueue_event(uint16_t rnti, srsran::move_callback ev); void enqueue_cc_event(uint32_t cc, srsran::move_callback ev); @@ -106,7 +108,7 @@ public: private: void update_ue_db(slot_point slot_tx, bool locked_context); - void get_metrics(mac_metrics_t& metrics); + void get_metrics_nolocking(mac_metrics_t& metrics); bool save_sched_result(slot_point pdcch_slot, uint32_t cc, dl_sched_res_t& dl_res, ul_sched_t& ul_res); const sched_params& cfg; diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index edeb2ac1c..b0a82fa8d 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -76,15 +76,13 @@ void mac_nr::stop() } } -/// Called from metrics thread +/// Called from metrics thread. +/// Note: This can contend for the same mutexes as the ones used by L1/L2 workers. +/// However, get_metrics is called infrequently enough to cause major halts in the L1/L2 void mac_nr::get_metrics(srsenb::mac_metrics_t& metrics) { - // Requests asynchronously MAC metrics - std::unique_lock lock(metrics_mutex); - metrics_pending = &metrics; - - // Blocks waiting for results - metrics_condvar.wait(lock, [this]() { return metrics_pending == nullptr; }); + get_metrics_nolock(metrics); + sched.get_metrics(metrics); } void mac_nr::get_metrics_nolock(srsenb::mac_metrics_t& metrics) @@ -286,24 +284,10 @@ int mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched slot_point pdsch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx}; sched_nr_interface::dl_sched_res_t dl_res; - // Get metrics if requested - { - std::unique_lock metrics_lock(metrics_mutex); - if (metrics_pending != nullptr) { - get_metrics_nolock(*metrics_pending); - } - - // Run Scheduler - int ret = sched.run_slot(pdsch_slot, 0, dl_res, metrics_pending); - - // Notify metrics are filled, if requested - if (metrics_pending != nullptr) { - metrics_pending = nullptr; - metrics_condvar.notify_one(); - } - if (ret != SRSRAN_SUCCESS) { - return ret; - } + // Run Scheduler + int ret = sched.run_slot(pdsch_slot, 0, dl_res); + if (ret != SRSRAN_SUCCESS) { + return ret; } dl_sched = dl_res.dl_sched; diff --git a/srsenb/src/stack/mac/nr/sched_nr.cc b/srsenb/src/stack/mac/nr/sched_nr.cc index 827b4bb85..f1a4ffc2e 100644 --- a/srsenb/src/stack/mac/nr/sched_nr.cc +++ b/srsenb/src/stack/mac/nr/sched_nr.cc @@ -124,13 +124,13 @@ void sched_nr::ue_cfg_impl(uint16_t rnti, const ue_cfg_t& uecfg) } /// Generate {pdcch_slot,cc} scheduling decision -int sched_nr::run_slot(slot_point slot_dl, uint32_t cc, dl_sched_res_t& result, mac_metrics_t* metrics) +int sched_nr::run_slot(slot_point slot_dl, uint32_t cc, dl_sched_res_t& result) { // Copy UL results to intermediate buffer ul_sched_t& ul_res = pending_results->add_ul_result(slot_dl, cc); // Generate {slot_idx,cc} result - sched_workers->run_slot(slot_dl, cc, result, ul_res, metrics); + sched_workers->run_slot(slot_dl, cc, result, ul_res); return SRSRAN_SUCCESS; } @@ -148,6 +148,11 @@ int sched_nr::get_ul_sched(slot_point slot_ul, uint32_t cc, ul_sched_t& result) return SRSRAN_SUCCESS; } +void sched_nr::get_metrics(mac_metrics_t& metrics) +{ + sched_workers->get_metrics(metrics); +} + int sched_nr::dl_rach_info(uint32_t cc, const dl_sched_rar_info_t& rar_info) { sched_workers->enqueue_cc_event(cc, [this, cc, rar_info]() { cells[cc]->bwps[0].ra.dl_rach_info(rar_info); }); diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc index 8b533511a..df32ed526 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_worker.cc @@ -256,11 +256,7 @@ void sched_worker_manager::update_ue_db(slot_point slot_tx, bool locked_context) } } -void sched_worker_manager::run_slot(slot_point slot_tx, - uint32_t cc, - dl_sched_res_t& dl_res, - ul_sched_t& ul_res, - mac_metrics_t* metrics) +void sched_worker_manager::run_slot(slot_point slot_tx, uint32_t cc, dl_sched_res_t& dl_res, ul_sched_t& ul_res) { // Fill DL signalling messages that do not depend on UEs state serv_cell_manager& serv_cell = *cells[cc]; @@ -289,11 +285,6 @@ void sched_worker_manager::run_slot(slot_point slot_tx, } update_ue_db(slot_tx, true); - // Obtain MAC metrics if requested - if (metrics != nullptr) { - get_metrics(*metrics); - } - // mark the start of slot. awake remaining workers if locking on the mutex current_slot = slot_tx; worker_count.store(static_cast(cc_worker_list.size()), std::memory_order_relaxed); @@ -346,6 +337,12 @@ void sched_worker_manager::run_slot(slot_point slot_tx, save_sched_result(slot_tx, cc, dl_res, ul_res); } +void sched_worker_manager::get_metrics(mac_metrics_t& metrics) +{ + std::unique_lock lock(slot_mutex); + get_metrics_nolocking(metrics); +} + bool sched_worker_manager::save_sched_result(slot_point pdcch_slot, uint32_t cc, dl_sched_res_t& dl_res, @@ -369,7 +366,7 @@ bool sched_worker_manager::save_sched_result(slot_point pdcch_slot, return true; } -void sched_worker_manager::get_metrics(mac_metrics_t& metrics) +void sched_worker_manager::get_metrics_nolocking(mac_metrics_t& metrics) { for (mac_ue_metrics_t& ue_metric : metrics.ues) { if (ue_db.contains(ue_metric.rnti) and ue_db[ue_metric.rnti]->carriers[0] != nullptr) { diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index c853b5598..c50533e70 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -451,7 +451,8 @@ public: valid = true; } - ~gnb_dummy_stack() {} + ~gnb_dummy_stack() = default; + bool is_valid() const { return valid; } int slot_indication(const srsran_slot_cfg_t& slot_cfg) override { return 0; } @@ -712,7 +713,11 @@ public: metrics_t get_metrics() { std::unique_lock lock(metrics_mutex); - + if (not use_dummy_mac) { + srsenb::mac_metrics_t mac_metrics; + mac->get_metrics(mac_metrics); + metrics.mac = mac_metrics.ues[0]; + } return metrics; } }; From ca7a3cf2014c10dd83b7ae115266e142a32d2b13 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 12 Oct 2021 12:18:45 +0100 Subject: [PATCH 095/208] nr,sched: fix sched tbs acked metric computation --- srsenb/src/stack/mac/nr/sched_nr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/stack/mac/nr/sched_nr.cc b/srsenb/src/stack/mac/nr/sched_nr.cc index f1a4ffc2e..28e88bba6 100644 --- a/srsenb/src/stack/mac/nr/sched_nr.cc +++ b/srsenb/src/stack/mac/nr/sched_nr.cc @@ -165,7 +165,7 @@ void sched_nr::dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb int tbs = ue_cc.harq_ent.dl_ack_info(pid, tb_idx, ack); if (tbs >= 0) { if (ack) { - ue_cc.metrics.tx_brate += tbs * 8; + ue_cc.metrics.tx_brate += tbs; } else { ue_cc.metrics.tx_errors++; } From 5979f98a8e1d9035f5b106280879ce1983824fb3 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 12 Oct 2021 12:25:52 +0100 Subject: [PATCH 096/208] nr,test: ensure phy metrics are generated in nr_phy_test when real mac is used --- test/phy/dummy_gnb_stack.h | 39 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index c50533e70..390911020 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -621,13 +621,12 @@ public: { if (not use_dummy_mac) { mac->pucch_info(slot_cfg, pucch_info); - return SRSRAN_SUCCESS; - } - - // Handle UCI data - if (not handle_uci_data(pucch_info.uci_data.cfg, pucch_info.uci_data.value)) { - logger.error("Error handling UCI data from PUCCH reception"); - return SRSRAN_ERROR; + } else { + // Handle UCI data + if (not handle_uci_data(pucch_info.uci_data.cfg, pucch_info.uci_data.value)) { + logger.error("Error handling UCI data from PUCCH reception"); + return SRSRAN_ERROR; + } } // Skip next steps if uci data is invalid @@ -658,21 +657,21 @@ public: { if (not use_dummy_mac) { mac->pusch_info(slot_cfg, pusch_info); - } - - // Handle UCI data - if (not handle_uci_data(pusch_info.uci_cfg, pusch_info.pusch_data.uci)) { - logger.error("Error handling UCI data from PUCCH reception"); - return SRSRAN_ERROR; - } + } else { + // Handle UCI data + if (not handle_uci_data(pusch_info.uci_cfg, pusch_info.pusch_data.uci)) { + logger.error("Error handling UCI data from PUCCH reception"); + return SRSRAN_ERROR; + } - // Handle UL-SCH metrics - std::unique_lock lock(metrics_mutex); - if (not pusch_info.pusch_data.tb[0].crc) { - metrics.mac.rx_errors++; + // Handle UL-SCH metrics + std::unique_lock lock(metrics_mutex); + if (not pusch_info.pusch_data.tb[0].crc) { + metrics.mac.rx_errors++; + } + metrics.mac.rx_brate += rx_harq_proc[pusch_info.pid].get_tbs(); + metrics.mac.rx_pkts++; } - metrics.mac.rx_brate += rx_harq_proc[pusch_info.pid].get_tbs(); - metrics.mac.rx_pkts++; // Handle PHY metrics metrics.pusch.epre_db_avg = SRSRAN_VEC_CMA(pusch_info.csi.epre_dB, metrics.pusch.epre_db_avg, metrics.pusch.count); From 53c99796cce291e314d2434a646718f56ea83a3e Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 12 Oct 2021 16:16:21 +0100 Subject: [PATCH 097/208] nr,gnb,rrc: ensure timing advance offset is set to present --- srsenb/src/stack/rrc/nr/cell_asn1_config.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc index 978de0cda..606711302 100644 --- a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc +++ b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc @@ -237,7 +237,8 @@ int fill_serv_cell_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, ser { auto& cell_cfg = cfg.cell_list.at(cc); - serv_common.ss_pbch_block_pwr = 0; + serv_common.ss_pbch_block_pwr = 0; + serv_common.n_timing_advance_offset_present = true; serv_common.n_timing_advance_offset = asn1::rrc_nr::serving_cell_cfg_common_s::n_timing_advance_offset_opts::n0; serv_common.dmrs_type_a_position = asn1::rrc_nr::serving_cell_cfg_common_s::dmrs_type_a_position_opts::pos2; From 11ee4ab9dd9e896344ed614ca7b656b4301fba6d Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 12 Oct 2021 16:39:19 +0100 Subject: [PATCH 098/208] nr,gnb,rrc: fix scheduler FDD configuration --- lib/include/srsran/asn1/rrc_nr_utils.h | 2 ++ lib/src/asn1/rrc_nr_utils.cc | 12 ++++++++++++ srsenb/src/stack/rrc/rrc_nr.cc | 4 ++++ 3 files changed, 18 insertions(+) diff --git a/lib/include/srsran/asn1/rrc_nr_utils.h b/lib/include/srsran/asn1/rrc_nr_utils.h index 04477dd80..d732aa57a 100644 --- a/lib/include/srsran/asn1/rrc_nr_utils.h +++ b/lib/include/srsran/asn1/rrc_nr_utils.h @@ -116,6 +116,8 @@ bool make_phy_ssb_cfg(const srsran_carrier_nr_t& carrier, phy_cfg_nr_t::ssb_cfg_t* ssb); bool make_pdsch_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_sch_hl_cfg_nr_t* sch_hl); bool make_csi_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_csi_hl_cfg_t* csi_hl); +bool make_duplex_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_common_s& serv_cell, + srsran_duplex_config_nr_t* duplex_cfg); /*************************** * MAC Config diff --git a/lib/src/asn1/rrc_nr_utils.cc b/lib/src/asn1/rrc_nr_utils.cc index 751f8e3a5..12964a225 100644 --- a/lib/src/asn1/rrc_nr_utils.cc +++ b/lib/src/asn1/rrc_nr_utils.cc @@ -1539,6 +1539,18 @@ bool make_csi_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_s& serv_ce return true; } +bool make_duplex_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_common_s& serv_cell, + srsran_duplex_config_nr_t* duplex_cfg) +{ + duplex_cfg->mode = serv_cell.tdd_ul_dl_cfg_common_present ? SRSRAN_DUPLEX_MODE_TDD : SRSRAN_DUPLEX_MODE_FDD; + if (serv_cell.tdd_ul_dl_cfg_common_present) { + if (not make_phy_tdd_cfg(serv_cell.tdd_ul_dl_cfg_common, duplex_cfg)) { + return false; + } + } + return true; +} + } // namespace srsran namespace srsenb { diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 4c206ae87..567249067 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -254,6 +254,8 @@ void rrc_nr::config_mac() ret2 = srsran::make_phy_ssb_cfg( cfg.cell_list[0].phy_cell.carrier, sp_cell.recfg_with_sync.sp_cell_cfg_common, &cell.ssb); srsran_assert(ret2, "Invalid NR cell configuration."); + ret2 = srsran::make_duplex_cfg_from_serv_cell(sp_cell.recfg_with_sync.sp_cell_cfg_common, &cell.duplex); + srsran_assert(ret2, "Invalid NR cell configuration."); // FIXME: entire SI configuration, etc needs to be ported to NR sched_interface::cell_cfg_t cell_cfg; @@ -1401,6 +1403,8 @@ void rrc_nr::ue::crnti_ce_received() srsran::make_phy_ssb_cfg(parent->cfg.cell_list[0].phy_cell.carrier, cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common, &uecfg.phy_cfg.ssb); + srsran::make_duplex_cfg_from_serv_cell(cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common, + &uecfg.phy_cfg.duplex); parent->mac->ue_cfg(rnti, uecfg); } From c08bb6023c5a1e4505e7370953109eb5cb75794e Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 12 Oct 2021 14:58:59 +0100 Subject: [PATCH 099/208] nr,sched,refactor: clear of unused typedefs and renaming of some types --- srsenb/hdr/stack/mac/nr/mac_nr.h | 12 +- srsenb/hdr/stack/mac/nr/sched_nr.h | 5 +- srsenb/hdr/stack/mac/nr/sched_nr_cell.h | 18 +-- srsenb/hdr/stack/mac/nr/sched_nr_cfg.h | 103 +++++++++--------- .../stack/mac/nr/sched_nr_grant_allocator.h | 14 +-- srsenb/hdr/stack/mac/nr/sched_nr_helpers.h | 8 +- srsenb/hdr/stack/mac/nr/sched_nr_interface.h | 34 +++--- srsenb/hdr/stack/mac/nr/sched_nr_pdcch.h | 10 +- srsenb/hdr/stack/mac/nr/sched_nr_signalling.h | 8 +- srsenb/hdr/stack/mac/nr/sched_nr_ue.h | 6 +- srsenb/hdr/stack/mac/nr/sched_nr_worker.h | 10 +- srsenb/src/stack/mac/nr/mac_nr.cc | 15 +-- srsenb/src/stack/mac/nr/sched_nr.cc | 4 +- srsenb/src/stack/mac/nr/sched_nr_cell.cc | 12 +- srsenb/src/stack/mac/nr/sched_nr_cfg.cc | 50 ++++----- .../stack/mac/nr/sched_nr_grant_allocator.cc | 6 +- srsenb/src/stack/mac/nr/sched_nr_helpers.cc | 10 +- srsenb/src/stack/mac/nr/sched_nr_pdcch.cc | 10 +- .../src/stack/mac/nr/sched_nr_signalling.cc | 8 +- srsenb/src/stack/mac/nr/sched_nr_ue.cc | 4 +- srsenb/src/stack/mac/nr/sched_nr_worker.cc | 6 +- srsenb/test/mac/nr/sched_nr_rar_test.cc | 8 +- srsenb/test/mac/nr/sched_nr_sim_ue.cc | 6 +- srsenb/test/mac/nr/sched_nr_sim_ue.h | 22 ++-- srsenb/test/mac/nr/sched_nr_test.cc | 4 +- 25 files changed, 196 insertions(+), 197 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/mac_nr.h b/srsenb/hdr/stack/mac/nr/mac_nr.h index f0687f27e..3b44d5bba 100644 --- a/srsenb/hdr/stack/mac/nr/mac_nr.h +++ b/srsenb/hdr/stack/mac/nr/mac_nr.h @@ -28,11 +28,11 @@ namespace srsenb { struct mac_nr_args_t { - srsran::phy_cfg_nr_t phy_base_cfg = {}; - int fixed_dl_mcs = -1; - int fixed_ul_mcs = -1; - sched_nr_interface::sched_cfg_t sched_cfg = {}; - srsenb::pcap_args_t pcap; + srsran::phy_cfg_nr_t phy_base_cfg = {}; + int fixed_dl_mcs = -1; + int fixed_ul_mcs = -1; + sched_nr_interface::sched_args_t sched_cfg = {}; + srsenb::pcap_args_t pcap; }; class mac_nr final : public mac_interface_phy_nr, public mac_interface_rrc_nr, public mac_interface_rlc_nr @@ -87,7 +87,7 @@ private: void get_metrics_nolock(srsenb::mac_metrics_t& metrics); // Encoding - srsran::byte_buffer_t* assemble_rar(srsran::const_span grants); + srsran::byte_buffer_t* assemble_rar(srsran::const_span grants); srsran::unique_byte_buffer_t rar_pdu_buffer = nullptr; // Interaction with other components diff --git a/srsenb/hdr/stack/mac/nr/sched_nr.h b/srsenb/hdr/stack/mac/nr/sched_nr.h index 7ec69419e..5e3e79de7 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr.h @@ -30,7 +30,6 @@ class sched_worker_manager; class serv_cell_manager; } // namespace sched_nr_impl -class ue_event_manager; class ul_sched_result_buffer; class sched_nr final : public sched_nr_interface @@ -38,12 +37,12 @@ class sched_nr final : public sched_nr_interface public: explicit sched_nr(); ~sched_nr() override; - int config(const sched_cfg_t& sched_cfg, srsran::const_span cell_list) override; + int config(const sched_args_t& sched_cfg, srsran::const_span cell_list) override; void ue_cfg(uint16_t rnti, const ue_cfg_t& cfg) override; void ue_rem(uint16_t rnti) override; bool ue_exists(uint16_t rnti) override; - int dl_rach_info(uint32_t cc, const dl_sched_rar_info_t& rar_info); + int dl_rach_info(uint32_t cc, const rar_info_t& rar_info); void dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) override; void ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) override; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_cell.h b/srsenb/hdr/stack/mac/nr/sched_nr_cell.h index d07a00253..540726b67 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_cell.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_cell.h @@ -25,12 +25,12 @@ namespace sched_nr_impl { class si_sched { public: - explicit si_sched(const bwp_params& bwp_cfg_); + explicit si_sched(const bwp_params_t& bwp_cfg_); void run_slot(bwp_slot_allocator& slot_alloc); private: - const bwp_params* bwp_cfg = nullptr; + const bwp_params_t* bwp_cfg = nullptr; srslog::basic_logger& logger; struct sched_si_t { @@ -45,13 +45,13 @@ private: srsran::bounded_vector pending_sis; }; -using dl_sched_rar_info_t = sched_nr_interface::dl_sched_rar_info_t; +using dl_sched_rar_info_t = sched_nr_interface::rar_info_t; /// RAR/Msg3 scheduler class ra_sched { public: - explicit ra_sched(const bwp_params& bwp_cfg_); + explicit ra_sched(const bwp_params_t& bwp_cfg_); /// Addition of detected PRACH into the queue int dl_rach_info(const dl_sched_rar_info_t& rar_info); @@ -73,7 +73,7 @@ private: alloc_result allocate_pending_rar(bwp_slot_allocator& slot_grid, const pending_rar_t& rar, uint32_t& nof_grants_alloc); - const bwp_params* bwp_cfg = nullptr; + const bwp_params_t* bwp_cfg = nullptr; srslog::basic_logger& logger; srsran::deque pending_rars; @@ -82,9 +82,9 @@ private: class bwp_ctxt { public: - explicit bwp_ctxt(const bwp_params& bwp_cfg); + explicit bwp_ctxt(const bwp_params_t& bwp_cfg); - const bwp_params* cfg; + const bwp_params_t* cfg; // channel-specific schedulers ra_sched ra; @@ -99,10 +99,10 @@ class serv_cell_manager public: using feedback_callback_t = srsran::move_callback; - explicit serv_cell_manager(const sched_cell_params& cell_cfg_); + explicit serv_cell_manager(const cell_params_t& cell_cfg_); srsran::bounded_vector bwps; - const sched_cell_params& cfg; + const cell_params_t& cfg; private: srslog::basic_logger& logger; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h b/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h index 26c225805..a2a7f38ef 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h @@ -26,27 +26,32 @@ static const size_t MAX_NOF_AGGR_LEVELS = 5; namespace sched_nr_impl { -const static size_t MAX_GRANTS = sched_nr_interface::MAX_GRANTS; - -using pdcch_dl_t = mac_interface_phy_nr::pdcch_dl_t; -using pdcch_ul_t = mac_interface_phy_nr::pdcch_ul_t; -using pdsch_t = mac_interface_phy_nr::pdsch_t; -using pusch_t = mac_interface_phy_nr::pusch_t; -using pucch_t = mac_interface_phy_nr::pucch_t; -using pdcch_dl_list_t = srsran::bounded_vector; -using pdcch_ul_list_t = srsran::bounded_vector; -using pucch_list_t = srsran::bounded_vector; -using pusch_list_t = srsran::bounded_vector; -using nzp_csi_rs_list = srsran::bounded_vector; -using ssb_t = mac_interface_phy_nr::ssb_t; -using ssb_list = srsran::bounded_vector; - -using sched_cfg_t = sched_nr_interface::sched_cfg_t; -using cell_cfg_t = sched_nr_interface::cell_cfg_t; -using bwp_cfg_t = sched_nr_interface::bwp_cfg_t; - +constexpr static size_t MAX_GRANTS = sched_nr_interface::MAX_GRANTS; + +using pdcch_dl_t = mac_interface_phy_nr::pdcch_dl_t; +using pdcch_ul_t = mac_interface_phy_nr::pdcch_ul_t; +using pdsch_t = mac_interface_phy_nr::pdsch_t; +using pusch_t = mac_interface_phy_nr::pusch_t; +using pucch_t = mac_interface_phy_nr::pucch_t; +using pdcch_dl_list_t = srsran::bounded_vector; +using pdcch_ul_list_t = srsran::bounded_vector; +using pucch_list_t = srsran::bounded_vector; +using pusch_list_t = srsran::bounded_vector; +using nzp_csi_rs_list = srsran::bounded_vector; +using ssb_t = mac_interface_phy_nr::ssb_t; +using ssb_list = srsran::bounded_vector; +using sched_args_t = sched_nr_interface::sched_args_t; +using cell_cfg_t = sched_nr_interface::cell_cfg_t; +using bwp_cfg_t = sched_nr_interface::bwp_cfg_t; +using ue_cfg_t = sched_nr_interface::ue_cfg_t; +using ue_cc_cfg_t = sched_nr_interface::ue_cc_cfg_t; using pdcch_cce_pos_list = srsran::bounded_vector; using bwp_cce_pos_list = std::array, SRSRAN_NOF_SF_X_FRAME>; +using dl_sched_t = sched_nr_interface::dl_sched_t; +using ul_sched_t = sched_nr_interface::ul_sched_t; +using dl_sched_res_t = sched_nr_interface::dl_sched_res_t; + +/// Generate list of CCE locations for UE based on coreset and search space configurations void get_dci_locs(const srsran_coreset_t& coreset, const srsran_search_space_t& search_space, uint16_t rnti, @@ -54,18 +59,22 @@ void get_dci_locs(const srsran_coreset_t& coreset, /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -struct bwp_params { - const uint32_t bwp_id; - const uint32_t cc; - const bwp_cfg_t& cfg; - const cell_cfg_t& cell_cfg; - const sched_cfg_t& sched_cfg; +/// Structure that extends the sched_nr_interface::bwp_cfg_t passed by upper layers with other +/// derived BWP-specific params +struct bwp_params_t { + const uint32_t bwp_id; + const uint32_t cc; + const bwp_cfg_t& cfg; + const cell_cfg_t& cell_cfg; + const sched_args_t& sched_cfg; // derived params srslog::basic_logger& logger; uint32_t P; uint32_t N_rbg; + uint32_t nof_prb() const { return cell_cfg.carrier.nof_prb; } + /// Table specifying if a slot has DL or UL enabled struct slot_cfg { bool is_dl; bool is_ul; @@ -82,48 +91,42 @@ struct bwp_params { bwp_cce_pos_list rar_cce_list; - bwp_params(const cell_cfg_t& cell, const sched_cfg_t& sched_cfg_, uint32_t cc, uint32_t bwp_id); + bwp_params_t(const cell_cfg_t& cell, const sched_args_t& sched_cfg_, uint32_t cc, uint32_t bwp_id); }; -struct sched_cell_params { - const uint32_t cc; - const cell_cfg_t cell_cfg; - const sched_cfg_t& sched_cfg; - std::vector bwps; +/// Structure packing a single cell config params, and sched args +struct cell_params_t { + const uint32_t cc; + const cell_cfg_t cfg; + const sched_args_t& sched_args; + std::vector bwps; - sched_cell_params(uint32_t cc_, const cell_cfg_t& cell, const sched_cfg_t& sched_cfg_); + cell_params_t(uint32_t cc_, const cell_cfg_t& cell, const sched_args_t& sched_cfg_); - uint32_t nof_prb() const { return cell_cfg.carrier.nof_prb; } + uint32_t nof_prb() const { return cfg.carrier.nof_prb; } }; +/// Structure packing both the sched args and all gNB NR cell configurations struct sched_params { - sched_cfg_t sched_cfg; - std::vector cells; + sched_args_t sched_cfg; + std::vector cells; sched_params() = default; - explicit sched_params(const sched_cfg_t& sched_cfg_); + explicit sched_params(const sched_args_t& sched_cfg_); }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -using prb_bitmap = srsran::bounded_bitset; - -using pdcchmask_t = srsran::bounded_bitset; - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -using ue_cfg_t = sched_nr_interface::ue_cfg_t; -using ue_cc_cfg_t = sched_nr_interface::ue_cc_cfg_t; - +/// Configuration of a UE for a given BWP class bwp_ue_cfg { public: bwp_ue_cfg() = default; - explicit bwp_ue_cfg(uint16_t rnti, const bwp_params& bwp_cfg, const ue_cfg_t& uecfg_); + explicit bwp_ue_cfg(uint16_t rnti, const bwp_params_t& bwp_cfg, const ue_cfg_t& uecfg_); const ue_cfg_t* ue_cfg() const { return cfg_; } const srsran::phy_cfg_nr_t& phy() const { return cfg_->phy_cfg; } - const bwp_params& active_bwp() const { return *bwp_cfg; } + const bwp_params_t& active_bwp() const { return *bwp_cfg; } const bwp_cce_pos_list& cce_pos_list(uint32_t search_id) const { return cce_positions_list[ss_id_to_cce_idx[search_id]]; @@ -137,9 +140,9 @@ public: } private: - uint16_t rnti = SRSRAN_INVALID_RNTI; - const ue_cfg_t* cfg_ = nullptr; - const bwp_params* bwp_cfg = nullptr; + uint16_t rnti = SRSRAN_INVALID_RNTI; + const ue_cfg_t* cfg_ = nullptr; + const bwp_params_t* bwp_cfg = nullptr; std::vector cce_positions_list; std::array ss_id_to_cce_idx; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h b/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h index 8b141ed73..bb7ad0235 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h @@ -24,7 +24,7 @@ namespace srsenb { namespace sched_nr_impl { // typedefs -using dl_sched_rar_info_t = sched_nr_interface::dl_sched_rar_info_t; +using dl_sched_rar_info_t = sched_nr_interface::rar_info_t; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -44,8 +44,8 @@ using harq_ack_list_t = srsran::bounded_vector; /// save data for scheduler to keep track of previous allocations /// This only contains information about a given slot struct bwp_slot_grid { - uint32_t slot_idx = 0; - const bwp_params* cfg = nullptr; + uint32_t slot_idx = 0; + const bwp_params_t* cfg = nullptr; bwp_rb_bitmap dl_prbs; bwp_rb_bitmap ul_prbs; @@ -63,7 +63,7 @@ struct bwp_slot_grid { srsran::unique_pool_ptr rar_softbuffer; bwp_slot_grid() = default; - explicit bwp_slot_grid(const bwp_params& bwp_params, uint32_t slot_idx_); + explicit bwp_slot_grid(const bwp_params_t& bwp_params, uint32_t slot_idx_); void reset(); bool is_dl() const { return cfg->slots[slot_idx].is_dl; } @@ -71,14 +71,14 @@ struct bwp_slot_grid { }; struct bwp_res_grid { - explicit bwp_res_grid(const bwp_params& bwp_cfg_); + explicit bwp_res_grid(const bwp_params_t& bwp_cfg_); bwp_slot_grid& operator[](slot_point tti) { return slots[tti.to_uint() % slots.capacity()]; }; const bwp_slot_grid& operator[](slot_point tti) const { return slots[tti.to_uint() % slots.capacity()]; }; uint32_t id() const { return cfg->bwp_id; } uint32_t nof_prbs() const { return cfg->cfg.rb_width; } - const bwp_params* cfg = nullptr; + const bwp_params_t* cfg = nullptr; private: // TTIMOD_SZ is the longest allocation in the future @@ -114,7 +114,7 @@ public: slot_point get_tti_rx() const { return pdcch_slot - TX_ENB_DELAY; } const bwp_res_grid& res_grid() const { return bwp_grid; } - const bwp_params& cfg; + const bwp_params_t& cfg; private: alloc_result verify_pdsch_space(bwp_slot_grid& pdsch_grid, bwp_slot_grid& pdcch_grid) const; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_helpers.h b/srsenb/hdr/stack/mac/nr/sched_nr_helpers.h index ab450d04a..81265827c 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_helpers.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_helpers.h @@ -25,20 +25,20 @@ struct bwp_res_grid; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -bool fill_dci_rar(prb_interval interv, uint16_t ra_rnti, const bwp_params& bwp_cfg, srsran_dci_dl_nr_t& dci); +bool fill_dci_rar(prb_interval interv, uint16_t ra_rnti, const bwp_params_t& bwp_cfg, srsran_dci_dl_nr_t& dci); -bool fill_dci_msg3(const slot_ue& ue, const bwp_params& bwp_cfg, srsran_dci_ul_nr_t& dci); +bool fill_dci_msg3(const slot_ue& ue, const bwp_params_t& bwp_cfg, srsran_dci_ul_nr_t& dci); /// Generate PDCCH DL DCI fields void fill_dl_dci_ue_fields(const slot_ue& ue, - const bwp_params& bwp_cfg, + const bwp_params_t& bwp_cfg, uint32_t ss_id, srsran_dci_location_t dci_pos, srsran_dci_dl_nr_t& dci); /// Generate PDCCH UL DCI fields void fill_ul_dci_ue_fields(const slot_ue& ue, - const bwp_params& bwp_cfg, + const bwp_params_t& bwp_cfg, uint32_t ss_id, srsran_dci_location_t dci_pos, srsran_dci_ul_nr_t& dci); diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index 19943040b..6a075e834 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -67,7 +67,7 @@ public: srsran::bounded_vector bwps{1}; // idx0 for BWP-common }; - struct sched_cfg_t { + struct sched_args_t { bool pdsch_enabled = true; bool pusch_enabled = true; bool auto_refill_buffer = false; @@ -88,9 +88,9 @@ public: srsran::phy_cfg_nr_t phy_cfg = {}; }; - ////// RACH ////// + ////// RA procedure ////// - struct dl_sched_rar_info_t { + struct rar_info_t { uint32_t preamble_idx; // is this the RAPID? uint32_t ofdm_symbol_idx; uint32_t freq_idx; @@ -99,32 +99,32 @@ public: uint32_t msg3_size = 7; slot_point prach_slot; }; + struct msg3_grant_t { + rar_info_t data; + srsran_dci_ul_nr_t msg3_dci = {}; + }; + struct rar_t { + srsran::bounded_vector grants; + }; ///// Sched Result ///// using dl_sched_t = mac_interface_phy_nr::dl_sched_t; using ul_sched_t = mac_interface_phy_nr::ul_sched_t; - struct sched_rar_grant_t { - dl_sched_rar_info_t data; - srsran_dci_ul_nr_t msg3_dci = {}; - }; - struct sched_rar_t { - srsran::bounded_vector grants; - }; - using sched_rar_list_t = srsran::bounded_vector; + using sched_rar_list_t = srsran::bounded_vector; struct dl_sched_res_t { sched_rar_list_t rar; dl_sched_t dl_sched; }; virtual ~sched_nr_interface() = default; - virtual int config(const sched_cfg_t& sched_cfg, srsran::const_span ue_cfg) = 0; - virtual void ue_cfg(uint16_t rnti, const ue_cfg_t& ue_cfg) = 0; - virtual void ue_rem(uint16_t rnti) = 0; - virtual bool ue_exists(uint16_t rnti) = 0; - virtual int run_slot(slot_point slot_rx, uint32_t cc, dl_sched_res_t& result) = 0; - virtual int get_ul_sched(slot_point slot_rx, uint32_t cc, ul_sched_t& result) = 0; + virtual int config(const sched_args_t& sched_cfg, srsran::const_span ue_cfg) = 0; + virtual void ue_cfg(uint16_t rnti, const ue_cfg_t& ue_cfg) = 0; + virtual void ue_rem(uint16_t rnti) = 0; + virtual bool ue_exists(uint16_t rnti) = 0; + virtual int run_slot(slot_point slot_rx, uint32_t cc, dl_sched_res_t& result) = 0; + virtual int get_ul_sched(slot_point slot_rx, uint32_t cc, ul_sched_t& result) = 0; virtual void dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) = 0; virtual void ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) = 0; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_pdcch.h b/srsenb/hdr/stack/mac/nr/sched_nr_pdcch.h index d2dad1b36..c151a8465 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_pdcch.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_pdcch.h @@ -34,11 +34,11 @@ using bwp_cfg_t = sched_nr_interface::bwp_cfg_t; class coreset_region { public: - coreset_region(const bwp_params& bwp_cfg_, - uint32_t coreset_id_, - uint32_t slot_idx, - pdcch_dl_list_t& pdcch_dl_list, - pdcch_ul_list_t& pdcch_ul_list); + coreset_region(const bwp_params_t& bwp_cfg_, + uint32_t coreset_id_, + uint32_t slot_idx, + pdcch_dl_list_t& pdcch_dl_list, + pdcch_ul_list_t& pdcch_ul_list); void reset(); /** diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_signalling.h b/srsenb/hdr/stack/mac/nr/sched_nr_signalling.h index f5d03baa4..d3188469a 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_signalling.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_signalling.h @@ -42,10 +42,10 @@ void sched_nzp_csi_rs(srsran::const_span nzp_csi_rs_set void sched_ssb_basic(const slot_point& sl_point, uint32_t ssb_periodicity, ssb_list& ssb_list); /// For a given BWP and slot, schedule SSB, NZP CSI RS and SIBs -void sched_dl_signalling(const bwp_params& bwp_params, - slot_point sl_pdcch, - ssb_list& ssb_list, - nzp_csi_rs_list& nzp_csi_rs); +void sched_dl_signalling(const bwp_params_t& bwp_params, + slot_point sl_pdcch, + ssb_list& ssb_list, + nzp_csi_rs_list& nzp_csi_rs); } // namespace sched_nr_impl } // namespace srsenb diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h index b02d14db0..4104e786b 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h @@ -62,7 +62,7 @@ public: class ue_carrier { public: - ue_carrier(uint16_t rnti, const ue_cfg_t& cfg, const sched_cell_params& cell_params_); + ue_carrier(uint16_t rnti, const ue_cfg_t& cfg, const cell_params_t& cell_params_); slot_ue try_reserve(slot_point pdcch_slot, const ue_cfg_t& uecfg_, uint32_t dl_harq_bytes, uint32_t ul_harq_bytes); const uint16_t rnti; @@ -78,8 +78,8 @@ public: mac_ue_metrics_t metrics = {}; private: - bwp_ue_cfg bwp_cfg; - const sched_cell_params& cell_params; + bwp_ue_cfg bwp_cfg; + const cell_params_t& cell_params; }; class ue diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_worker.h b/srsenb/hdr/stack/mac/nr/sched_nr_worker.h index 7154414db..f9843ca3c 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_worker.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_worker.h @@ -30,10 +30,6 @@ struct mac_metrics_t; namespace sched_nr_impl { -using dl_sched_t = sched_nr_interface::dl_sched_t; -using ul_sched_t = sched_nr_interface::ul_sched_t; -using dl_sched_res_t = sched_nr_interface::dl_sched_res_t; - class slot_cc_worker { public: @@ -57,9 +53,9 @@ private: void alloc_ul_ues(); void postprocess_decisions(); - const sched_cell_params& cfg; - serv_cell_manager& cell; - srslog::basic_logger& logger; + const cell_params_t& cfg; + serv_cell_manager& cell; + srslog::basic_logger& logger; slot_point slot_rx; bwp_slot_allocator bwp_alloc; diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index b0a82fa8d..150b0e2d0 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -165,11 +165,11 @@ void mac_nr::rach_detected(const rach_info_t& rach_info) ++detected_rachs[enb_cc_idx]; // Trigger scheduler RACH - srsenb::sched_nr_interface::dl_sched_rar_info_t rar_info = {}; - rar_info.preamble_idx = rach_info.preamble; - rar_info.temp_crnti = rnti; - rar_info.ta_cmd = rach_info.time_adv; - rar_info.prach_slot = slot_point{NUMEROLOGY_IDX, rach_info.slot_index}; + srsenb::sched_nr_interface::rar_info_t rar_info = {}; + rar_info.preamble_idx = rach_info.preamble; + rar_info.temp_crnti = rnti; + rar_info.ta_cmd = rach_info.time_adv; + rar_info.prach_slot = slot_point{NUMEROLOGY_IDX, rach_info.slot_index}; // TODO: fill remaining fields as required sched.dl_rach_info(enb_cc_idx, rar_info); rrc->add_user(rnti); @@ -312,7 +312,7 @@ int mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched } } } else if (pdsch.sch.grant.rnti_type == srsran_rnti_type_ra) { - sched_nr_interface::sched_rar_t& rar = dl_res.rar[rar_count++]; + sched_nr_interface::rar_t& rar = dl_res.rar[rar_count++]; // for RARs we could actually move the byte_buffer to the PHY, as there are no retx pdsch.data[0] = assemble_rar(rar.grants); } @@ -372,6 +372,7 @@ int mac_nr::pusch_info(const srsran_slot_cfg_t& slot_cfg, mac_interface_phy_nr:: { uint16_t rnti = pusch_info.rnti; uint32_t nof_bytes = pusch_info.pdu->N_bytes; + // Handle UCI data if (not handle_uci_data(rnti, pusch_info.uci_cfg, pusch_info.pusch_data.uci)) { logger.error("Error handling UCI data from PUCCH reception"); @@ -405,7 +406,7 @@ int mac_nr::pusch_info(const srsran_slot_cfg_t& slot_cfg, mac_interface_phy_nr:: return SRSRAN_SUCCESS; } -srsran::byte_buffer_t* mac_nr::assemble_rar(srsran::const_span grants) +srsran::byte_buffer_t* mac_nr::assemble_rar(srsran::const_span grants) { srsran::mac_rar_pdu_nr rar_pdu; diff --git a/srsenb/src/stack/mac/nr/sched_nr.cc b/srsenb/src/stack/mac/nr/sched_nr.cc index 28e88bba6..85d25c5cd 100644 --- a/srsenb/src/stack/mac/nr/sched_nr.cc +++ b/srsenb/src/stack/mac/nr/sched_nr.cc @@ -70,7 +70,7 @@ sched_nr::sched_nr() : logger(&srslog::fetch_basic_logger("MAC-NR")) {} sched_nr::~sched_nr() {} -int sched_nr::config(const sched_cfg_t& sched_cfg, srsran::const_span cell_list) +int sched_nr::config(const sched_args_t& sched_cfg, srsran::const_span cell_list) { cfg = sched_params{sched_cfg}; logger = &srslog::fetch_basic_logger(sched_cfg.logger_name); @@ -153,7 +153,7 @@ void sched_nr::get_metrics(mac_metrics_t& metrics) sched_workers->get_metrics(metrics); } -int sched_nr::dl_rach_info(uint32_t cc, const dl_sched_rar_info_t& rar_info) +int sched_nr::dl_rach_info(uint32_t cc, const rar_info_t& rar_info) { sched_workers->enqueue_cc_event(cc, [this, cc, rar_info]() { cells[cc]->bwps[0].ra.dl_rach_info(rar_info); }); return SRSRAN_SUCCESS; diff --git a/srsenb/src/stack/mac/nr/sched_nr_cell.cc b/srsenb/src/stack/mac/nr/sched_nr_cell.cc index 909263669..0881d2144 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_cell.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_cell.cc @@ -17,7 +17,7 @@ namespace srsenb { namespace sched_nr_impl { -si_sched::si_sched(const bwp_params& bwp_cfg_) : +si_sched::si_sched(const bwp_params_t& bwp_cfg_) : bwp_cfg(&bwp_cfg_), logger(srslog::fetch_basic_logger(bwp_cfg_.sched_cfg.logger_name)) {} @@ -77,7 +77,7 @@ void si_sched::run_slot(bwp_slot_allocator& slot_alloc) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -ra_sched::ra_sched(const bwp_params& bwp_cfg_) : +ra_sched::ra_sched(const bwp_params_t& bwp_cfg_) : bwp_cfg(&bwp_cfg_), logger(srslog::fetch_basic_logger(bwp_cfg_.sched_cfg.logger_name)) {} @@ -220,16 +220,16 @@ int ra_sched::dl_rach_info(const dl_sched_rar_info_t& rar_info) return SRSRAN_SUCCESS; } -bwp_ctxt::bwp_ctxt(const bwp_params& bwp_cfg) : +bwp_ctxt::bwp_ctxt(const bwp_params_t& bwp_cfg) : cfg(&bwp_cfg), ra(bwp_cfg), grid(bwp_cfg), data_sched(new sched_nr_time_rr()) {} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -serv_cell_manager::serv_cell_manager(const sched_cell_params& cell_cfg_) : - cfg(cell_cfg_), logger(srslog::fetch_basic_logger(cell_cfg_.sched_cfg.logger_name)) +serv_cell_manager::serv_cell_manager(const cell_params_t& cell_cfg_) : + cfg(cell_cfg_), logger(srslog::fetch_basic_logger(cell_cfg_.sched_args.logger_name)) { - for (uint32_t bwp_id = 0; bwp_id < cfg.cell_cfg.bwps.size(); ++bwp_id) { + for (uint32_t bwp_id = 0; bwp_id < cfg.cfg.bwps.size(); ++bwp_id) { bwps.emplace_back(cell_cfg_.bwps[bwp_id]); } diff --git a/srsenb/src/stack/mac/nr/sched_nr_cfg.cc b/srsenb/src/stack/mac/nr/sched_nr_cfg.cc index 04f7ecaa6..f077d8edd 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_cfg.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_cfg.cc @@ -20,7 +20,25 @@ extern "C" { namespace srsenb { namespace sched_nr_impl { -bwp_params::bwp_params(const cell_cfg_t& cell, const sched_cfg_t& sched_cfg_, uint32_t cc_, uint32_t bwp_id_) : +void get_dci_locs(const srsran_coreset_t& coreset, + const srsran_search_space_t& search_space, + uint16_t rnti, + bwp_cce_pos_list& cce_locs) +{ + for (uint32_t sl = 0; sl < SRSRAN_NOF_SF_X_FRAME; ++sl) { + for (uint32_t agg_idx = 0; agg_idx < MAX_NOF_AGGR_LEVELS; ++agg_idx) { + pdcch_cce_pos_list pdcch_locs; + cce_locs[sl][agg_idx].resize(pdcch_locs.capacity()); + uint32_t n = + srsran_pdcch_nr_locations_coreset(&coreset, &search_space, rnti, agg_idx, sl, cce_locs[sl][agg_idx].data()); + cce_locs[sl][agg_idx].resize(n); + } + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +bwp_params_t::bwp_params_t(const cell_cfg_t& cell, const sched_args_t& sched_cfg_, uint32_t cc_, uint32_t bwp_id_) : cell_cfg(cell), sched_cfg(sched_cfg_), cc(cc_), @@ -73,39 +91,21 @@ bwp_params::bwp_params(const cell_cfg_t& cell, const sched_cfg_t& sched_cfg_, ui } } -sched_cell_params::sched_cell_params(uint32_t cc_, const cell_cfg_t& cell, const sched_cfg_t& sched_cfg_) : - cc(cc_), cell_cfg(cell), sched_cfg(sched_cfg_) +cell_params_t::cell_params_t(uint32_t cc_, const cell_cfg_t& cell, const sched_args_t& sched_cfg_) : + cc(cc_), cfg(cell), sched_args(sched_cfg_) { bwps.reserve(cell.bwps.size()); - for (uint32_t i = 0; i < cell_cfg.bwps.size(); ++i) { - bwps.emplace_back(cell_cfg, sched_cfg_, cc, i); + for (uint32_t i = 0; i < cfg.bwps.size(); ++i) { + bwps.emplace_back(cfg, sched_cfg_, cc, i); } srsran_assert(not bwps.empty(), "No BWPs were configured"); } -sched_params::sched_params(const sched_cfg_t& sched_cfg_) : sched_cfg(sched_cfg_) {} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void get_dci_locs(const srsran_coreset_t& coreset, - const srsran_search_space_t& search_space, - uint16_t rnti, - bwp_cce_pos_list& cce_locs) -{ - for (uint32_t sl = 0; sl < SRSRAN_NOF_SF_X_FRAME; ++sl) { - for (uint32_t agg_idx = 0; agg_idx < MAX_NOF_AGGR_LEVELS; ++agg_idx) { - pdcch_cce_pos_list pdcch_locs; - cce_locs[sl][agg_idx].resize(pdcch_locs.capacity()); - uint32_t n = - srsran_pdcch_nr_locations_coreset(&coreset, &search_space, rnti, agg_idx, sl, cce_locs[sl][agg_idx].data()); - cce_locs[sl][agg_idx].resize(n); - } - } -} +sched_params::sched_params(const sched_args_t& sched_cfg_) : sched_cfg(sched_cfg_) {} /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -bwp_ue_cfg::bwp_ue_cfg(uint16_t rnti_, const bwp_params& bwp_cfg_, const ue_cfg_t& uecfg_) : +bwp_ue_cfg::bwp_ue_cfg(uint16_t rnti_, const bwp_params_t& bwp_cfg_, const ue_cfg_t& uecfg_) : rnti(rnti_), cfg_(&uecfg_), bwp_cfg(&bwp_cfg_) { std::fill(ss_id_to_cce_idx.begin(), ss_id_to_cce_idx.end(), SRSRAN_UE_DL_NR_MAX_NOF_SEARCH_SPACE); diff --git a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc index 671461187..c64fdc51a 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc @@ -17,7 +17,7 @@ namespace srsenb { namespace sched_nr_impl { -bwp_slot_grid::bwp_slot_grid(const bwp_params& bwp_cfg_, uint32_t slot_idx_) : +bwp_slot_grid::bwp_slot_grid(const bwp_params_t& bwp_cfg_, uint32_t slot_idx_) : dl_prbs(bwp_cfg_.cfg.rb_width, bwp_cfg_.cfg.start_rb, bwp_cfg_.cfg.pdsch.rbg_size_cfg_1), ul_prbs(bwp_cfg_.cfg.rb_width, bwp_cfg_.cfg.start_rb, bwp_cfg_.cfg.pdsch.rbg_size_cfg_1), slot_idx(slot_idx_), @@ -52,7 +52,7 @@ void bwp_slot_grid::reset() rar.clear(); } -bwp_res_grid::bwp_res_grid(const bwp_params& bwp_cfg_) : cfg(&bwp_cfg_) +bwp_res_grid::bwp_res_grid(const bwp_params_t& bwp_cfg_) : cfg(&bwp_cfg_) { for (uint32_t sl = 0; sl < slots.capacity(); ++sl) { slots.emplace_back(*cfg, sl % static_cast(SRSRAN_NSLOTS_PER_FRAME_NR(0u))); @@ -161,7 +161,7 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t const int mcs = 0, max_harq_msg3_retx = 4; slot_cfg.idx = msg3_slot.to_uint(); bwp_pdcch_slot.rar.emplace_back(); - sched_nr_interface::sched_rar_t& rar_out = bwp_pdcch_slot.rar.back(); + sched_nr_interface::rar_t& rar_out = bwp_pdcch_slot.rar.back(); for (const dl_sched_rar_info_t& grant : pending_rars) { slot_ue& ue = (*slot_ues)[grant.temp_crnti]; diff --git a/srsenb/src/stack/mac/nr/sched_nr_helpers.cc b/srsenb/src/stack/mac/nr/sched_nr_helpers.cc index a2905226c..f45900c81 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_helpers.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_helpers.cc @@ -22,7 +22,7 @@ namespace sched_nr_impl { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template -void fill_dci_common(const slot_ue& ue, const bwp_params& bwp_cfg, DciDlOrUl& dci) +void fill_dci_common(const slot_ue& ue, const bwp_params_t& bwp_cfg, DciDlOrUl& dci) { const static uint32_t rv_idx[4] = {0, 2, 3, 1}; @@ -47,7 +47,7 @@ void fill_dci_common(const slot_ue& ue, const bwp_params& bwp_cfg, DciDlOrUl& dc dci.time_domain_assigment = 0; } -bool fill_dci_rar(prb_interval interv, uint16_t ra_rnti, const bwp_params& bwp_cfg, srsran_dci_dl_nr_t& dci) +bool fill_dci_rar(prb_interval interv, uint16_t ra_rnti, const bwp_params_t& bwp_cfg, srsran_dci_dl_nr_t& dci) { dci.mcs = 5; dci.ctx.format = srsran_dci_format_nr_1_0; @@ -65,7 +65,7 @@ bool fill_dci_rar(prb_interval interv, uint16_t ra_rnti, const bwp_params& bwp_c return true; } -bool fill_dci_msg3(const slot_ue& ue, const bwp_params& bwp_cfg, srsran_dci_ul_nr_t& msg3_dci) +bool fill_dci_msg3(const slot_ue& ue, const bwp_params_t& bwp_cfg, srsran_dci_ul_nr_t& msg3_dci) { fill_dci_common(ue, bwp_cfg, msg3_dci); msg3_dci.ctx.coreset_id = ue.cfg->phy().pdcch.ra_search_space.coreset_id; @@ -82,7 +82,7 @@ bool fill_dci_msg3(const slot_ue& ue, const bwp_params& bwp_cfg, srsran_dci_ul_n } void fill_dl_dci_ue_fields(const slot_ue& ue, - const bwp_params& bwp_cfg, + const bwp_params_t& bwp_cfg, uint32_t ss_id, srsran_dci_location_t dci_pos, srsran_dci_dl_nr_t& dci) @@ -101,7 +101,7 @@ void fill_dl_dci_ue_fields(const slot_ue& ue, } void fill_ul_dci_ue_fields(const slot_ue& ue, - const bwp_params& bwp_cfg, + const bwp_params_t& bwp_cfg, uint32_t ss_id, srsran_dci_location_t dci_pos, srsran_dci_ul_nr_t& dci) diff --git a/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc b/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc index dd2d8ec92..c478f05b3 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc @@ -16,11 +16,11 @@ namespace srsenb { namespace sched_nr_impl { -coreset_region::coreset_region(const bwp_params& bwp_cfg_, - uint32_t coreset_id_, - uint32_t slot_idx_, - pdcch_dl_list_t& dl_list_, - pdcch_ul_list_t& ul_list_) : +coreset_region::coreset_region(const bwp_params_t& bwp_cfg_, + uint32_t coreset_id_, + uint32_t slot_idx_, + pdcch_dl_list_t& dl_list_, + pdcch_ul_list_t& ul_list_) : coreset_cfg(&bwp_cfg_.cfg.pdcch.coreset[coreset_id_]), coreset_id(coreset_id_), slot_idx(slot_idx_), diff --git a/srsenb/src/stack/mac/nr/sched_nr_signalling.cc b/srsenb/src/stack/mac/nr/sched_nr_signalling.cc index 04f5f5b06..a3b310be7 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_signalling.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_signalling.cc @@ -75,10 +75,10 @@ void sched_ssb_basic(const slot_point& sl_point, uint32_t ssb_periodicity, ssb_l } } -void sched_dl_signalling(const bwp_params& bwp_params, - slot_point sl_pdcch, - ssb_list& ssb_list, - nzp_csi_rs_list& nzp_csi_rs) +void sched_dl_signalling(const bwp_params_t& bwp_params, + slot_point sl_pdcch, + ssb_list& ssb_list, + nzp_csi_rs_list& nzp_csi_rs) { srsran_slot_cfg_t cfg; cfg.idx = sl_pdcch.to_uint(); diff --git a/srsenb/src/stack/mac/nr/sched_nr_ue.cc b/srsenb/src/stack/mac/nr/sched_nr_ue.cc index 77cbfa86e..011591756 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_ue.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_ue.cc @@ -21,7 +21,7 @@ slot_ue::slot_ue(uint16_t rnti_, slot_point slot_rx_, uint32_t cc_) : rnti(rnti_ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -ue_carrier::ue_carrier(uint16_t rnti_, const ue_cfg_t& uecfg_, const sched_cell_params& cell_params_) : +ue_carrier::ue_carrier(uint16_t rnti_, const ue_cfg_t& uecfg_, const cell_params_t& cell_params_) : rnti(rnti_), cc(cell_params_.cc), bwp_cfg(rnti_, cell_params_.bwps[0], uecfg_), @@ -59,7 +59,7 @@ slot_ue ue_carrier::try_reserve(slot_point pdcch_slot, sfu.dl_pending_bytes = dl_pending_bytes; sfu.ul_pending_bytes = ul_pending_bytes; - const srsran_duplex_config_nr_t& tdd_cfg = cell_params.cell_cfg.duplex; + const srsran_duplex_config_nr_t& tdd_cfg = cell_params.cfg.duplex; if (srsran_duplex_nr_is_dl(&tdd_cfg, 0, sfu.pdsch_slot.slot_idx())) { // If DL enabled sfu.h_dl = harq_ent.find_pending_dl_retx(); diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc index df32ed526..0fd5d0f5e 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_worker.cc @@ -22,7 +22,7 @@ slot_cc_worker::slot_cc_worker(serv_cell_manager& cc_sched) : cell(cc_sched), cfg(cc_sched.cfg), bwp_alloc(cc_sched.bwps[0].grid), - logger(srslog::fetch_basic_logger(cc_sched.cfg.sched_cfg.logger_name)) + logger(srslog::fetch_basic_logger(cc_sched.cfg.sched_args.logger_name)) {} void slot_cc_worker::enqueue_cc_event(srsran::move_callback ev) @@ -116,7 +116,7 @@ void slot_cc_worker::run(slot_point pdcch_slot, ue_map_t& ue_db) void slot_cc_worker::alloc_dl_ues() { - if (not cfg.sched_cfg.pdsch_enabled) { + if (not cfg.sched_args.pdsch_enabled) { return; } cell.bwps[0].data_sched->sched_dl_users(slot_ues, bwp_alloc); @@ -124,7 +124,7 @@ void slot_cc_worker::alloc_dl_ues() void slot_cc_worker::alloc_ul_ues() { - if (not cfg.sched_cfg.pusch_enabled) { + if (not cfg.sched_args.pusch_enabled) { return; } cell.bwps[0].data_sched->sched_ul_users(slot_ues, bwp_alloc); diff --git a/srsenb/test/mac/nr/sched_nr_rar_test.cc b/srsenb/test/mac/nr/sched_nr_rar_test.cc index 1104b914f..b9acd4a6c 100644 --- a/srsenb/test/mac/nr/sched_nr_rar_test.cc +++ b/srsenb/test/mac/nr/sched_nr_rar_test.cc @@ -30,15 +30,15 @@ void test_single_prach() std::default_random_engine rgen(rand_gen()); // Set scheduler configuration - sched_nr_interface::sched_cfg_t sched_cfg{}; + sched_nr_interface::sched_args_t sched_cfg{}; sched_cfg.auto_refill_buffer = std::uniform_int_distribution{0, 1}(rgen) > 0; // Set cells configuration std::vector cells_cfg = get_default_cells_cfg(1); sched_params schedparams{sched_cfg}; schedparams.cells.emplace_back(0, cells_cfg[0], sched_cfg); - const bwp_params& bwpparams = schedparams.cells[0].bwps[0]; - slot_ue_map_t slot_ues; + const bwp_params_t& bwpparams = schedparams.cells[0].bwps[0]; + slot_ue_map_t slot_ues; ra_sched rasched(bwpparams); TESTASSERT(rasched.empty()); @@ -81,7 +81,7 @@ void test_single_prach() } // A PRACH arrives... - sched_nr_interface::dl_sched_rar_info_t rainfo{}; + sched_nr_interface::rar_info_t rainfo{}; rainfo.preamble_idx = 10; rainfo.temp_crnti = rnti; rainfo.prach_slot = prach_slot; diff --git a/srsenb/test/mac/nr/sched_nr_sim_ue.cc b/srsenb/test/mac/nr/sched_nr_sim_ue.cc index 59b7766e0..5034e6cb1 100644 --- a/srsenb/test/mac/nr/sched_nr_sim_ue.cc +++ b/srsenb/test/mac/nr/sched_nr_sim_ue.cc @@ -90,7 +90,7 @@ void sched_nr_ue_sim::update_dl_harqs(const sched_nr_cc_output_res_t& cc_out) } } -sched_nr_sim_base::sched_nr_sim_base(const sched_nr_interface::sched_cfg_t& sched_args, +sched_nr_sim_base::sched_nr_sim_base(const sched_nr_interface::sched_args_t& sched_args, const std::vector& cell_cfg_list, std::string test_name_) : logger(srslog::fetch_basic_logger("TEST")), @@ -123,7 +123,7 @@ int sched_nr_sim_base::add_user(uint16_t rnti, sched_ptr->ue_cfg(rnti, ue_cfg_); ue_db.insert(std::make_pair(rnti, sched_nr_ue_sim(rnti, ue_cfg_, current_slot_tx, preamble_idx))); - sched_nr_interface::dl_sched_rar_info_t rach_info{}; + sched_nr_interface::rar_info_t rach_info{}; rach_info.temp_crnti = rnti; rach_info.prach_slot = tti_rx; rach_info.preamble_idx = preamble_idx; @@ -162,7 +162,7 @@ void sched_nr_sim_base::update(sched_nr_cc_output_res_t& cc_out) // Run common tests test_dl_pdcch_consistency(cc_out.dl_cc_result->dl_sched.pdcch_dl); test_pdsch_consistency(cc_out.dl_cc_result->dl_sched.pdsch); - test_ssb_scheduled_grant(cc_out.slot, ctxt.cell_params[cc_out.cc].cell_cfg, cc_out.dl_cc_result->dl_sched.ssb); + test_ssb_scheduled_grant(cc_out.slot, ctxt.cell_params[cc_out.cc].cfg, cc_out.dl_cc_result->dl_sched.ssb); // Run UE-dedicated tests test_dl_sched_result(ctxt, cc_out); diff --git a/srsenb/test/mac/nr/sched_nr_sim_ue.h b/srsenb/test/mac/nr/sched_nr_sim_ue.h index cecb1a050..05a347b7e 100644 --- a/srsenb/test/mac/nr/sched_nr_sim_ue.h +++ b/srsenb/test/mac/nr/sched_nr_sim_ue.h @@ -74,8 +74,8 @@ struct sim_nr_ue_ctxt_t { } }; struct sim_nr_enb_ctxt_t { - srsran::span cell_params; - std::map ue_db; + srsran::span cell_params; + std::map ue_db; }; class sched_nr_ue_sim @@ -101,7 +101,7 @@ private: class sched_nr_sim_base { public: - sched_nr_sim_base(const sched_nr_interface::sched_cfg_t& sched_args, + sched_nr_sim_base(const sched_nr_interface::sched_args_t& sched_args, const std::vector& cell_params_, std::string test_name); virtual ~sched_nr_sim_base(); @@ -129,9 +129,9 @@ public: const sched_nr_ue_sim* ret = find_rnti(rnti); return ret == nullptr ? nullptr : &ret->get_ctxt().ue_cfg; } - sched_nr* get_sched() { return sched_ptr.get(); } - srsran::const_span get_cell_params() { return cell_params; } - slot_point get_slot_rx() const + sched_nr* get_sched() { return sched_ptr.get(); } + srsran::const_span get_cell_params() { return cell_params; } + slot_point get_slot_rx() const { std::lock_guard lock(mutex); return current_slot_tx; @@ -149,11 +149,11 @@ private: int set_default_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_slot_events& pending_events); int apply_slot_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_nr_slot_events& events); - std::string test_name; - srslog::basic_logger& logger; - srslog::basic_logger& mac_logger; - std::unique_ptr sched_ptr; - std::vector cell_params; + std::string test_name; + srslog::basic_logger& logger; + srslog::basic_logger& mac_logger; + std::unique_ptr sched_ptr; + std::vector cell_params; slot_point current_slot_tx; int cc_finished = 0; diff --git a/srsenb/test/mac/nr/sched_nr_test.cc b/srsenb/test/mac/nr/sched_nr_test.cc index 51f995f6d..349069359 100644 --- a/srsenb/test/mac/nr/sched_nr_test.cc +++ b/srsenb/test/mac/nr/sched_nr_test.cc @@ -81,7 +81,7 @@ void sched_nr_cfg_serialized_test() uint32_t max_nof_ttis = 1000, nof_sectors = 4; task_job_manager tasks; - sched_nr_interface::sched_cfg_t cfg; + sched_nr_interface::sched_args_t cfg; cfg.auto_refill_buffer = true; std::vector cells_cfg = get_default_cells_cfg(nof_sectors); @@ -132,7 +132,7 @@ void sched_nr_cfg_parallel_cc_test() uint32_t max_nof_ttis = 1000; task_job_manager tasks; - sched_nr_interface::sched_cfg_t cfg; + sched_nr_interface::sched_args_t cfg; cfg.auto_refill_buffer = true; std::vector cells_cfg = get_default_cells_cfg(nof_sectors); From 6926754e67c5320fb39d660926464468536c711f Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 12 Oct 2021 22:15:12 +0100 Subject: [PATCH 100/208] nr,sched: fix sched logging in case of HARQ CRC=KO --- srsenb/src/stack/mac/nr/sched_nr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/stack/mac/nr/sched_nr.cc b/srsenb/src/stack/mac/nr/sched_nr.cc index 85d25c5cd..63c56220d 100644 --- a/srsenb/src/stack/mac/nr/sched_nr.cc +++ b/srsenb/src/stack/mac/nr/sched_nr.cc @@ -179,7 +179,7 @@ void sched_nr::dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb void sched_nr::ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) { sched_workers->enqueue_cc_feedback(rnti, cc, [this, pid, crc](ue_carrier& ue_cc) { - if (ue_cc.harq_ent.ul_crc_info(pid, crc) != SRSRAN_SUCCESS) { + if (ue_cc.harq_ent.ul_crc_info(pid, crc) < 0) { logger->warning("SCHED: rnti=0x%x, received CRC for empty pid=%d", ue_cc.rnti, pid); } }); From 7ecca61d60c35cb1b5fd9671fbe1b3bd3e5e78e4 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Fri, 8 Oct 2021 18:59:19 +0200 Subject: [PATCH 101/208] Enhanced nr_phy_test with better PRACH stats --- test/phy/dummy_gnb_stack.h | 6 ++- test/phy/dummy_ue_stack.h | 11 ++++-- test/phy/nr_phy_test.cc | 80 +++++++++++++++++++++++++------------- 3 files changed, 67 insertions(+), 30 deletions(-) diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index 390911020..b9b699db9 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -36,7 +36,9 @@ class gnb_dummy_stack : public srsenb::stack_interface_phy_nr public: struct prach_metrics_t { uint32_t count; - float avg_ta; + float avg_ta = 0.0f; + float min_ta = +INFINITY; + float max_ta = -INFINITY; }; struct pucch_metrics_t { float epre_db_avg = 0.0f; @@ -706,6 +708,8 @@ public: std::unique_lock lock(metrics_mutex); prach_metrics_t& prach_metrics = metrics.prach[rach_info.preamble]; prach_metrics.avg_ta = SRSRAN_VEC_SAFE_CMA((float)rach_info.time_adv, prach_metrics.avg_ta, prach_metrics.count); + prach_metrics.min_ta = SRSRAN_MIN((float)rach_info.time_adv, prach_metrics.min_ta); + prach_metrics.max_ta = SRSRAN_MAX((float)rach_info.time_adv, prach_metrics.max_ta); prach_metrics.count++; } diff --git a/test/phy/dummy_ue_stack.h b/test/phy/dummy_ue_stack.h index 07254f1ee..51601d4b7 100644 --- a/test/phy/dummy_ue_stack.h +++ b/test/phy/dummy_ue_stack.h @@ -29,6 +29,7 @@ public: private: std::mutex rnti_mutex; + srsran_random_t random_gen = srsran_random_init(0x1323); srsran_rnti_type_t dl_rnti_type = srsran_rnti_type_c; uint16_t rnti = 0; bool valid = false; @@ -58,7 +59,7 @@ public: { valid = true; } - ~ue_dummy_stack() = default; + ~ue_dummy_stack() { srsran_random_free(random_gen); } void in_sync() override {} void out_of_sync() override {} void run_tti(const uint32_t tti) override @@ -68,8 +69,12 @@ public: uint32_t slot_idx = tti % SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz); uint32_t sfn = tti / SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz); if (slot_idx == 0 and sfn % prach_period == 0) { - phy.send_prach(0, prach_preamble, 0.0f, 0.0f); - metrics.prach[prach_preamble].count++; + uint32_t prach_preamble_ = prach_preamble; + if (prach_preamble_ >= 64) { + prach_preamble_ = srsran_random_uniform_int_dist(random_gen, 0, 63); + } + phy.send_prach(0, prach_preamble_, 0.0f, 0.0f); + metrics.prach[prach_preamble_].count++; } } } diff --git a/test/phy/nr_phy_test.cc b/test/phy/nr_phy_test.cc index bbc744744..e957ec4f3 100644 --- a/test/phy/nr_phy_test.cc +++ b/test/phy/nr_phy_test.cc @@ -21,10 +21,11 @@ // shorten boost program options namespace namespace bpo = boost::program_options; -static double assert_sr_detection_min = 1.000; -static double assert_cqi_detection_min = 1.000; -static double assert_pusch_bler_max = 0.000; -static double assert_pdsch_bler_max = 0.000; +static double assert_sr_detection_min = 1.000; +static double assert_cqi_detection_min = 1.000; +static double assert_pusch_bler_max = 0.000; +static double assert_pdsch_bler_max = 0.000; +static double assert_prach_detection_min = 1.000; test_bench::args_t::args_t(int argc, char** argv) { @@ -236,34 +237,57 @@ int main(int argc, char** argv) } // Print PRACH + double prach_detection = 0.0; + uint32_t prach_tx_count = 0; + uint32_t prach_rx_count = 0; if (metrics.ue_stack.prach.size() > 0) { srsran::console("PRACH:\n"); - srsran::console(" UE transmitted:\n"); - srsran::console(" +------------+------------+\n"); - srsran::console(" | %10s | %10s |\n", "preamble", "count"); - srsran::console(" +------------+------------+\n"); + srsran::console( + " +------------+------------+------------+------------+------------+------------+------------+\n"); + srsran::console(" | %10s | %10s | %10s | %10s | %10s | %10s | %10s |\n", + "Preamble", + "Transmit'd", + "Received", + "Detection", + "Avg TA", + "Min TA", + "Max TA"); + srsran::console( + " +------------+------------+------------+------------+------------+------------+------------+\n"); for (const auto& p : metrics.ue_stack.prach) { - srsran::console(" | %10d | %10d |\n", p.first, p.second.count); - // Ensure the detected count matches with transmission - TESTASSERT(metrics.gnb_stack.prach.count(p.first)); - TESTASSERT(metrics.gnb_stack.prach[p.first].count == p.second.count); - } - srsran::console(" +------------+------------+\n\n"); - - srsran::console(" GNB detected:\n"); - srsran::console(" +------------+------------+------------+\n"); - srsran::console(" | %10s | %10s | %10s |\n", "preamble", "count", "avg TA"); - srsran::console(" +------------+------------+------------+\n"); - - for (const auto& p : metrics.gnb_stack.prach) { - srsran::console(" | %10d | %10d | %10.1f |\n", p.first, p.second.count, p.second.avg_ta); - - // Ensure all detected preambles were transmitted - TESTASSERT(metrics.ue_stack.prach.count(p.first) > 0); + // TESTASSERT(metrics.gnb_stack.prach.count(p.first)); + // TESTASSERT(metrics.gnb_stack.prach[p.first].count == p.second.count); + TESTASSERT(p.second.count != 0); + prach_tx_count += p.second.count; + + gnb_dummy_stack::prach_metrics_t gnb_prach = {}; + if (metrics.gnb_stack.prach.count(p.first) > 0) { + gnb_prach = metrics.gnb_stack.prach[p.first]; + } else { + gnb_prach.avg_ta = NAN; + gnb_prach.min_ta = NAN; + gnb_prach.max_ta = NAN; + } + prach_rx_count += gnb_prach.count; + + double detection = (double)gnb_prach.count / (double)p.second.count; + + srsran::console(" | %10d | %10d | %10d | %10.3f | %10.1f | %10.1f | %10.1f |\n", + p.first, + p.second.count, + gnb_prach.count, + detection, + gnb_prach.avg_ta, + gnb_prach.min_ta, + gnb_prach.max_ta); } - srsran::console(" +------------+------------+------------+\n\n"); + srsran::console( + " +------------+------------+------------+------------+------------+------------+------------+\n"); + } + if (prach_tx_count > 0) { + prach_detection = (double)prach_rx_count / (double)prach_tx_count; } // Print PUCCH @@ -410,6 +434,10 @@ int main(int argc, char** argv) "CQI report detection probability (%f) did not reach the assertion minimum (%f)", cqi_detection, assert_sr_detection_min); + srsran_assert(prach_tx_count == 0 or prach_detection >= assert_prach_detection_min, + "PRACH detection probability (%f) did not reach the assertion minimum (%f)", + prach_detection, + assert_prach_detection_min); // If reached here, the test is successful return SRSRAN_SUCCESS; From 5e1291b0c7f3e251cf040a77f862703ff22b438a Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 11 Oct 2021 15:33:40 +0200 Subject: [PATCH 102/208] Fix PRACH detection sequence generation for NR --- lib/src/phy/phch/prach.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/src/phy/phch/prach.c b/lib/src/phy/phch/prach.c index 6c6a954bf..e403f2bee 100644 --- a/lib/src/phy/phch/prach.c +++ b/lib/src/phy/phch/prach.c @@ -753,11 +753,16 @@ int srsran_prach_gen(srsran_prach_t* p, uint32_t seq_index, uint32_t freq_offset DEBUG( "N_zc: %d, N_cp: %d, N_seq: %d, N_ifft_prach=%d begin: %d", p->N_zc, p->N_cp, p->N_seq, p->N_ifft_prach, begin); + // Fill bottom guard frequency domain with zeros + srsran_vec_cf_zero(p->ifft_in, begin); + // Map dft-precoded sequence to ifft bins - memset(p->ifft_in, 0, begin * sizeof(cf_t)); - memcpy(&p->ifft_in[begin], get_precoded_dft(p, seq_index), p->N_zc * sizeof(cf_t)); - memset(&p->ifft_in[begin + p->N_zc], 0, (p->N_ifft_prach - begin - p->N_zc) * sizeof(cf_t)); + srsran_vec_cf_copy(&p->ifft_in[begin], get_precoded_dft(p, seq_index), p->N_zc); + + // Fill top guard frequency domain with zeros + srsran_vec_cf_zero(&p->ifft_in[begin + p->N_zc], p->N_ifft_prach - begin - p->N_zc); + // Generate frequency domain signal srsran_dft_run(&p->ifft, p->ifft_in, p->ifft_out); // Copy CP into buffer @@ -977,7 +982,7 @@ int srsran_prach_detect_offset(srsran_prach_t* p, uint32_t N_rb_ul = srsran_nof_prb(p->N_ifft_ul); uint32_t k_0 = freq_offset * N_RB_SC - N_rb_ul * N_RB_SC / 2 + p->N_ifft_ul / 2; uint32_t K = DELTA_F / DELTA_F_RA; - uint32_t begin = PHI + (K * k_0) + (K / 2); + uint32_t begin = PHI + (K * k_0) + (p->is_nr ? 1 : (K / 2)); memcpy(p->prach_bins, &p->signal_fft[begin], p->N_zc * sizeof(cf_t)); int loops = (p->successive_cancellation) ? SUCCESSIVE_CANCELLATION_ITS : 1; From 3c4efba4180e5801cea0a64e8b5c71755b61fdaf Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 11 Oct 2021 15:34:16 +0200 Subject: [PATCH 103/208] Added missing parameters to NR PHY configuration factory --- lib/src/common/phy_cfg_nr_default.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/src/common/phy_cfg_nr_default.cc b/lib/src/common/phy_cfg_nr_default.cc index 58c8b1fcb..d457aa6cd 100644 --- a/lib/src/common/phy_cfg_nr_default.cc +++ b/lib/src/common/phy_cfg_nr_default.cc @@ -384,10 +384,13 @@ void phy_cfg_nr_default_t::make_harq_auto(srsran_harq_ack_cfg_hl_t& harq, void phy_cfg_nr_default_t::make_prach_default_lte(srsran_prach_cfg_t& prach) { - prach.config_idx = 0; - prach.freq_offset = 4; - prach.root_seq_idx = 0; - prach.is_nr = true; + prach.is_nr = true; + prach.config_idx = 0; + prach.root_seq_idx = 0; + prach.zero_corr_zone = 0; + prach.freq_offset = 4; + prach.num_ra_preambles = 64; + prach.hs_flag = false; } phy_cfg_nr_default_t::phy_cfg_nr_default_t(const reference_cfg_t& reference_cfg) From 8bab12fb00fd8ff26d7975e501fd490e0a255046 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 11 Oct 2021 15:34:45 +0200 Subject: [PATCH 104/208] Added NR case to prach_test --- lib/src/phy/phch/test/CMakeLists.txt | 2 ++ lib/src/phy/phch/test/prach_test.c | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/src/phy/phch/test/CMakeLists.txt b/lib/src/phy/phch/test/CMakeLists.txt index 7a93a4de9..4396418e9 100644 --- a/lib/src/phy/phch/test/CMakeLists.txt +++ b/lib/src/phy/phch/test/CMakeLists.txt @@ -573,6 +573,8 @@ add_lte_test(prach_zc0 prach_test -z 0) add_lte_test(prach_zc2 prach_test -z 2) add_lte_test(prach_zc3 prach_test -z 3) +add_nr_test(prach_nr prach_test -n 50 -f 0 -r 0 -z 0 -N 1) + add_executable(prach_test_multi prach_test_multi.c) target_link_libraries(prach_test_multi srsran_phy) diff --git a/lib/src/phy/phch/test/prach_test.c b/lib/src/phy/phch/test/prach_test.c index 26ee8f5be..fee53ef22 100644 --- a/lib/src/phy/phch/test/prach_test.c +++ b/lib/src/phy/phch/test/prach_test.c @@ -23,6 +23,7 @@ #define MAX_LEN 70176 +static bool is_nr = false; static uint32_t nof_prb = 50; static uint32_t config_idx = 3; static uint32_t root_seq_idx = 0; @@ -36,12 +37,13 @@ static void usage(char* prog) printf("\t-f Preamble format [Default 0]\n"); printf("\t-r Root sequence index [Default 0]\n"); printf("\t-z Zero correlation zone config [Default 1]\n"); + printf("\t-N Toggle LTE/NR operation, zero for LTE, non-zero for NR [Default %s]\n", is_nr ? "NR" : "LTE"); } static void parse_args(int argc, char** argv) { int opt; - while ((opt = getopt(argc, argv, "nfrz")) != -1) { + while ((opt = getopt(argc, argv, "nfrzN")) != -1) { switch (opt) { case 'n': nof_prb = (uint32_t)strtol(argv[optind], NULL, 10); @@ -55,6 +57,9 @@ static void parse_args(int argc, char** argv) case 'z': zero_corr_zone = (uint32_t)strtol(argv[optind], NULL, 10); break; + case 'N': + is_nr = (uint32_t)strtol(argv[optind], NULL, 10) > 0; + break; default: usage(argv[0]); exit(-1); @@ -74,6 +79,7 @@ int main(int argc, char** argv) srsran_prach_cfg_t prach_cfg; ZERO_OBJECT(prach_cfg); + prach_cfg.is_nr = is_nr; prach_cfg.config_idx = config_idx; prach_cfg.hs_flag = high_speed_flag; prach_cfg.freq_offset = 0; From 4cea3d92bd69c02d704dba8122f4f5c340cd141c Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 11 Oct 2021 15:36:00 +0200 Subject: [PATCH 105/208] NR PHY accepts multiple SF PRACH sequence --- srsue/hdr/phy/nr/worker_pool.h | 7 ++++++- srsue/src/phy/nr/sf_worker.cc | 7 ------- srsue/src/phy/nr/worker_pool.cc | 28 ++++++++++++++++++++++++---- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/srsue/hdr/phy/nr/worker_pool.h b/srsue/hdr/phy/nr/worker_pool.h index b49b90dfe..18d2cb98d 100644 --- a/srsue/hdr/phy/nr/worker_pool.h +++ b/srsue/hdr/phy/nr/worker_pool.h @@ -27,7 +27,12 @@ private: srsran::thread_pool pool; std::vector > workers; state phy_state; - std::unique_ptr prach_buffer = nullptr; + std::unique_ptr prach_buffer = nullptr; + uint32_t prach_nof_sf = 0; + uint32_t prach_sf_count = 0; + cf_t* prach_ptr = nullptr; + float prach_target_power = 0.0f; + uint32_t sf_sz = 0; public: sf_worker* operator[](std::size_t pos) { return workers.at(pos).get(); } diff --git a/srsue/src/phy/nr/sf_worker.cc b/srsue/src/phy/nr/sf_worker.cc index c64be5f0d..703084d82 100644 --- a/srsue/src/phy/nr/sf_worker.cc +++ b/srsue/src/phy/nr/sf_worker.cc @@ -88,13 +88,6 @@ void sf_worker::work_imp() tx_buffer.set(phy_state.args.rf_channel_offset, prach_ptr); tx_buffer.set_nof_samples(SRSRAN_SF_LEN_PRB_NR(phy_state.cfg.carrier.nof_prb)); - // Notify MAC about PRACH transmission - phy_state.stack->prach_sent(TTI_TX(tti_rx), - srsran_prach_nr_start_symbol(phy_state.cfg.prach.config_idx, phy_state.cfg.duplex.mode), - SRSRAN_SLOT_NR_MOD(phy_state.cfg.carrier.scs, TTI_TX(tti_rx)), - 0, - 0); - // Transmit NR PRACH common.worker_end(context, true, tx_buffer); diff --git a/srsue/src/phy/nr/worker_pool.cc b/srsue/src/phy/nr/worker_pool.cc index c9a46a12e..073e80ee0 100644 --- a/srsue/src/phy/nr/worker_pool.cc +++ b/srsue/src/phy/nr/worker_pool.cc @@ -78,10 +78,29 @@ sf_worker* worker_pool::wait_worker(uint32_t tti) // Generate PRACH if ready if (prach_buffer->is_ready_to_send(tti, phy_state.cfg.carrier.pci)) { - uint32_t nof_prach_sf = 0; - float prach_target_power = 0.0f; - cf_t* prach_ptr = prach_buffer->generate(phy_state.get_ul_cfo() / 15000, &nof_prach_sf, &prach_target_power); - worker->set_prach(prach_ptr, prach_target_power); + prach_ptr = prach_buffer->generate(phy_state.get_ul_cfo() / 15000, &prach_nof_sf, &prach_target_power); + + // Notify MAC about PRACH transmission + phy_state.stack->prach_sent(TTI_TX(tti), + srsran_prach_nr_start_symbol(phy_state.cfg.prach.config_idx, phy_state.cfg.duplex.mode), + SRSRAN_SLOT_NR_MOD(phy_state.cfg.carrier.scs, TTI_TX(tti)), + 0, + 0); + } + + // Set PRACH transmission buffer in workers if it is pending + if (prach_nof_sf > 0) { + // Set worker PRACH buffer + worker->set_prach(&prach_ptr[sf_sz * prach_sf_count], prach_target_power); + + // Increment SF counter + prach_sf_count++; + + // Reset PRACH pending subframe count + if (prach_sf_count >= prach_nof_sf) { + prach_nof_sf = 0; + prach_sf_count = 0; + } } return worker; @@ -141,6 +160,7 @@ bool worker_pool::set_config(const srsran::phy_cfg_nr_t& cfg) { uint32_t dl_arfcn = srsran::srsran_band_helper().freq_to_nr_arfcn(cfg.carrier.dl_center_frequency_hz); phy_state.cfg = cfg; + sf_sz = SRSRAN_SF_LEN_PRB_NR(cfg.carrier.nof_prb); logger.info("Setting new PHY configuration ARFCN=%d, PCI=%d", dl_arfcn, cfg.carrier.pci); From c7940f455c4238b3a1b9b339bec440a2f1040dfa Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 11 Oct 2021 15:36:34 +0200 Subject: [PATCH 106/208] More clear equation to calculate number of PRACH subframes --- srsue/src/phy/prach.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/phy/prach.cc b/srsue/src/phy/prach.cc index 9f679e5b5..f227ddf12 100644 --- a/srsue/src/phy/prach.cc +++ b/srsue/src/phy/prach.cc @@ -248,7 +248,7 @@ cf_t* prach::generate(float cfo, uint32_t* nof_sf, float* target_power) srsran_cfo_correct(&cfo_h, buffer[f_idx][preamble_idx], signal_buffer, cfo / srsran_symbol_sz(cell.nof_prb)); // pad guard symbols with zeros - uint32_t nsf = (len - 1) / SRSRAN_SF_LEN_PRB(cell.nof_prb) + 1; + uint32_t nsf = SRSRAN_CEIL(len, SRSRAN_SF_LEN_PRB(cell.nof_prb)); srsran_vec_cf_zero(&signal_buffer[len], (nsf * SRSRAN_SF_LEN_PRB(cell.nof_prb) - len)); *nof_sf = nsf; From 4e76d7fef626ee75674ba2ed9db2b9bde0e6d9c1 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 11 Oct 2021 15:37:11 +0200 Subject: [PATCH 107/208] Enhanced nr_phy_test to assert PRACH detection --- test/phy/CMakeLists.txt | 2 -- test/phy/dummy_ue_stack.h | 27 +++++++++++---------------- test/phy/nr_phy_test.cc | 14 ++++++++++++-- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/test/phy/CMakeLists.txt b/test/phy/CMakeLists.txt index 2488cbbf0..d0b697220 100644 --- a/test/phy/CMakeLists.txt +++ b/test/phy/CMakeLists.txt @@ -100,7 +100,6 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) --gnb.stack.pusch.slots=none # No PUSCH --gnb.phy.nof_threads=${NR_PHY_TEST_GNB_NOF_THREADS} --ue.stack.prach.period=30 # Transmit PRACH every 30 radio frames - --ue.stack.prach.preamble=10 # Use preamble 10 --ue.phy.nof_threads=${NR_PHY_TEST_UE_NOF_THREADS} ) @@ -110,7 +109,6 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) --gnb.stack.pdsch.slots=none # No PDSCH --gnb.stack.pusch.slots=none # No PUSCH --ue.stack.prach.period=30 # Transmit PRACH every 30 radio frames - --ue.stack.prach.preamble=10 # Use preamble 10 ${NR_PHY_TEST_COMMON_ARGS} ) diff --git a/test/phy/dummy_ue_stack.h b/test/phy/dummy_ue_stack.h index 51601d4b7..598099fec 100644 --- a/test/phy/dummy_ue_stack.h +++ b/test/phy/dummy_ue_stack.h @@ -37,6 +37,7 @@ private: uint32_t sr_count = 0; uint32_t prach_period = 0; uint32_t prach_preamble = 0; + bool prach_pending = false; metrics_t metrics = {}; srsue::phy_interface_stack_nr& phy; @@ -45,17 +46,12 @@ private: public: struct args_t { - uint16_t rnti = 0x1234; ///< C-RNTI for PUSCH and PDSCH transmissions - uint32_t sr_period = 0; ///< Indicates positive SR period in number of opportunities. Set to 0 to disable. - uint32_t prach_period = 0; ///< Requests PHY to transmit PRACH periodically in frames. Set to 0 to disable. - uint32_t prach_preamble = 0; ///< Requests PHY to transmit PRACH periodically in frames. Set to 0 to disable. + uint16_t rnti = 0x1234; ///< C-RNTI for PUSCH and PDSCH transmissions + uint32_t sr_period = 0; ///< Indicates positive SR period in number of opportunities. Set to 0 to disable. + uint32_t prach_period = 0; ///< Requests PHY to transmit PRACH periodically in frames. Set to 0 to disable. }; ue_dummy_stack(const args_t& args, srsue::phy_interface_stack_nr& phy_) : - rnti(args.rnti), - sr_period(args.sr_period), - prach_period(args.prach_period), - prach_preamble(args.prach_preamble), - phy(phy_) + rnti(args.rnti), sr_period(args.sr_period), prach_period(args.prach_period), phy(phy_) { valid = true; } @@ -68,13 +64,10 @@ public: if (prach_period != 0) { uint32_t slot_idx = tti % SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz); uint32_t sfn = tti / SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz); - if (slot_idx == 0 and sfn % prach_period == 0) { - uint32_t prach_preamble_ = prach_preamble; - if (prach_preamble_ >= 64) { - prach_preamble_ = srsran_random_uniform_int_dist(random_gen, 0, 63); - } - phy.send_prach(0, prach_preamble_, 0.0f, 0.0f); - metrics.prach[prach_preamble_].count++; + if (not prach_pending and slot_idx == 0 and sfn % prach_period == 0) { + prach_preamble = srsran_random_uniform_int_dist(random_gen, 0, 63); + phy.send_prach(0, prach_preamble, 0.0f, 0.0f); + prach_pending = true; } } } @@ -109,6 +102,8 @@ public: std::unique_lock lock(rnti_mutex); dl_rnti_type = srsran_rnti_type_ra; rnti = 1 + s_id + 14 * t_id + 14 * 80 * f_id + 14 * 80 * 8 * ul_carrier_id; + metrics.prach[prach_preamble].count++; + prach_pending = false; } bool sr_opportunity(uint32_t tti, uint32_t sr_id, bool meas_gap, bool ul_sch_tx) override { diff --git a/test/phy/nr_phy_test.cc b/test/phy/nr_phy_test.cc index e957ec4f3..9a7122313 100644 --- a/test/phy/nr_phy_test.cc +++ b/test/phy/nr_phy_test.cc @@ -26,6 +26,8 @@ static double assert_cqi_detection_min = 1.000; static double assert_pusch_bler_max = 0.000; static double assert_pdsch_bler_max = 0.000; static double assert_prach_detection_min = 1.000; +static double assert_prach_ta_min = 0.000; +static double assert_prach_ta_max = 0.000; test_bench::args_t::args_t(int argc, char** argv) { @@ -90,7 +92,6 @@ test_bench::args_t::args_t(int argc, char** argv) options_ue_stack.add_options() ("ue.stack.sr.period", bpo::value(&ue_stack.sr_period)->default_value(ue_stack.sr_period), "SR period in number of opportunities. Set 0 to disable and 1 for all.") ("ue.stack.prach.period", bpo::value(&ue_stack.prach_period)->default_value(ue_stack.prach_period), "PRACH period in SFN. Set 0 to disable and 1 for all.") - ("ue.stack.prach.preamble", bpo::value(&ue_stack.prach_preamble)->default_value(ue_stack.prach_preamble), "PRACH preamble. Set 0 to disable and 1 for all.") ; options_assertion.add_options() @@ -98,6 +99,8 @@ test_bench::args_t::args_t(int argc, char** argv) ("assert.cqi.detection.min", bpo::value(&assert_cqi_detection_min)->default_value(assert_cqi_detection_min), "CQI report minimum detection threshold") ("assert.pusch.bler.max", bpo::value(&assert_pusch_bler_max)->default_value(assert_pusch_bler_max), "PUSCH maximum BLER threshold") ("assert.pdsch.bler.max", bpo::value(&assert_pdsch_bler_max)->default_value(assert_pdsch_bler_max), "PDSCH maximum BLER threshold") + ("assert.prach.ta.min", bpo::value(&assert_prach_ta_min)->default_value(assert_prach_ta_min), "PRACH estimated TA minimum value threshold") + ("assert.prach.ta.max", bpo::value(&assert_prach_ta_max)->default_value(assert_prach_ta_max), "PRACH estimated TA maximum value threshold") ; options.add(options_gnb_stack).add(options_gnb_phy).add(options_ue_stack).add(options_ue_phy).add_options() @@ -148,7 +151,7 @@ test_bench::args_t::args_t(int argc, char** argv) gnb_stack.rnti = rnti; gnb_stack.phy_cfg = phy_cfg; - gnb_stack.wait_preamble = ue_stack.prach_preamble > 0; + gnb_stack.wait_preamble = ue_stack.prach_period > 0; if (gnb_stack.pdsch.rb_length == 0) { gnb_stack.pdsch.rb_length = phy_cfg.carrier.nof_prb; @@ -238,6 +241,7 @@ int main(int argc, char** argv) // Print PRACH double prach_detection = 0.0; + double prach_ta = 0.0; uint32_t prach_tx_count = 0; uint32_t prach_rx_count = 0; if (metrics.ue_stack.prach.size() > 0) { @@ -265,6 +269,7 @@ int main(int argc, char** argv) gnb_dummy_stack::prach_metrics_t gnb_prach = {}; if (metrics.gnb_stack.prach.count(p.first) > 0) { gnb_prach = metrics.gnb_stack.prach[p.first]; + prach_ta = SRSRAN_VEC_SAFE_CMA(gnb_prach.avg_ta, prach_ta, prach_rx_count); } else { gnb_prach.avg_ta = NAN; gnb_prach.min_ta = NAN; @@ -438,6 +443,11 @@ int main(int argc, char** argv) "PRACH detection probability (%f) did not reach the assertion minimum (%f)", prach_detection, assert_prach_detection_min); + srsran_assert(prach_tx_count == 0 or (prach_ta >= assert_prach_ta_min and prach_ta <= assert_prach_ta_max), + "PRACH TA average measurement %f is higher than minimum (%d) or above maximum (%f)", + prach_ta, + assert_prach_ta_min, + assert_prach_ta_max); // If reached here, the test is successful return SRSRAN_SUCCESS; From 753edc7d7b5af5e231cace77d16bad9a7b4d8c15 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 11 Oct 2021 16:24:28 +0200 Subject: [PATCH 108/208] Force NR PRACH scaling to 0.99 of the DAC dynamic range --- srsue/src/phy/nr/worker_pool.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/srsue/src/phy/nr/worker_pool.cc b/srsue/src/phy/nr/worker_pool.cc index 073e80ee0..dfa333166 100644 --- a/srsue/src/phy/nr/worker_pool.cc +++ b/srsue/src/phy/nr/worker_pool.cc @@ -80,6 +80,16 @@ sf_worker* worker_pool::wait_worker(uint32_t tti) if (prach_buffer->is_ready_to_send(tti, phy_state.cfg.carrier.pci)) { prach_ptr = prach_buffer->generate(phy_state.get_ul_cfo() / 15000, &prach_nof_sf, &prach_target_power); + // Scale signal to maximum + { + float* ptr = (float*)prach_ptr; + int max_i = srsran_vec_max_abs_fi(ptr, 2 * sf_sz); + float max = ptr[max_i]; + if (std::isnormal(max)) { + srsran_vec_sc_prod_cfc(prach_ptr, 0.99f / max, prach_ptr, sf_sz * prach_nof_sf); + } + } + // Notify MAC about PRACH transmission phy_state.stack->prach_sent(TTI_TX(tti), srsran_prach_nr_start_symbol(phy_state.cfg.prach.config_idx, phy_state.cfg.duplex.mode), From a31a40184d52f403908cf44aea07c983ce43c70f Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 12 Oct 2021 19:00:14 +0200 Subject: [PATCH 109/208] Fix NR PRACH encoding --- lib/src/phy/phch/prach.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/src/phy/phch/prach.c b/lib/src/phy/phch/prach.c index e403f2bee..1351fd716 100644 --- a/lib/src/phy/phch/prach.c +++ b/lib/src/phy/phch/prach.c @@ -615,7 +615,9 @@ int srsran_prach_set_cell_(srsran_prach_t* p, int ret = SRSRAN_ERROR; if (p != NULL && N_ifft_ul < 2049 && cfg->config_idx < 64 && cfg->root_seq_idx < MAX_ROOTS) { if (N_ifft_ul > p->max_N_ifft_ul) { - ERROR("PRACH: Error in set_cell(): N_ifft_ul must be lower or equal max_N_ifft_ul in init()"); + ERROR("PRACH: Error in set_cell(): N_ifft_ul (%d) must be lower or equal max_N_ifft_ul (%d) in init()", + N_ifft_ul, + p->max_N_ifft_ul); return -1; } @@ -743,7 +745,7 @@ int srsran_prach_gen(srsran_prach_t* p, uint32_t seq_index, uint32_t freq_offset uint32_t N_rb_ul = srsran_nof_prb(p->N_ifft_ul); uint32_t k_0 = freq_offset * N_RB_SC - N_rb_ul * N_RB_SC / 2 + p->N_ifft_ul / 2; uint32_t K = DELTA_F / DELTA_F_RA; - uint32_t begin = PHI + (K * k_0) + (p->is_nr ? 1 : (K / 2)); + uint32_t begin = PHI + (K * k_0) + (p->is_nr ? 0 : (K / 2)); if (6 + freq_offset > N_rb_ul) { ERROR("Error no space for PRACH: frequency offset=%d, N_rb_ul=%d", freq_offset, N_rb_ul); @@ -982,7 +984,7 @@ int srsran_prach_detect_offset(srsran_prach_t* p, uint32_t N_rb_ul = srsran_nof_prb(p->N_ifft_ul); uint32_t k_0 = freq_offset * N_RB_SC - N_rb_ul * N_RB_SC / 2 + p->N_ifft_ul / 2; uint32_t K = DELTA_F / DELTA_F_RA; - uint32_t begin = PHI + (K * k_0) + (p->is_nr ? 1 : (K / 2)); + uint32_t begin = PHI + (K * k_0) + (p->is_nr ? 0 : (K / 2)); memcpy(p->prach_bins, &p->signal_fft[begin], p->N_zc * sizeof(cf_t)); int loops = (p->successive_cancellation) ? SUCCESSIVE_CANCELLATION_ITS : 1; From f250c83a66aa8ceb645e517ace88975bfed20994 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 12 Oct 2021 19:01:15 +0200 Subject: [PATCH 110/208] Minor NR configuration fixes --- srsenb/src/enb_cfg_parser.cc | 2 +- srsenb/src/stack/rrc/nr/cell_asn1_config.cc | 1 + srsenb/src/stack/rrc/rrc_nr.cc | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index c3c17694a..6c55e2c38 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -1498,7 +1498,7 @@ int set_derived_args_nr(all_args_t* args_, rrc_nr_cfg_t* rrc_cfg_, phy_cfg_t* ph cfg.phy_cell.prach.is_nr = true; cfg.phy_cell.prach.config_idx = 0; cfg.phy_cell.prach.root_seq_idx = 0; - cfg.phy_cell.prach.freq_offset = phy_cfg_->prach_cnfg.prach_cfg_info.prach_freq_offset; + cfg.phy_cell.prach.freq_offset = 1; cfg.phy_cell.prach.num_ra_preambles = cfg.phy_cell.num_ra_preambles; cfg.phy_cell.prach.hs_flag = phy_cfg_->prach_cnfg.prach_cfg_info.high_speed_flag; cfg.phy_cell.prach.tdd_config.configured = (cfg.duplex_mode == SRSRAN_DUPLEX_MODE_TDD); diff --git a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc index 606711302..ce0906ed1 100644 --- a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc +++ b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc @@ -240,6 +240,7 @@ int fill_serv_cell_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, ser serv_common.ss_pbch_block_pwr = 0; serv_common.n_timing_advance_offset_present = true; serv_common.n_timing_advance_offset = asn1::rrc_nr::serving_cell_cfg_common_s::n_timing_advance_offset_opts::n0; + serv_common.n_timing_advance_offset_present = true; serv_common.dmrs_type_a_position = asn1::rrc_nr::serving_cell_cfg_common_s::dmrs_type_a_position_opts::pos2; serv_common.pci_present = true; diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 567249067..1ab477eef 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -1143,7 +1143,7 @@ int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bw rach_cfg_common_pack.setup().ssb_per_rach_occasion_and_cb_preambs_per_ssb_present = true; rach_cfg_common_pack.setup().ssb_per_rach_occasion_and_cb_preambs_per_ssb.set_one(); rach_cfg_common_pack.setup().ssb_per_rach_occasion_and_cb_preambs_per_ssb.one() = - asn1::rrc_nr::rach_cfg_common_s::ssb_per_rach_occasion_and_cb_preambs_per_ssb_c_::one_opts::n8; + asn1::rrc_nr::rach_cfg_common_s::ssb_per_rach_occasion_and_cb_preambs_per_ssb_c_::one_opts::n64; return SRSRAN_SUCCESS; } From a9904c2b642d064fd141ba858430d8b5edc32981 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Fri, 8 Oct 2021 17:41:45 +0200 Subject: [PATCH 111/208] Fix info format string --- lib/src/radio/radio.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index 9d83d86fd..a1b2e2952 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -705,7 +705,7 @@ void radio::set_rx_srate(const double& srate) // Assert ratio is integer srsran_assert(((uint32_t)cur_rx_srate % (uint32_t)srate) == 0, - "The sampling rate ratio is not integer (%.2f MHz / %.2 MHz = %.3f)", + "The sampling rate ratio is not integer (%.2f MHz / %.2f MHz = %.3f)", cur_rx_srate / 1e6, srate / 1e6, cur_rx_srate / srate); @@ -958,7 +958,7 @@ void radio::set_tx_srate(const double& srate) // Assert ratio is integer srsran_assert(((uint32_t)cur_tx_srate % (uint32_t)srate) == 0, - "The sampling rate ratio is not integer (%.2f MHz / %.2 MHz = %.3f)", + "The sampling rate ratio is not integer (%.2f MHz / %.2f MHz = %.3f)", cur_rx_srate / 1e6, srate / 1e6, cur_rx_srate / srate); From 781ae4abfbb49d045e3c953448cb7726d7179837 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Tue, 12 Oct 2021 13:01:27 +0200 Subject: [PATCH 112/208] fix static analysis error (CID 373575) Signed-off-by: Carlo Galiotto --- srsenb/src/metrics_stdout.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/metrics_stdout.cc b/srsenb/src/metrics_stdout.cc index 48aa6aa69..0fe35cc1e 100644 --- a/srsenb/src/metrics_stdout.cc +++ b/srsenb/src/metrics_stdout.cc @@ -138,7 +138,7 @@ void metrics_stdout::set_metrics_helper(uint32_t num_ue } else { fmt::print(" {:>5.5}", "n/a"); } - int phr = (is_nr) ? mac.ues[i].phr : mac.ues[i].phr; + int phr = mac.ues[i].phr; fmt::print(" {:>3}", int(phr)); if (not isnan(phr)) { fmt::print(" {:>2}", int(phr)); From dc3e3a89f8fb9f1a5c41b9e61b1c159c310660dd Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Fri, 8 Oct 2021 15:58:17 +0200 Subject: [PATCH 113/208] mac: update CQI in MAC with CSI reports from PHY Signed-off-by: Carlo Galiotto --- lib/include/srsran/common/rwlock_guard.h | 8 ++++---- srsenb/hdr/stack/mac/mac.h | 2 +- srsenb/hdr/stack/mac/nr/ue_nr.h | 13 +++++++------ srsenb/src/stack/mac/mac.cc | 2 +- srsenb/src/stack/mac/nr/mac_nr.cc | 6 +++++- srsenb/src/stack/mac/nr/ue_nr.cc | 23 +++++++++++++++++++---- 6 files changed, 37 insertions(+), 17 deletions(-) diff --git a/lib/include/srsran/common/rwlock_guard.h b/lib/include/srsran/common/rwlock_guard.h index 7fe87e763..1eb32fad9 100644 --- a/lib/include/srsran/common/rwlock_guard.h +++ b/lib/include/srsran/common/rwlock_guard.h @@ -31,19 +31,19 @@ private: pthread_rwlock_t* rwlock; }; -// Shared lock guard that automatically unlocks rwlock on exit +// Shared lock guard that automatically unlocks rwmutex on exit class rwlock_read_guard { public: - rwlock_read_guard(pthread_rwlock_t& rwlock_) : rwlock(&rwlock_) { pthread_rwlock_rdlock(rwlock); } + rwlock_read_guard(pthread_rwlock_t& rwlock_) : rwmutex(&rwlock_) { pthread_rwlock_rdlock(rwmutex); } rwlock_read_guard(const rwlock_read_guard&) = delete; rwlock_read_guard(rwlock_read_guard&&) = delete; rwlock_read_guard& operator=(const rwlock_read_guard&) = delete; rwlock_read_guard& operator=(rwlock_read_guard&&) = delete; - ~rwlock_read_guard() { pthread_rwlock_unlock(rwlock); } + ~rwlock_read_guard() { pthread_rwlock_unlock(rwmutex); } private: - pthread_rwlock_t* rwlock; + pthread_rwlock_t* rwmutex; }; } // namespace srsran diff --git a/srsenb/hdr/stack/mac/mac.h b/srsenb/hdr/stack/mac/mac.h index cbb7e4af3..8790d42a6 100644 --- a/srsenb/hdr/stack/mac/mac.h +++ b/srsenb/hdr/stack/mac/mac.h @@ -112,7 +112,7 @@ private: srslog::basic_logger& logger; - // We use a rwlock in MAC to allow multiple workers to access MAC simultaneously. No conflicts will happen since + // We use a rwmutex in MAC to allow multiple workers to access MAC simultaneously. No conflicts will happen since // access for different TTIs pthread_rwlock_t rwlock = {}; diff --git a/srsenb/hdr/stack/mac/nr/ue_nr.h b/srsenb/hdr/stack/mac/nr/ue_nr.h index 1cb587842..5f53dc52b 100644 --- a/srsenb/hdr/stack/mac/nr/ue_nr.h +++ b/srsenb/hdr/stack/mac/nr/ue_nr.h @@ -59,7 +59,7 @@ public: void metrics_phr(float phr); void metrics_dl_ri(uint32_t dl_cqi); void metrics_dl_pmi(uint32_t dl_cqi); - void metrics_dl_cqi(uint32_t dl_cqi); + void metrics_dl_cqi(const srsran_uci_cfg_nr_t& cfg_, uint32_t dl_cqi, bool valid_cqi); void metrics_dl_mcs(uint32_t mcs); void metrics_ul_mcs(uint32_t mcs); void metrics_cnt(); @@ -83,11 +83,12 @@ private: std::atomic active_state{true}; - uint32_t phr_counter = 0; - uint32_t dl_cqi_counter = 0; - uint32_t dl_ri_counter = 0; - uint32_t dl_pmi_counter = 0; - mac_ue_metrics_t ue_metrics = {}; + uint32_t phr_counter = 0; + uint32_t dl_cqi_counter = 0; + uint32_t dl_cqi_valid_counter = 0; + uint32_t dl_ri_counter = 0; + uint32_t dl_pmi_counter = 0; + mac_ue_metrics_t ue_metrics = {}; // UE-specific buffer for MAC PDU packing, unpacking and handling srsran::mac_sch_pdu_nr mac_pdu_dl, mac_pdu_ul; diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index 88c919f8f..2136c9ea7 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -996,7 +996,7 @@ void mac::write_mcch(const srsran::sib2_mbms_t* sib2_, rrc_h->add_user(SRSRAN_MRNTI, {}); } -// Internal helper function, caller must hold UE DB rwlock +// Internal helper function, caller must hold UE DB rwmutex bool mac::check_ue_active(uint16_t rnti) { if (not ue_db.contains(rnti)) { diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 150b0e2d0..a0319dac6 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -365,6 +365,11 @@ bool mac_nr::handle_uci_data(const uint16_t rnti, const srsran_uci_cfg_nr_t& cfg if (value.valid and value.sr > 0) { sched.ul_sr_info(cfg_.pucch.rnti); } + + // Process CQI + srsran::rwlock_read_guard rw_lock(rwlock); + ue_db[rnti]->metrics_dl_cqi(cfg_, value.csi->wideband_cri_ri_pmi_cqi.cqi, value.valid); + return true; } @@ -401,7 +406,6 @@ int mac_nr::pusch_info(const srsran_slot_cfg_t& slot_cfg, mac_interface_phy_nr:: srsran::rwlock_read_guard rw_lock(rwlock); if (ue_db.contains(rnti)) { ue_db[rnti]->metrics_rx(pusch_info.pusch_data.tb[0].crc, nof_bytes); - ue_db[rnti]->metrics_dl_cqi(15); // TODO extract correct CQI measurments } return SRSRAN_SUCCESS; } diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc index 623d5059d..e0e072b09 100644 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ b/srsenb/src/stack/mac/nr/ue_nr.cc @@ -194,11 +194,26 @@ void ue_nr::metrics_read(mac_ue_metrics_t* metrics_) ue_metrics = {}; } -void ue_nr::metrics_dl_cqi(uint32_t dl_cqi) +void ue_nr::metrics_dl_cqi(const srsran_uci_cfg_nr_t& cfg_, uint32_t dl_cqi, bool valid_cqi) { - std::lock_guard lock(metrics_mutex); - ue_metrics.dl_cqi = SRSRAN_VEC_CMA((float)dl_cqi, ue_metrics.dl_cqi, dl_cqi_counter); - dl_cqi_counter++; + // I think this is not necessary, as we locked from the calling function + // std::lock_guard lock(metrics_mutex); + + // Process CQI + for (uint32_t i = 0; i < cfg_.nof_csi; i++) { + // Increment CQI opportunity + dl_cqi_counter++; + + // Skip if invalid or not supported CSI report + if (not valid_cqi or cfg_.csi[i].cfg.quantity != SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI or + cfg_.csi[i].cfg.freq_cfg != SRSRAN_CSI_REPORT_FREQ_WIDEBAND) { + continue; + } + + // Add statistics + ue_metrics.dl_cqi = SRSRAN_VEC_SAFE_CMA(dl_cqi, ue_metrics.dl_cqi, dl_cqi_counter); + dl_cqi_valid_counter++; + } } void ue_nr::metrics_rx(bool crc, uint32_t tbs) From f53e01cfa366d43f6296726617ec64cda0059ca8 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Fri, 8 Oct 2021 18:33:05 +0200 Subject: [PATCH 114/208] mac: apply changes by PR reviewers - reinstate write_lock on ue metrics - change "rwlock" variable name in mac_nr.h Signed-off-by: Carlo Galiotto --- lib/include/srsran/common/rwlock_guard.h | 8 ++++---- srsenb/hdr/stack/mac/mac.h | 2 +- srsenb/hdr/stack/mac/nr/mac_nr.h | 2 +- srsenb/src/stack/mac/mac.cc | 2 +- srsenb/src/stack/mac/nr/mac_nr.cc | 18 +++++++++--------- srsenb/src/stack/mac/nr/ue_nr.cc | 3 +-- 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/lib/include/srsran/common/rwlock_guard.h b/lib/include/srsran/common/rwlock_guard.h index 1eb32fad9..7fe87e763 100644 --- a/lib/include/srsran/common/rwlock_guard.h +++ b/lib/include/srsran/common/rwlock_guard.h @@ -31,19 +31,19 @@ private: pthread_rwlock_t* rwlock; }; -// Shared lock guard that automatically unlocks rwmutex on exit +// Shared lock guard that automatically unlocks rwlock on exit class rwlock_read_guard { public: - rwlock_read_guard(pthread_rwlock_t& rwlock_) : rwmutex(&rwlock_) { pthread_rwlock_rdlock(rwmutex); } + rwlock_read_guard(pthread_rwlock_t& rwlock_) : rwlock(&rwlock_) { pthread_rwlock_rdlock(rwlock); } rwlock_read_guard(const rwlock_read_guard&) = delete; rwlock_read_guard(rwlock_read_guard&&) = delete; rwlock_read_guard& operator=(const rwlock_read_guard&) = delete; rwlock_read_guard& operator=(rwlock_read_guard&&) = delete; - ~rwlock_read_guard() { pthread_rwlock_unlock(rwmutex); } + ~rwlock_read_guard() { pthread_rwlock_unlock(rwlock); } private: - pthread_rwlock_t* rwmutex; + pthread_rwlock_t* rwlock; }; } // namespace srsran diff --git a/srsenb/hdr/stack/mac/mac.h b/srsenb/hdr/stack/mac/mac.h index 8790d42a6..cbb7e4af3 100644 --- a/srsenb/hdr/stack/mac/mac.h +++ b/srsenb/hdr/stack/mac/mac.h @@ -112,7 +112,7 @@ private: srslog::basic_logger& logger; - // We use a rwmutex in MAC to allow multiple workers to access MAC simultaneously. No conflicts will happen since + // We use a rwlock in MAC to allow multiple workers to access MAC simultaneously. No conflicts will happen since // access for different TTIs pthread_rwlock_t rwlock = {}; diff --git a/srsenb/hdr/stack/mac/nr/mac_nr.h b/srsenb/hdr/stack/mac/nr/mac_nr.h index 3b44d5bba..e11a0e32f 100644 --- a/srsenb/hdr/stack/mac/nr/mac_nr.h +++ b/srsenb/hdr/stack/mac/nr/mac_nr.h @@ -111,7 +111,7 @@ private: std::vector cell_config; // Map of active UEs - pthread_rwlock_t rwlock = {}; + pthread_rwlock_t rwmutex = {}; static const uint16_t FIRST_RNTI = 0x4601; srsran::static_circular_map, SRSENB_MAX_UES> ue_db; diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index 2136c9ea7..88c919f8f 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -996,7 +996,7 @@ void mac::write_mcch(const srsran::sib2_mbms_t* sib2_, rrc_h->add_user(SRSRAN_MRNTI, {}); } -// Internal helper function, caller must hold UE DB rwmutex +// Internal helper function, caller must hold UE DB rwlock bool mac::check_ue_active(uint16_t rnti) { if (not ue_db.contains(rnti)) { diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index a0319dac6..9ee998905 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -200,7 +200,7 @@ uint16_t mac_nr::alloc_ue(uint32_t enb_cc_idx) // Pre-check if rnti is valid { - srsran::rwlock_read_guard read_lock(rwlock); + srsran::rwlock_read_guard read_lock(rwmutex); if (not is_rnti_valid_nolock(rnti)) { continue; } @@ -210,7 +210,7 @@ uint16_t mac_nr::alloc_ue(uint32_t enb_cc_idx) std::unique_ptr ue_ptr = std::unique_ptr(new ue_nr(rnti, enb_cc_idx, &sched, rrc, rlc, phy, logger)); // Add UE to rnti map - srsran::rwlock_write_guard rw_lock(rwlock); + srsran::rwlock_write_guard rw_lock(rwmutex); if (not is_rnti_valid_nolock(rnti)) { continue; } @@ -228,7 +228,7 @@ uint16_t mac_nr::alloc_ue(uint32_t enb_cc_idx) // Remove UE from the perspective of L2/L3 int mac_nr::remove_ue(uint16_t rnti) { - srsran::rwlock_write_guard lock(rwlock); + srsran::rwlock_write_guard lock(rwmutex); if (is_rnti_active_nolock(rnti)) { sched.ue_rem(rnti); ue_db.erase(rnti); @@ -292,7 +292,7 @@ int mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched dl_sched = dl_res.dl_sched; uint32_t rar_count = 0; - srsran::rwlock_read_guard rw_lock(rwlock); + srsran::rwlock_read_guard rw_lock(rwmutex); for (pdsch_t& pdsch : dl_sched.pdsch) { if (pdsch.sch.grant.rnti_type == srsran_rnti_type_c) { uint16_t rnti = pdsch.sch.grant.rnti; @@ -330,7 +330,7 @@ int mac_nr::get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched slot_point pusch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx}; ret = sched.get_ul_sched(pusch_slot, 0, ul_sched); - srsran::rwlock_read_guard rw_lock(rwlock); + srsran::rwlock_read_guard rw_lock(rwmutex); for (auto& pusch : ul_sched.pusch) { if (ue_db.contains(pusch.sch.grant.rnti)) { ue_db[pusch.sch.grant.rnti]->metrics_ul_mcs(pusch.sch.grant.tb->mcs); @@ -355,7 +355,7 @@ bool mac_nr::handle_uci_data(const uint16_t rnti, const srsran_uci_cfg_nr_t& cfg const srsran_harq_ack_bit_t* ack_bit = &cfg_.ack.bits[i]; bool is_ok = (value.ack[i] == 1) and value.valid; sched.dl_ack_info(rnti, 0, ack_bit->pid, 0, is_ok); - srsran::rwlock_read_guard rw_lock(rwlock); + srsran::rwlock_read_guard rw_lock(rwmutex); if (ue_db.contains(rnti)) { ue_db[rnti]->metrics_tx(is_ok, 0 /*TODO get size of packet from scheduler somehow*/); } @@ -367,7 +367,7 @@ bool mac_nr::handle_uci_data(const uint16_t rnti, const srsran_uci_cfg_nr_t& cfg } // Process CQI - srsran::rwlock_read_guard rw_lock(rwlock); + srsran::rwlock_read_guard rw_lock(rwmutex); ue_db[rnti]->metrics_dl_cqi(cfg_, value.csi->wideband_cri_ri_pmi_cqi.cqi, value.valid); return true; @@ -394,7 +394,7 @@ int mac_nr::pusch_info(const srsran_slot_cfg_t& slot_cfg, mac_interface_phy_nr:: } auto process_pdu_task = [this, rnti](srsran::unique_byte_buffer_t& pdu) { - srsran::rwlock_read_guard lock(rwlock); + srsran::rwlock_read_guard lock(rwmutex); if (is_rnti_active_nolock(rnti)) { ue_db[rnti]->process_pdu(std::move(pdu)); } else { @@ -403,7 +403,7 @@ int mac_nr::pusch_info(const srsran_slot_cfg_t& slot_cfg, mac_interface_phy_nr:: }; stack_task_queue.try_push(std::bind(process_pdu_task, std::move(pusch_info.pdu))); } - srsran::rwlock_read_guard rw_lock(rwlock); + srsran::rwlock_read_guard rw_lock(rwmutex); if (ue_db.contains(rnti)) { ue_db[rnti]->metrics_rx(pusch_info.pusch_data.tb[0].crc, nof_bytes); } diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc index e0e072b09..a4908ba3f 100644 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ b/srsenb/src/stack/mac/nr/ue_nr.cc @@ -196,8 +196,7 @@ void ue_nr::metrics_read(mac_ue_metrics_t* metrics_) void ue_nr::metrics_dl_cqi(const srsran_uci_cfg_nr_t& cfg_, uint32_t dl_cqi, bool valid_cqi) { - // I think this is not necessary, as we locked from the calling function - // std::lock_guard lock(metrics_mutex); + std::lock_guard lock(metrics_mutex); // Process CQI for (uint32_t i = 0; i < cfg_.nof_csi; i++) { From 1a52cdcdaae01e38ffffc20356b331240ab8049f Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Mon, 11 Oct 2021 11:06:13 +0200 Subject: [PATCH 115/208] mac: remove unused rwlock and unused cqi counter Signed-off-by: Carlo Galiotto --- srsenb/hdr/stack/mac/nr/ue_nr.h | 1 - srsenb/src/stack/mac/nr/mac_nr.cc | 1 - srsenb/src/stack/mac/nr/ue_nr.cc | 13 +++++-------- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/ue_nr.h b/srsenb/hdr/stack/mac/nr/ue_nr.h index 5f53dc52b..9200c12b3 100644 --- a/srsenb/hdr/stack/mac/nr/ue_nr.h +++ b/srsenb/hdr/stack/mac/nr/ue_nr.h @@ -84,7 +84,6 @@ private: std::atomic active_state{true}; uint32_t phr_counter = 0; - uint32_t dl_cqi_counter = 0; uint32_t dl_cqi_valid_counter = 0; uint32_t dl_ri_counter = 0; uint32_t dl_pmi_counter = 0; diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 9ee998905..5860b5e75 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -367,7 +367,6 @@ bool mac_nr::handle_uci_data(const uint16_t rnti, const srsran_uci_cfg_nr_t& cfg } // Process CQI - srsran::rwlock_read_guard rw_lock(rwmutex); ue_db[rnti]->metrics_dl_cqi(cfg_, value.csi->wideband_cri_ri_pmi_cqi.cqi, value.valid); return true; diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc index a4908ba3f..98c3788d4 100644 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ b/srsenb/src/stack/mac/nr/ue_nr.cc @@ -188,10 +188,10 @@ void ue_nr::metrics_read(mac_ue_metrics_t* metrics_) auto it = std::find(cc_list.begin(), cc_list.end(), 0); ue_metrics.cc_idx = std::distance(cc_list.begin(), it); - *metrics_ = ue_metrics; - phr_counter = 0; - dl_cqi_counter = 0; - ue_metrics = {}; + *metrics_ = ue_metrics; + phr_counter = 0; + dl_cqi_valid_counter = 0; + ue_metrics = {}; } void ue_nr::metrics_dl_cqi(const srsran_uci_cfg_nr_t& cfg_, uint32_t dl_cqi, bool valid_cqi) @@ -200,9 +200,6 @@ void ue_nr::metrics_dl_cqi(const srsran_uci_cfg_nr_t& cfg_, uint32_t dl_cqi, boo // Process CQI for (uint32_t i = 0; i < cfg_.nof_csi; i++) { - // Increment CQI opportunity - dl_cqi_counter++; - // Skip if invalid or not supported CSI report if (not valid_cqi or cfg_.csi[i].cfg.quantity != SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI or cfg_.csi[i].cfg.freq_cfg != SRSRAN_CSI_REPORT_FREQ_WIDEBAND) { @@ -210,7 +207,7 @@ void ue_nr::metrics_dl_cqi(const srsran_uci_cfg_nr_t& cfg_, uint32_t dl_cqi, boo } // Add statistics - ue_metrics.dl_cqi = SRSRAN_VEC_SAFE_CMA(dl_cqi, ue_metrics.dl_cqi, dl_cqi_counter); + ue_metrics.dl_cqi = SRSRAN_VEC_SAFE_CMA(dl_cqi, ue_metrics.dl_cqi, dl_cqi_valid_counter); dl_cqi_valid_counter++; } } From a57ccdabf5f8c0614ac61dbc9e110bdfd922ebcf Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Mon, 11 Oct 2021 12:47:03 +0200 Subject: [PATCH 116/208] mac: move and check boolean from funcion to caller Signed-off-by: Carlo Galiotto --- srsenb/hdr/stack/mac/nr/ue_nr.h | 2 +- srsenb/src/stack/mac/nr/mac_nr.cc | 4 +++- srsenb/src/stack/mac/nr/ue_nr.cc | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/ue_nr.h b/srsenb/hdr/stack/mac/nr/ue_nr.h index 9200c12b3..b5d1cf6a2 100644 --- a/srsenb/hdr/stack/mac/nr/ue_nr.h +++ b/srsenb/hdr/stack/mac/nr/ue_nr.h @@ -59,7 +59,7 @@ public: void metrics_phr(float phr); void metrics_dl_ri(uint32_t dl_cqi); void metrics_dl_pmi(uint32_t dl_cqi); - void metrics_dl_cqi(const srsran_uci_cfg_nr_t& cfg_, uint32_t dl_cqi, bool valid_cqi); + void metrics_dl_cqi(const srsran_uci_cfg_nr_t& cfg_, uint32_t dl_cqi); void metrics_dl_mcs(uint32_t mcs); void metrics_ul_mcs(uint32_t mcs); void metrics_cnt(); diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 5860b5e75..b2a5cae66 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -367,7 +367,9 @@ bool mac_nr::handle_uci_data(const uint16_t rnti, const srsran_uci_cfg_nr_t& cfg } // Process CQI - ue_db[rnti]->metrics_dl_cqi(cfg_, value.csi->wideband_cri_ri_pmi_cqi.cqi, value.valid); + if (value.valid) { + ue_db[rnti]->metrics_dl_cqi(cfg_, value.csi->wideband_cri_ri_pmi_cqi.cqi); + } return true; } diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc index 98c3788d4..05c40c343 100644 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ b/srsenb/src/stack/mac/nr/ue_nr.cc @@ -194,14 +194,14 @@ void ue_nr::metrics_read(mac_ue_metrics_t* metrics_) ue_metrics = {}; } -void ue_nr::metrics_dl_cqi(const srsran_uci_cfg_nr_t& cfg_, uint32_t dl_cqi, bool valid_cqi) +void ue_nr::metrics_dl_cqi(const srsran_uci_cfg_nr_t& cfg_, uint32_t dl_cqi) { std::lock_guard lock(metrics_mutex); // Process CQI for (uint32_t i = 0; i < cfg_.nof_csi; i++) { // Skip if invalid or not supported CSI report - if (not valid_cqi or cfg_.csi[i].cfg.quantity != SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI or + if (cfg_.csi[i].cfg.quantity != SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI or cfg_.csi[i].cfg.freq_cfg != SRSRAN_CSI_REPORT_FREQ_WIDEBAND) { continue; } From 919d94979087e6e8e82941eada93559ad16d803a Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Mon, 11 Oct 2021 19:01:01 +0200 Subject: [PATCH 117/208] mac: fix rebase errors Signed-off-by: Carlo Galiotto --- srsenb/src/stack/mac/nr/mac_nr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index b2a5cae66..b639c904f 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -87,7 +87,7 @@ void mac_nr::get_metrics(srsenb::mac_metrics_t& metrics) void mac_nr::get_metrics_nolock(srsenb::mac_metrics_t& metrics) { - srsran::rwlock_read_guard lock(rwlock); + srsran::rwlock_read_guard lock(rwmutex); metrics.ues.reserve(ue_db.size()); for (auto& u : ue_db) { metrics.ues.emplace_back(); From 04d48127bbe6c91c32ab1a836d99ea270e7ffcb7 Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 13 Oct 2021 10:11:05 +0100 Subject: [PATCH 118/208] nr,sched: enable NR fixed mcs configuration via enb.conf --- srsenb/enb.conf.example | 4 ++++ srsenb/hdr/stack/mac/nr/sched_nr_cfg.h | 2 ++ srsenb/hdr/stack/mac/nr/sched_nr_interface.h | 6 +++--- srsenb/src/main.cc | 2 ++ srsenb/src/stack/mac/nr/mac_nr.cc | 12 +++++++++--- srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc | 10 +++++----- srsenb/test/mac/nr/sched_nr_cfg_generators.h | 8 -------- srsenb/test/mac/nr/sched_nr_test.cc | 4 ---- test/phy/dummy_gnb_stack.h | 9 ++------- 9 files changed, 27 insertions(+), 30 deletions(-) diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index bbc402425..b86c2c7b3 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -186,6 +186,8 @@ enable = false # init_dl_cqi: DL CQI value used before any CQI report is available to the eNB # max_sib_coderate: Upper bound on SIB and RAR grants coderate # pdcch_cqi_offset: CQI offset in derivation of PDCCH aggregation level +# pdsch_mcs: Optional fixed NR PDSCH MCS (ignores reported CQIs if specified) +# pusch_mcs: Optional fixed NR PUSCH MCS (ignores reported CQIs if specified) # ##################################################################### [scheduler] @@ -213,6 +215,8 @@ enable = false #init_dl_cqi=5 #max_sib_coderate=0.3 #pdcch_cqi_offset=0 +#nr_pdsch_mcs=28 +#nr_pusch_mcs=28 ##################################################################### # eMBMS configuration options diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h b/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h index a2a7f38ef..f905dcb99 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h @@ -138,6 +138,8 @@ public: } return phy().harq_ack.dl_data_to_ul_ack[pdsch_slot.to_uint() % phy().harq_ack.nof_dl_data_to_ul_ack]; } + int fixed_pdsch_mcs() const { return bwp_cfg->sched_cfg.fixed_dl_mcs; } + int fixed_pusch_mcs() const { return bwp_cfg->sched_cfg.fixed_ul_mcs; } private: uint16_t rnti = SRSRAN_INVALID_RNTI; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index 6a075e834..d804a2d43 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -71,6 +71,8 @@ public: bool pdsch_enabled = true; bool pusch_enabled = true; bool auto_refill_buffer = false; + int fixed_dl_mcs = -1; + int fixed_ul_mcs = -1; std::string logger_name = "MAC-NR"; }; @@ -80,9 +82,7 @@ public: }; struct ue_cfg_t { - uint32_t maxharq_tx = 4; - int fixed_dl_mcs = -1; - int fixed_ul_mcs = -1; + uint32_t maxharq_tx = 4; srsran::bounded_vector carriers; std::array ue_bearers = {}; srsran::phy_cfg_nr_t phy_cfg = {}; diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 82dba6db6..f95349ebf 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -253,6 +253,8 @@ void parse_args(all_args_t* args, int argc, char* argv[]) // NR section ("scheduler.tb_len", bpo::value(&args->stack.mac.nr_tb_size)->default_value(1520), "Default TB size") + ("scheduler.nr_pdsch_mcs", bpo::value(&args->nr_stack.mac.sched_cfg.fixed_dl_mcs)->default_value(28), "Fixed NR DL MCS (-1 for dynamic)") + ("scheduler.nr_pusch_mcs", bpo::value(&args->nr_stack.mac.sched_cfg.fixed_ul_mcs)->default_value(28), "Fixed NR UL MCS (-1 for dynamic)") // VNF params ("vnf.type", bpo::value(&args->phy.vnf_args.type)->default_value("gnb"), "VNF instance type [gnb,ue]") diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index b639c904f..6d5411286 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -11,9 +11,9 @@ */ #include "srsenb/hdr/stack/mac/nr/mac_nr.h" -#include "srsenb/test/mac/nr/sched_nr_cfg_generators.h" #include "srsran/common/buffer_pool.h" #include "srsran/common/log_helper.h" +#include "srsran/common/phy_cfg_nr_default.h" #include "srsran/common/rwlock_guard.h" #include "srsran/common/standard_streams.h" #include "srsran/common/string_helpers.h" @@ -144,8 +144,14 @@ uint16_t mac_nr::reserve_rnti(uint32_t enb_cc_idx) } // Add new user to the scheduler so that it can RX/TX SRB0 - srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_rach_ue_cfg(enb_cc_idx); - sched.ue_cfg(rnti, ue_cfg); + srsenb::sched_nr_interface::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; + uecfg.phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}}; + uecfg.phy_cfg.csi = {}; // disable CSI until RA is complete + sched.ue_cfg(rnti, uecfg); return rnti; } diff --git a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc index c64fdc51a..768ffb82a 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc @@ -232,8 +232,8 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr // Allocate HARQ if (ue.h_dl->empty()) { - srsran_assert(ue.cfg->ue_cfg()->fixed_dl_mcs >= 0, "Dynamic MCS not yet supported"); - int mcs = ue.cfg->ue_cfg()->fixed_dl_mcs; + int mcs = ue.cfg->fixed_pdsch_mcs(); + srsran_assert(mcs >= 0, "Dynamic MCS not yet supported"); int tbs = 100; bool ret = ue.h_dl->new_tx(ue.pdsch_slot, ue.uci_slot, dl_grant, mcs, tbs, 4); srsran_assert(ret, "Failed to allocate DL HARQ"); @@ -244,7 +244,7 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr // Allocation Successful - int mcs = ue.cfg->ue_cfg()->fixed_dl_mcs; + int mcs = ue.h_dl->mcs(); const static float max_R = 0.93; do { // Generate PDCCH @@ -320,8 +320,8 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_pr } if (ue.h_ul->empty()) { - srsran_assert(ue.cfg->ue_cfg()->fixed_ul_mcs >= 0, "Dynamic MCS not yet supported"); - int mcs = ue.cfg->ue_cfg()->fixed_ul_mcs; + int mcs = ue.cfg->fixed_pusch_mcs(); + srsran_assert(mcs >= 0, "Dynamic MCS not yet supported"); int tbs = 100; bool success = ue.h_ul->new_tx(ue.pusch_slot, ue.pusch_slot, ul_prbs, mcs, tbs, ue.cfg->ue_cfg()->maxharq_tx); srsran_assert(success, "Failed to allocate UL HARQ"); diff --git a/srsenb/test/mac/nr/sched_nr_cfg_generators.h b/srsenb/test/mac/nr/sched_nr_cfg_generators.h index 2744b40ce..93e927612 100644 --- a/srsenb/test/mac/nr/sched_nr_cfg_generators.h +++ b/srsenb/test/mac/nr/sched_nr_cfg_generators.h @@ -94,10 +94,6 @@ inline sched_nr_interface::ue_cfg_t get_rach_ue_cfg(uint32_t cc) uecfg.phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}}; uecfg.phy_cfg.csi = {}; - // Note: dynamic MCS not yet supported - uecfg.fixed_dl_mcs = 28; - uecfg.fixed_ul_mcs = 28; - return uecfg; } @@ -114,10 +110,6 @@ inline sched_nr_interface::ue_cfg_t get_default_ue_cfg( uecfg.phy_cfg = phy_cfg; uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; - // Note: dynamic MCS not yet supported - uecfg.fixed_dl_mcs = 28; - uecfg.fixed_ul_mcs = 28; - return uecfg; } diff --git a/srsenb/test/mac/nr/sched_nr_test.cc b/srsenb/test/mac/nr/sched_nr_test.cc index 349069359..035413727 100644 --- a/srsenb/test/mac/nr/sched_nr_test.cc +++ b/srsenb/test/mac/nr/sched_nr_test.cc @@ -89,8 +89,6 @@ void sched_nr_cfg_serialized_test() sched_nr_sim_base sched_tester(cfg, cells_cfg, "Serialized Test"); sched_nr_interface::ue_cfg_t uecfg = get_default_ue_cfg(nof_sectors); - uecfg.fixed_dl_mcs = 15; - uecfg.fixed_ul_mcs = 15; sched_tester.add_user(0x46, uecfg, slot_point{0, 0}, 0); std::vector count_per_cc(nof_sectors, 0); @@ -140,8 +138,6 @@ void sched_nr_cfg_parallel_cc_test() sched_nr_sim_base sched_tester(cfg, cells_cfg, "Parallel CC Test"); sched_nr_interface::ue_cfg_t uecfg = get_default_ue_cfg(cells_cfg.size()); - uecfg.fixed_dl_mcs = 15; - uecfg.fixed_ul_mcs = 15; sched_tester.add_user(0x46, uecfg, slot_point{0, 0}, 0); std::array, SRSRAN_MAX_CARRIERS> nano_count{}; diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index b9b699db9..4f70c6269 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -366,6 +366,8 @@ public: srsenb::mac_nr_args_t mac_args{}; mac_args.sched_cfg.pdsch_enabled = args.pdsch.slots != "" and args.pdsch.slots != "none"; mac_args.sched_cfg.pusch_enabled = args.pusch.slots != "" and args.pusch.slots != "none"; + mac_args.sched_cfg.fixed_dl_mcs = args.pdsch.mcs; + mac_args.sched_cfg.fixed_ul_mcs = args.pusch.mcs; mac->init(mac_args, nullptr, nullptr, &rlc_obj, &rrc_obj); std::vector cells_cfg = srsenb::get_default_cells_cfg(1, phy_cfg); mac->cell_cfg(cells_cfg); @@ -375,8 +377,6 @@ public: mac->reserve_rnti(0); srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1, phy_cfg); - ue_cfg.fixed_dl_mcs = args.pdsch.mcs; - ue_cfg.fixed_ul_mcs = args.pusch.mcs; ue_cfg.ue_bearers[4].direction = srsenb::mac_lc_ch_cfg_t::BOTH; mac->ue_cfg(args.rnti, ue_cfg); } @@ -698,11 +698,6 @@ public: if (not use_dummy_mac) { mac->rach_detected(rach_info); task_sched.run_pending_tasks(); - - srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1, phy_cfg); - ue_cfg.fixed_dl_mcs = ue_cfg.fixed_dl_mcs; - ue_cfg.fixed_ul_mcs = ue_cfg.fixed_ul_mcs; - mac->ue_cfg(rnti, ue_cfg); } std::unique_lock lock(metrics_mutex); From 25eb44914ed75fdc57c6fa72b8f715e900e665af Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 13 Oct 2021 10:17:51 +0100 Subject: [PATCH 119/208] nr,sched: fix sched_args_t default values --- srsenb/enb.conf.example | 4 ++-- srsenb/hdr/stack/mac/nr/sched_nr_interface.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index b86c2c7b3..b7bf3dafa 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -186,8 +186,8 @@ enable = false # init_dl_cqi: DL CQI value used before any CQI report is available to the eNB # max_sib_coderate: Upper bound on SIB and RAR grants coderate # pdcch_cqi_offset: CQI offset in derivation of PDCCH aggregation level -# pdsch_mcs: Optional fixed NR PDSCH MCS (ignores reported CQIs if specified) -# pusch_mcs: Optional fixed NR PUSCH MCS (ignores reported CQIs if specified) +# nr_pdsch_mcs: Optional fixed NR PDSCH MCS (ignores reported CQIs if specified) +# nr_pusch_mcs: Optional fixed NR PUSCH MCS (ignores reported CQIs if specified) # ##################################################################### [scheduler] diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index d804a2d43..ed5938949 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -71,8 +71,8 @@ public: bool pdsch_enabled = true; bool pusch_enabled = true; bool auto_refill_buffer = false; - int fixed_dl_mcs = -1; - int fixed_ul_mcs = -1; + int fixed_dl_mcs = 28; + int fixed_ul_mcs = 28; std::string logger_name = "MAC-NR"; }; From 25f34502a7cb522f0eaeb75ee0864af08c3b6da6 Mon Sep 17 00:00:00 2001 From: Francisco Date: Mon, 11 Oct 2021 18:03:21 +0100 Subject: [PATCH 120/208] nr,gnb,rrc: restore the GTPU TEIDs back from NR RNTI to LTE RNTI when RRC reconfiguration fails --- srsenb/hdr/stack/rrc/rrc_endc.h | 7 +++++-- srsenb/src/stack/rrc/rrc_endc.cc | 12 +++++++++++- srsenb/src/stack/rrc/rrc_ue.cc | 4 ++++ srsenb/src/stack/upper/gtpu.cc | 6 ++++-- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_endc.h b/srsenb/hdr/stack/rrc/rrc_endc.h index 3cb993b16..3f82acb10 100644 --- a/srsenb/hdr/stack/rrc/rrc_endc.h +++ b/srsenb/hdr/stack/rrc/rrc_endc.h @@ -36,8 +36,9 @@ public: struct sgnb_add_req_ack_ev { sgnb_addition_ack_params_t params; }; - struct sgnb_add_req_reject_ev {}; + /// Called when Reconf fails + struct rrc_reest_rx_ev {}; /** * @brief Non-standard event sent from NR-RRC to EUTRA when UE has attached to NR cell @@ -98,6 +99,7 @@ private: // FSM transition handlers void handle_sgnb_add_req_ack(wait_sgnb_add_req_resp_st& s, const sgnb_add_req_ack_ev& ev); + void handle_rrc_reest(wait_add_complete_st& s, const rrc_reest_rx_ev& ev); protected: // states @@ -120,7 +122,8 @@ protected: row< wait_sgnb_add_req_resp_st, prepare_recfg_st, sgnb_add_req_ack_ev, &fsm::handle_sgnb_add_req_ack >, row< wait_sgnb_add_req_resp_st, endc_deactivated_st, sgnb_add_req_reject_ev >, row< prepare_recfg_st, wait_add_complete_st, rrc_recfg_sent_ev >, - row< wait_add_complete_st, endc_activated_st, sgnb_add_complete_ev > + row< wait_add_complete_st, endc_activated_st, sgnb_add_complete_ev >, + row< wait_add_complete_st, endc_deactivated_st, rrc_reest_rx_ev, &fsm::handle_rrc_reest > // +---------------------------+--------------------------+------------------------+------------------------------+-------------------------+ >; // clang-format on diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index 47d5f6991..cbdc5cefa 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -168,7 +168,7 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn .non_crit_ext_present = true; rrc_conn_recfg_v1510_ies_s& reconf_v1510 = conn_recfg->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext .non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext; - reconf_v1510.nr_cfg_r15_present = true; + reconf_v1510.nr_cfg_r15_present = true; reconf_v1510.nr_cfg_r15.set_setup(); reconf_v1510.nr_cfg_r15.setup().endc_release_and_add_r15 = false; @@ -319,4 +319,14 @@ bool rrc::ue::rrc_endc::is_endc_supported() return endc_supported; } +void rrc::ue::rrc_endc::handle_rrc_reest(wait_add_complete_st& s, const rrc_reest_rx_ev& ev) +{ + auto& sgnb_config = get_state()->sgnb_config; + + // Transition GTPU tunnel rnti back from NR RNTI to LTE RNTI, given that the reconfiguration failed + rrc_enb->gtpu->mod_bearer_rnti(sgnb_config.nr_rnti, rrc_ue->rnti); + + rrc_enb->bearer_manager.rem_user(sgnb_config.nr_rnti); +} + } // namespace srsenb diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index db516cefb..cc5648914 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -652,6 +652,10 @@ void rrc::ue::handle_rrc_con_reest_req(rrc_conn_reest_request_s* msg) srsran::console( "User 0x%x requesting RRC Reestablishment as 0x%x. Cause: %s\n", rnti, old_rnti, req_r8.reest_cause.to_string()); + if (endc_handler != nullptr) { + old_ue->endc_handler->trigger(rrc_endc::rrc_reest_rx_ev{}); + } + // Cancel Handover in Target eNB if on-going asn1::s1ap::cause_c cause; cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::interaction_with_other_proc; diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index 658a4933e..e221311e8 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -124,14 +124,16 @@ gtpu_tunnel_manager::add_tunnel(uint16_t rnti, uint32_t eps_bearer_id, uint32_t bool gtpu_tunnel_manager::update_rnti(uint16_t old_rnti, uint16_t new_rnti) { auto* old_rnti_ptr = find_rnti_tunnels(old_rnti); - if (old_rnti_ptr == nullptr or find_rnti_tunnels(new_rnti) != nullptr) { + auto* new_rnti_ptr = find_rnti_tunnels(new_rnti); + if (old_rnti_ptr == nullptr or (new_rnti_ptr != nullptr and not new_rnti_ptr->empty())) { + // The old rnti must exist and the new rnti TEID list must be empty logger.error("Modifying bearer rnti. Old rnti=0x%x, new rnti=0x%x", old_rnti, new_rnti); return false; } logger.info("Modifying bearer rnti. Old rnti: 0x%x, new rnti: 0x%x", old_rnti, new_rnti); // create new RNTI and update TEIDs of old rnti to reflect new rnti - if (not ue_teidin_db.insert(new_rnti, ue_bearer_tunnel_list())) { + if (new_rnti_ptr == nullptr and not ue_teidin_db.insert(new_rnti, ue_bearer_tunnel_list())) { logger.error("Failure to create new rnti=0x%x", new_rnti); return false; } From acd5b8c46a16526c297b788f333987477dd5da94 Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 13 Oct 2021 13:16:29 +0100 Subject: [PATCH 121/208] nr,gnb,rrc: correctly configure TDD for UE and scheduler --- srsenb/hdr/stack/rrc/rrc_nr.h | 3 --- srsenb/src/stack/rrc/nr/cell_asn1_config.cc | 14 +++++++++++++- srsenb/src/stack/rrc/rrc_nr.cc | 20 -------------------- 3 files changed, 13 insertions(+), 24 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 4d8466c86..5341bbbb9 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -172,9 +172,6 @@ public: int pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bwp_pusch_cfg_common( asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int - pack_recfg_with_sync_sp_cell_cfg_common_tdd_ul_dl_cfg_common(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_nr_radio_bearer_config(asn1::dyn_octstring& packed_nr_bearer_config); int add_drb(); diff --git a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc index ce0906ed1..0fd1fbd82 100644 --- a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc +++ b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc @@ -241,7 +241,7 @@ int fill_serv_cell_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, ser serv_common.n_timing_advance_offset_present = true; serv_common.n_timing_advance_offset = asn1::rrc_nr::serving_cell_cfg_common_s::n_timing_advance_offset_opts::n0; serv_common.n_timing_advance_offset_present = true; - serv_common.dmrs_type_a_position = asn1::rrc_nr::serving_cell_cfg_common_s::dmrs_type_a_position_opts::pos2; + serv_common.dmrs_type_a_position = asn1::rrc_nr::serving_cell_cfg_common_s::dmrs_type_a_position_opts::pos2; serv_common.pci_present = true; serv_common.pci = cell_cfg.phy_cell.carrier.pci; @@ -268,6 +268,18 @@ int fill_serv_cell_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, ser serv_common.ssb_subcarrier_spacing = subcarrier_spacing_opts::khz30; } + if (cfg.cell_list[cc].duplex_mode == SRSRAN_DUPLEX_MODE_TDD) { + // TDD UL-DL config + serv_common.tdd_ul_dl_cfg_common_present = true; + auto& tdd_config = serv_common.tdd_ul_dl_cfg_common; + tdd_config.ref_subcarrier_spacing = subcarrier_spacing_e::khz15; + tdd_config.pattern1.dl_ul_tx_periodicity = asn1::rrc_nr::tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms10; + tdd_config.pattern1.nrof_dl_slots = 6; + tdd_config.pattern1.nrof_dl_symbols = 0; + tdd_config.pattern1.nrof_ul_slots = 4; + tdd_config.pattern1.nrof_ul_symbols = 0; + } + return SRSRAN_SUCCESS; } diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 1ab477eef..f8ea9348d 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -1212,22 +1212,6 @@ int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common( return SRSRAN_SUCCESS; } -int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_tdd_ul_dl_cfg_common( - asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - // TDD UL-DL config - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.tdd_ul_dl_cfg_common_present = true; - auto& tdd_config = cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.tdd_ul_dl_cfg_common; - tdd_config.ref_subcarrier_spacing = subcarrier_spacing_e::khz15; - tdd_config.pattern1.dl_ul_tx_periodicity = asn1::rrc_nr::tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms10; - tdd_config.pattern1.nrof_dl_slots = 6; - tdd_config.pattern1.nrof_dl_symbols = 0; - tdd_config.pattern1.nrof_ul_slots = 4; - tdd_config.pattern1.nrof_ul_symbols = 0; - - return SRSRAN_SUCCESS; -} - int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) { auto& pscell_cfg = parent->cfg.cell_list.at(UE_PSCELL_CC_IDX); @@ -1242,10 +1226,6 @@ int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common(asn1::rrc_nr::cell_group // UL config pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common(cell_group_cfg_pack); - if (parent->cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_TDD) { - pack_recfg_with_sync_sp_cell_cfg_common_tdd_ul_dl_cfg_common(cell_group_cfg_pack); - } - return SRSRAN_SUCCESS; } From 964dce575b8265ae2d812f1908a6cc8a280a17d7 Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 13 Oct 2021 17:22:55 +0100 Subject: [PATCH 122/208] nr,sched: fix nof_harqs in NR scheduler to 8 --- srsenb/hdr/stack/mac/nr/sched_nr_interface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index ed5938949..c3a6f0551 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -28,7 +28,7 @@ const static size_t SCHED_NR_MAX_CARRIERS = 4; const static uint16_t SCHED_NR_INVALID_RNTI = 0; const static size_t SCHED_NR_MAX_NOF_RBGS = 18; const static size_t SCHED_NR_MAX_TB = 1; -const static size_t SCHED_NR_MAX_HARQ = 16; +const static size_t SCHED_NR_MAX_HARQ = SRSRAN_DEFAULT_HARQ_PROC_DL_NR; const static size_t SCHED_NR_MAX_BWP_PER_CELL = 2; const static size_t SCHED_NR_MAX_LCID = 32; const static size_t SCHED_NR_MAX_LC_GROUP = 7; From 1a64c6adad1b8e09ae7e6312a07db37b7a47f376 Mon Sep 17 00:00:00 2001 From: Alejandro Leal Conejos Date: Fri, 8 Oct 2021 12:10:01 +0200 Subject: [PATCH 123/208] Enum fixes so clang 12 can build the repo --- lib/include/srsran/common/interfaces_common.h | 13 ++++++------- lib/include/srsran/phy/channel/channel.h | 4 ++-- srsenb/hdr/stack/mac/mac.h | 4 ++-- srsepc/hdr/hss/hss.h | 8 ++++---- srsue/hdr/stack/upper/nas_config.h | 4 ++-- 5 files changed, 16 insertions(+), 17 deletions(-) diff --git a/lib/include/srsran/common/interfaces_common.h b/lib/include/srsran/common/interfaces_common.h index d2372a58d..2a80530ea 100644 --- a/lib/include/srsran/common/interfaces_common.h +++ b/lib/include/srsran/common/interfaces_common.h @@ -20,20 +20,20 @@ namespace srsran { -typedef struct { +struct phy_log_args_t { std::string phy_level = "none"; std::string phy_lib_level = "none"; std::string id_preamble = ""; int phy_hex_limit = -1; -} phy_log_args_t; +}; -typedef struct { +struct rf_args_band_t { float min; float max; -} rf_args_band_t; +}; // RF/radio args -typedef struct { +struct rf_args_t { std::string type; std::string log_level; double srate_hz; @@ -56,8 +56,7 @@ typedef struct { std::array ch_rx_bands; std::array ch_tx_bands; - -} rf_args_t; +}; struct vnf_args_t { std::string type; diff --git a/lib/include/srsran/phy/channel/channel.h b/lib/include/srsran/phy/channel/channel.h index 2b73789b8..66da73052 100644 --- a/lib/include/srsran/phy/channel/channel.h +++ b/lib/include/srsran/phy/channel/channel.h @@ -28,7 +28,7 @@ namespace srsran { class channel { public: - typedef struct { + struct args_t { // General bool enable = false; @@ -58,7 +58,7 @@ public: bool rlf_enable = false; uint32_t rlf_t_on_ms = 10000; uint32_t rlf_t_off_ms = 2000; - } args_t; + }; channel(const args_t& channel_args, uint32_t _nof_channels, srslog::basic_logger& logger); ~channel(); diff --git a/srsenb/hdr/stack/mac/mac.h b/srsenb/hdr/stack/mac/mac.h index cbb7e4af3..718c1cbd2 100644 --- a/srsenb/hdr/stack/mac/mac.h +++ b/srsenb/hdr/stack/mac/mac.h @@ -155,12 +155,12 @@ private: const static int NOF_BCCH_DLSCH_MSG = sched_interface::MAX_SIBS; const static int pcch_payload_buffer_len = 1024; - typedef struct { + struct common_buffers_t { uint8_t pcch_payload_buffer[pcch_payload_buffer_len] = {}; srsran_softbuffer_tx_t bcch_softbuffer_tx[NOF_BCCH_DLSCH_MSG] = {}; srsran_softbuffer_tx_t pcch_softbuffer_tx = {}; srsran_softbuffer_tx_t rar_softbuffer_tx = {}; - } common_buffers_t; + }; std::vector common_buffers; diff --git a/srsepc/hdr/hss/hss.h b/srsepc/hdr/hss/hss.h index 43e12d28e..46e635686 100644 --- a/srsepc/hdr/hss/hss.h +++ b/srsepc/hdr/hss/hss.h @@ -34,15 +34,15 @@ namespace srsepc { -typedef struct { +struct hss_args_t { std::string db_file; uint16_t mcc; uint16_t mnc; -} hss_args_t; +}; enum hss_auth_algo { HSS_ALGO_XOR, HSS_ALGO_MILENAGE }; -typedef struct { +struct hss_ue_ctx_t { // Members std::string name; uint64_t imsi; @@ -61,7 +61,7 @@ typedef struct { void set_sqn(const uint8_t* sqn_); void set_last_rand(const uint8_t* rand_); void get_last_rand(uint8_t* rand_); -} hss_ue_ctx_t; +}; class hss : public hss_interface_nas { diff --git a/srsue/hdr/stack/upper/nas_config.h b/srsue/hdr/stack/upper/nas_config.h index 4d6216956..2af8a2fe6 100644 --- a/srsue/hdr/stack/upper/nas_config.h +++ b/srsue/hdr/stack/upper/nas_config.h @@ -18,10 +18,10 @@ namespace srsue { -typedef struct { +struct nas_sim_args_t { int airplane_t_on_ms = -1; int airplane_t_off_ms = -1; -} nas_sim_args_t; +}; class nas_args_t { From 75af37bd4bfb2e398936cd5dcd60f3c9ce537707 Mon Sep 17 00:00:00 2001 From: faluco Date: Fri, 8 Oct 2021 10:42:02 +0200 Subject: [PATCH 124/208] Batch of race fixes when running the UE and ENB with UHD. Main fixes are in the UHD driver, fixing races and potential deadlocks. --- lib/src/phy/rf/rf_uhd_imp.cc | 20 ++++++++++++++------ srsenb/src/enb.cc | 8 ++++---- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/src/phy/rf/rf_uhd_imp.cc b/lib/src/phy/rf/rf_uhd_imp.cc index 3525174f8..96a6b9091 100644 --- a/lib/src/phy/rf/rf_uhd_imp.cc +++ b/lib/src/phy/rf/rf_uhd_imp.cc @@ -10,6 +10,7 @@ * */ +#include #include #include #include @@ -155,7 +156,7 @@ struct rf_uhd_handler_t { #if HAVE_ASYNC_THREAD // Asynchronous transmission message thread - bool async_thread_running = false; + std::atomic async_thread_running{false}; std::thread async_thread; std::mutex async_mutex; std::condition_variable async_cvar; @@ -226,9 +227,12 @@ static void log_late(rf_uhd_handler_t* h, bool is_rx) #if HAVE_ASYNC_THREAD static void log_underflow(rf_uhd_handler_t* h) { - // Flag underflow - if (h->tx_state == RF_UHD_IMP_TX_STATE_BURST) { - h->tx_state = RF_UHD_IMP_TX_STATE_END_OF_BURST; + { + std::lock_guard tx_lock(h->tx_mutex); + // Flag underflow + if (h->tx_state == RF_UHD_IMP_TX_STATE_BURST) { + h->tx_state = RF_UHD_IMP_TX_STATE_END_OF_BURST; + } } if (h->uhd_error_handler != nullptr) { srsran_rf_error_t error; @@ -289,6 +293,7 @@ static void* async_thread(void* h) } } else if (event_code == uhd::async_metadata_t::EVENT_CODE_BURST_ACK) { // Makes sure next block will be start of burst + std::lock_guard tx_lock(handler->tx_mutex); if (handler->tx_state == RF_UHD_IMP_TX_STATE_WAIT_EOB_ACK) { handler->tx_state = RF_UHD_IMP_TX_STATE_START_BURST; } @@ -1023,11 +1028,12 @@ double rf_uhd_set_rx_srate(void* h, double freq) double rf_uhd_set_tx_srate(void* h, double freq) { - rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h; - std::unique_lock lock(handler->tx_mutex); + rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h; + // Locking order should be kept the same with the async worker. #if HAVE_ASYNC_THREAD std::unique_lock lock_async(handler->async_mutex); #endif /* HAVE_ASYNC_THREAD */ + std::unique_lock lock(handler->tx_mutex); // Early return if the current rate matches and Tx stream has been created if (freq == handler->tx_rate and handler->uhd->is_tx_ready()) { @@ -1409,6 +1415,8 @@ int rf_uhd_send_timed_multi(void* h, // Flush receiver only if allowed if (RF_UHD_IMP_PROHIBITED_EOB_FLUSH.count(handler->devname) == 0) { + // Avoid holding the tx lock while in the rf_uhd_flush_buffer function to avoid potential deadlocks. + lock.unlock(); rf_uhd_flush_buffer(h); } diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index e11281191..7babf6a28 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -152,14 +152,14 @@ void enb::stop() { if (started) { // tear down in reverse order - if (radio) { - radio->stop(); - } - if (phy) { phy->stop(); } + if (radio) { + radio->stop(); + } + if (eutra_stack) { eutra_stack->stop(); } From 28bbaa7816fb620d4c7f2d269679c8b8fb2a899a Mon Sep 17 00:00:00 2001 From: faluco Date: Fri, 8 Oct 2021 10:52:35 +0200 Subject: [PATCH 125/208] Blacklist TSAN issues from libusb and libuhd. --- lib/include/srsran/common/tsan_options.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/include/srsran/common/tsan_options.h b/lib/include/srsran/common/tsan_options.h index bac732021..18e5bace0 100644 --- a/lib/include/srsran/common/tsan_options.h +++ b/lib/include/srsran/common/tsan_options.h @@ -41,6 +41,12 @@ const char* __tsan_default_suppressions() // External uninstrumented libraries "called_from_lib:libzmq.so\n" "called_from_lib:libpgm-5.2.so\n" + "called_from_lib:libusb*\n" + "called_from_lib:libuhd*\n" + // Races detected inside uninstrumented libraries. This may hide legit races if any of the libraries appear in the + // backtrace + "race:libusb*\n" + "race:libuhd*\n" // Lock order inversion issues in these functions, ignore it as it uses rw locks in read mode "deadlock:srsenb::mac::rlc_buffer_state\n" "deadlock:srsenb::mac::snr_info\n" From aa0c936f5010cb2f8bddaab91fd4b21c636a2a91 Mon Sep 17 00:00:00 2001 From: faluco Date: Fri, 8 Oct 2021 11:05:25 +0200 Subject: [PATCH 126/208] Fix race condition when destroying the gnb stack class. The gnb stack class could be destroyed concurrently while still running its task scheduler thread. --- srsenb/hdr/stack/gnb_stack_nr.h | 3 ++- srsenb/src/stack/gnb_stack_nr.cc | 21 +++++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/srsenb/hdr/stack/gnb_stack_nr.h b/srsenb/hdr/stack/gnb_stack_nr.h index 83fe9317f..2161b8ca9 100644 --- a/srsenb/hdr/stack/gnb_stack_nr.h +++ b/srsenb/hdr/stack/gnb_stack_nr.h @@ -106,6 +106,7 @@ public: private: void run_thread() final; void tti_clock_impl(); + void stop_impl(); // args gnb_stack_args_t args = {}; @@ -121,7 +122,7 @@ private: 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; + metrics_task_queue, gnb_task_queue; // metrics waiting condition std::mutex metrics_mutex; diff --git a/srsenb/src/stack/gnb_stack_nr.cc b/srsenb/src/stack/gnb_stack_nr.cc index 417f936a9..da21498fd 100644 --- a/srsenb/src/stack/gnb_stack_nr.cc +++ b/srsenb/src/stack/gnb_stack_nr.cc @@ -35,6 +35,7 @@ gnb_stack_nr::gnb_stack_nr(srslog::sink& log_sink) : 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(); } gnb_stack_nr::~gnb_stack_nr() @@ -97,15 +98,23 @@ int gnb_stack_nr::init(const gnb_stack_args_t& args_, void gnb_stack_nr::stop() { if (running) { - rrc.stop(); - pdcp.stop(); - mac.stop(); - - srsran::get_background_workers().stop(); - running = false; + gnb_task_queue.push([this]() { stop_impl(); }); + wait_thread_finish(); } } +void gnb_stack_nr::stop_impl() +{ + rrc.stop(); + pdcp.stop(); + mac.stop(); + + task_sched.stop(); + srsran::get_background_workers().stop(); + + running = false; +} + bool gnb_stack_nr::switch_on() { // Nothing to be done here From 1bffebe0bfc7954081e8ef83f9e4ebbc79f521b4 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 7 Oct 2021 16:59:00 +0200 Subject: [PATCH 127/208] Removed cached PRACH signals --- srsue/hdr/phy/prach.h | 40 ++++++++++++++-------------------------- srsue/src/phy/prach.cc | 33 +++------------------------------ 2 files changed, 17 insertions(+), 56 deletions(-) diff --git a/srsue/hdr/phy/prach.h b/srsue/hdr/phy/prach.h index cfe9a272d..f858f3266 100644 --- a/srsue/hdr/phy/prach.h +++ b/srsue/hdr/phy/prach.h @@ -41,37 +41,25 @@ public: private: bool generate_buffer(uint32_t f_idx); - bool is_buffer_generated(uint32_t f_idx, uint32_t preamble_index) const - { - return buffer_bitmask.test(f_idx * 64 + preamble_index); - } - - void set_buffer_as_generated(uint32_t f_idx, uint32_t preamble_index) - { - buffer_bitmask.set(f_idx * 64 + preamble_index); - } - private: static constexpr unsigned MAX_LEN_SF = 3; static constexpr unsigned max_fs = 12; static constexpr unsigned max_preambles = 64; - srslog::basic_logger& logger; - srsran_prach_t prach_obj = {}; - srsran_cell_t cell = {}; - srsran_cfo_t cfo_h = {}; - srsran_prach_cfg_t cfg = {}; - std::array, max_fs> buffer = {}; - cf_t* signal_buffer = nullptr; - int preamble_idx = -1; - uint32_t len = 0; - int allowed_subframe = 0; - int transmitted_tti = 0; - float target_power_dbm = 0; - bool mem_initiated = false; - bool cell_initiated = false; - std::bitset buffer_bitmask; - mutable std::mutex mutex; + srslog::basic_logger& logger; + srsran_prach_t prach_obj = {}; + srsran_cell_t cell = {}; + srsran_cfo_t cfo_h = {}; + srsran_prach_cfg_t cfg = {}; + cf_t* signal_buffer = nullptr; + int preamble_idx = -1; + uint32_t len = 0; + int allowed_subframe = 0; + int transmitted_tti = 0; + float target_power_dbm = 0; + bool mem_initiated = false; + bool cell_initiated = false; + mutable std::mutex mutex; }; } // namespace srsue diff --git a/srsue/src/phy/prach.cc b/srsue/src/phy/prach.cc index f227ddf12..8425f7e34 100644 --- a/srsue/src/phy/prach.cc +++ b/srsue/src/phy/prach.cc @@ -33,15 +33,6 @@ using namespace srsue; void prach::init(uint32_t max_prb) { std::lock_guard lock(mutex); - for (auto& i : buffer) { - for (auto& j : i) { - j = srsran_vec_cf_malloc(SRSRAN_PRACH_MAX_LEN); - if (!j) { - perror("malloc"); - return; - } - } - } if (srsran_cfo_init(&cfo_h, SRSRAN_PRACH_MAX_LEN)) { ERROR("PRACH: Error initiating CFO"); @@ -50,7 +41,7 @@ void prach::init(uint32_t max_prb) srsran_cfo_set_tol(&cfo_h, 0); - signal_buffer = srsran_vec_cf_malloc(MAX_LEN_SF * 30720U); + signal_buffer = srsran_vec_cf_malloc(SRSRAN_MAX(MAX_LEN_SF * 30720U, SRSRAN_PRACH_MAX_LEN)); if (!signal_buffer) { perror("malloc"); return; @@ -71,12 +62,6 @@ void prach::stop() return; } - for (auto& i : buffer) { - for (auto& j : i) { - free(j); - } - } - free(signal_buffer); srsran_cfo_free(&cfo_h); srsran_prach_free(&prach_obj); @@ -118,7 +103,6 @@ bool prach::set_cell(srsran_cell_t cell_, srsran_prach_cfg_t prach_cfg) return false; } - buffer_bitmask.reset(); len = prach_obj.N_seq + prach_obj.N_cp; transmitted_tti = -1; cell_initiated = true; @@ -130,22 +114,16 @@ bool prach::set_cell(srsran_cell_t cell_, srsran_prach_cfg_t prach_cfg) bool prach::generate_buffer(uint32_t f_idx) { - if (is_buffer_generated(f_idx, preamble_idx)) { - return true; - } - uint32_t freq_offset = cfg.freq_offset; if (cell.frame_type == SRSRAN_TDD) { freq_offset = srsran_prach_f_ra_tdd( cfg.config_idx, cfg.tdd_config.sf_config, (f_idx / 6) * 10, f_idx % 6, cfg.freq_offset, cell.nof_prb); } - if (srsran_prach_gen(&prach_obj, preamble_idx, freq_offset, buffer[f_idx][preamble_idx])) { + if (srsran_prach_gen(&prach_obj, preamble_idx, freq_offset, signal_buffer)) { Error("Generating PRACH preamble %d", preamble_idx); return false; } - set_buffer_as_generated(f_idx, preamble_idx); - return true; } @@ -239,13 +217,8 @@ cf_t* prach::generate(float cfo, uint32_t* nof_sf, float* target_power) return nullptr; } - if (!is_buffer_generated(f_idx, preamble_idx)) { - Error("PRACH Buffer not generated: f_idx=%d preamble_idx=%d", f_idx, preamble_idx); - return nullptr; - } - // Correct CFO before transmission - srsran_cfo_correct(&cfo_h, buffer[f_idx][preamble_idx], signal_buffer, cfo / srsran_symbol_sz(cell.nof_prb)); + srsran_cfo_correct(&cfo_h, signal_buffer, signal_buffer, cfo / srsran_symbol_sz(cell.nof_prb)); // pad guard symbols with zeros uint32_t nsf = SRSRAN_CEIL(len, SRSRAN_SF_LEN_PRB(cell.nof_prb)); From 7cbd3d50b7c72ade95e0ce35be6a6e88b1ad1e6a Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 13 Oct 2021 17:52:33 +0200 Subject: [PATCH 128/208] mac_sch_pdu_nr,bsr: fix length check for BSR fix nasty bug where the length calucation for the LCID was taking the bsr_format_nr_t that was having the same name. --- lib/src/mac/mac_sch_pdu_nr.cc | 6 ++++-- srsue/src/stack/mac_nr/proc_bsr_nr.cc | 9 ++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/src/mac/mac_sch_pdu_nr.cc b/lib/src/mac/mac_sch_pdu_nr.cc index 268e8ebd8..f87289230 100644 --- a/lib/src/mac/mac_sch_pdu_nr.cc +++ b/lib/src/mac/mac_sch_pdu_nr.cc @@ -254,12 +254,14 @@ uint32_t mac_sch_subpdu_nr::sizeof_ce(uint32_t lcid, bool is_ul) return 8; case CRNTI: return 2; - case SHORT_TRUNC_BSR: - return 1; case SHORT_BSR: + case SHORT_TRUNC_BSR: return 1; case SE_PHR: return 2; + case LONG_BSR: + case LONG_TRUNC_BSR: + return 1; // minimum size, could be more than that case PADDING: return 0; } diff --git a/srsue/src/stack/mac_nr/proc_bsr_nr.cc b/srsue/src/stack/mac_nr/proc_bsr_nr.cc index 391264be7..b292476a9 100644 --- a/srsue/src/stack/mac_nr/proc_bsr_nr.cc +++ b/srsue/src/stack/mac_nr/proc_bsr_nr.cc @@ -219,11 +219,14 @@ void proc_bsr_nr::set_padding_bytes(uint32_t nof_bytes) const uint32_t LBSR_CE_SUBHEADER_LEN = 1; // if the number of padding bits is equal to or larger than the size of the Short BSR plus its subheader but smaller // than the size of the Long BSR plus its subheader - if (nof_bytes >= SBSR_CE_SUBHEADER_LEN + srsran::mac_sch_subpdu_nr::sizeof_ce(SHORT_BSR, true) && - nof_bytes < LBSR_CE_SUBHEADER_LEN + srsran::mac_sch_subpdu_nr::sizeof_ce(LONG_BSR, true)) { + if (nof_bytes >= (SBSR_CE_SUBHEADER_LEN + + srsran::mac_sch_subpdu_nr::sizeof_ce(srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::SHORT_BSR, true)) && + nof_bytes < (LBSR_CE_SUBHEADER_LEN + + srsran::mac_sch_subpdu_nr::sizeof_ce(srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::LONG_BSR, true))) { // generate short padding BSR mux->generate_bsr_mac_ce(SHORT_BSR); - } else if (nof_bytes >= LBSR_CE_SUBHEADER_LEN + srsran::mac_sch_subpdu_nr::sizeof_ce(LONG_BSR, true)) { + } else if (nof_bytes >= (LBSR_CE_SUBHEADER_LEN + srsran::mac_sch_subpdu_nr::sizeof_ce( + srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::LONG_BSR, true))) { // report Long BSR if more than one LCG has data to send mux->generate_bsr_mac_ce(LONG_BSR); } From fed53c91d0227c82cc73bad8e39cca5619b5f8d3 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 13 Oct 2021 17:53:59 +0200 Subject: [PATCH 129/208] mac_nr_test: add TC to reproduce #3325 extend the rlc_dummy to allow providing different RLC PDUs. add TC for issue #3325 but leave the original TV because it is very large. --- srsue/src/stack/mac_nr/test/mac_nr_test.cc | 98 +++++++++++++++++++++- 1 file changed, 94 insertions(+), 4 deletions(-) diff --git a/srsue/src/stack/mac_nr/test/mac_nr_test.cc b/srsue/src/stack/mac_nr/test/mac_nr_test.cc index 35baa845f..f6bbc28ba 100644 --- a/srsue/src/stack/mac_nr/test/mac_nr_test.cc +++ b/srsue/src/stack/mac_nr/test/mac_nr_test.cc @@ -101,8 +101,12 @@ public: return 0; } - if (read_len > 0 && read_len < (int32_t)nof_bytes) { - nof_bytes = read_len; + if (read_len.size() >= read_len_idx) { + int32_t tmp_read_len = read_len.at(read_len_idx); + if (read_len.at(read_len_idx) > 0 && tmp_read_len < (int32_t)nof_bytes) { + nof_bytes = tmp_read_len; + } + read_len_idx = (read_len_idx + 1) % read_len.size(); } uint32_t len = SRSRAN_MIN(ul_queues[lcid], nof_bytes); @@ -127,7 +131,7 @@ public: uint32_t get_received_pdus() { return received_pdus; } void disable_read() { read_enable = false; } - void set_read_len(uint32_t len) { read_len = len; } + void set_read_len(const std::vector& read_len_) { read_len = read_len_; } void set_read_min(uint32_t len) { read_min = len; } void reset_queues() { @@ -138,7 +142,8 @@ public: private: bool read_enable = true; - int32_t read_len = -1; // read all + std::vector read_len = {-1}; // read all + uint32_t read_len_idx = 0; uint32_t read_min = 0; // minimum "grant size" for read_pdu() to return data uint32_t received_bytes = 0; uint32_t received_pdus = 0; @@ -425,6 +430,90 @@ int mac_nr_ul_logical_channel_prioritization_test2() return SRSRAN_SUCCESS; } +// Correct packing of MAC PDU with multiple subHeader with 16bit L field +int mac_nr_ul_logical_channel_prioritization_test3() +{ + // PDU layout (4737 B in total) + // TV skipped because it is very big + + // dummy layers + dummy_phy phy; + rlc_dummy rlc; + rrc_dummy rrc; + stack_dummy stack; + + // the actual MAC + mac_nr mac(&stack.task_sched); + + const uint16_t crnti = 0x1001; + mac_nr_args_t args = {}; + mac.init(args, &phy, &rlc, &rrc); + mac.set_crnti(crnti); + + stack.init(&mac, &phy); + + // generate config (default DRB2 config for EN-DC) + std::vector lcids; + srsran::logical_channel_config_t config = {}; + config.lcid = 4; + config.lcg = 6; + config.PBR = 0; + config.BSD = 1000; // 1000ms + config.priority = 11; + lcids.push_back(config); + + // setup LCIDs in MAC + for (auto& channel : lcids) { + mac.setup_lcid(channel); + } + + // write muliple SDUs to DRB2 + const uint32_t sdu_len = 1502; + for (uint32_t i = 0; i < 10; ++i) { + rlc.write_sdu(4, sdu_len); + } + std::vector read_len; + read_len.push_back(80); + read_len.push_back(1480); + read_len.push_back(1480); + read_len.push_back(1480); + read_len.push_back(203); + rlc.set_read_len(read_len); + + // run TTI to setup Bj, BSR should be generated + stack.run_tti(0); + usleep(100); + + // create UL action and grant and read MAC PDU + { + mac_interface_phy_nr::tb_action_ul_t ul_action = {}; + mac_interface_phy_nr::mac_nr_grant_ul_t mac_grant = {}; + + mac_grant.rnti = crnti; // make sure MAC picks it up as valid UL grant + mac_grant.pid = 0; + mac_grant.tti = 0; + mac_grant.tbs = 4737; + int cc_idx = 0; + + // Send grant to MAC and get action for this TB, 0x + mac.new_grant_ul(cc_idx, mac_grant, &ul_action); + + // print generated PDU + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload->msg, mac_grant.tbs, "Generated PDU (%d B)", mac_grant.tbs); +#if HAVE_PCAP + pcap_handle->write_ul_crnti_nr( + ul_action.tb.payload->msg, mac_grant.tbs, mac_grant.rnti, UE_ID, mac_grant.pid, mac_grant.tti); +#endif + } + + // make sure MAC PDU thread picks up before stopping + stack.run_tti(0); + mac.stop(); + + return SRSRAN_SUCCESS; +} + // Basic test for periodic BSR transmission int mac_nr_ul_periodic_bsr_test() { @@ -710,6 +799,7 @@ int main() TESTASSERT(msg3_test() == SRSRAN_SUCCESS); TESTASSERT(mac_nr_ul_logical_channel_prioritization_test1() == SRSRAN_SUCCESS); TESTASSERT(mac_nr_ul_logical_channel_prioritization_test2() == SRSRAN_SUCCESS); + TESTASSERT(mac_nr_ul_logical_channel_prioritization_test3() == SRSRAN_SUCCESS); TESTASSERT(mac_nr_ul_periodic_bsr_test() == SRSRAN_SUCCESS); TESTASSERT(mac_nr_dl_retx_test() == SRSRAN_SUCCESS); From 64ffd81cf9b2f987b74fa80b092e59e52029c1d1 Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 13 Oct 2021 17:39:02 +0100 Subject: [PATCH 130/208] nr,sched: fix recomputation of ue_bwp_cfg when sched receives new ue_cfg objects --- srsenb/hdr/stack/mac/nr/sched_nr_cfg.h | 16 +++++++++++---- srsenb/hdr/stack/mac/nr/sched_nr_ue.h | 3 ++- srsenb/src/stack/mac/nr/sched_nr_pdcch.cc | 6 +++--- srsenb/src/stack/mac/nr/sched_nr_ue.cc | 25 ++++++++++++----------- 4 files changed, 30 insertions(+), 20 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h b/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h index f905dcb99..eba8a0631 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h @@ -124,10 +124,18 @@ public: bwp_ue_cfg() = default; explicit bwp_ue_cfg(uint16_t rnti, const bwp_params_t& bwp_cfg, const ue_cfg_t& uecfg_); - const ue_cfg_t* ue_cfg() const { return cfg_; } - const srsran::phy_cfg_nr_t& phy() const { return cfg_->phy_cfg; } - const bwp_params_t& active_bwp() const { return *bwp_cfg; } - const bwp_cce_pos_list& cce_pos_list(uint32_t search_id) const + const ue_cfg_t* ue_cfg() const { return cfg_; } + const srsran::phy_cfg_nr_t& phy() const { return cfg_->phy_cfg; } + const bwp_params_t& active_bwp() const { return *bwp_cfg; } + srsran::const_span cce_pos_list(uint32_t search_id, uint32_t slot_idx, uint32_t aggr_idx) const + { + if (cce_positions_list.size() > ss_id_to_cce_idx[search_id]) { + auto& lst = cce_pos_list(search_id); + return lst[slot_idx][aggr_idx]; + } + return srsran::const_span{}; + } + const bwp_cce_pos_list& cce_pos_list(uint32_t search_id) const { return cce_positions_list[ss_id_to_cce_idx[search_id]]; } diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h index 4104e786b..666eff1dd 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h @@ -63,7 +63,8 @@ class ue_carrier { public: ue_carrier(uint16_t rnti, const ue_cfg_t& cfg, const cell_params_t& cell_params_); - slot_ue try_reserve(slot_point pdcch_slot, const ue_cfg_t& uecfg_, uint32_t dl_harq_bytes, uint32_t ul_harq_bytes); + void set_cfg(const ue_cfg_t& ue_cfg); + slot_ue try_reserve(slot_point pdcch_slot, uint32_t dl_harq_bytes, uint32_t ul_harq_bytes); const uint16_t rnti; const uint32_t cc; diff --git a/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc b/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc index c478f05b3..2d54546d0 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc @@ -179,9 +179,9 @@ srsran::span coreset_region::get_cce_loc_table(const alloc_recor { switch (record.alloc_type) { case pdcch_grant_type_t::dl_data: - return record.ue->cfg->cce_pos_list(record.ss_id)[slot_idx][record.aggr_idx]; + return record.ue->cfg->cce_pos_list(record.ss_id, slot_idx, record.aggr_idx); case pdcch_grant_type_t::ul_data: - return record.ue->cfg->cce_pos_list(record.ss_id)[slot_idx][record.aggr_idx]; + return record.ue->cfg->cce_pos_list(record.ss_id, slot_idx, record.aggr_idx); case pdcch_grant_type_t::rar: return rar_cce_list[slot_idx][record.aggr_idx]; default: @@ -191,4 +191,4 @@ srsran::span coreset_region::get_cce_loc_table(const alloc_recor } } // namespace sched_nr_impl -} // namespace srsenb \ No newline at end of file +} // namespace srsenb diff --git a/srsenb/src/stack/mac/nr/sched_nr_ue.cc b/srsenb/src/stack/mac/nr/sched_nr_ue.cc index 011591756..ed0349a0d 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_ue.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_ue.cc @@ -29,17 +29,14 @@ ue_carrier::ue_carrier(uint16_t rnti_, const ue_cfg_t& uecfg_, const cell_params harq_ent(cell_params_.nof_prb()) {} -slot_ue ue_carrier::try_reserve(slot_point pdcch_slot, - const ue_cfg_t& uecfg_, - uint32_t dl_pending_bytes, - uint32_t ul_pending_bytes) +void ue_carrier::set_cfg(const ue_cfg_t& ue_cfg) { - slot_point slot_rx = pdcch_slot - TX_ENB_DELAY; + bwp_cfg = bwp_ue_cfg(rnti, cell_params.bwps[0], ue_cfg); +} - // update CC/BWP config if there were changes - if (bwp_cfg.ue_cfg() != &uecfg_) { - bwp_cfg = bwp_ue_cfg(rnti, cell_params.bwps[0], uecfg_); - } +slot_ue ue_carrier::try_reserve(slot_point pdcch_slot, uint32_t dl_pending_bytes, uint32_t ul_pending_bytes) +{ + slot_point slot_rx = pdcch_slot - TX_ENB_DELAY; // copy cc-specific parameters and find available HARQs slot_ue sfu(rnti, slot_rx, cc); @@ -90,8 +87,12 @@ void ue::set_cfg(const ue_cfg_t& cfg) { ue_cfg = cfg; for (auto& ue_cc_cfg : cfg.carriers) { - if (ue_cc_cfg.active and carriers[ue_cc_cfg.cc] == nullptr) { - carriers[ue_cc_cfg.cc].reset(new ue_carrier(rnti, cfg, sched_cfg.cells[ue_cc_cfg.cc])); + if (ue_cc_cfg.active) { + if (carriers[ue_cc_cfg.cc] == nullptr) { + carriers[ue_cc_cfg.cc].reset(new ue_carrier(rnti, cfg, sched_cfg.cells[ue_cc_cfg.cc])); + } else { + carriers[ue_cc_cfg.cc]->set_cfg(ue_cfg); + } } } @@ -147,7 +148,7 @@ slot_ue ue::try_reserve(slot_point pdcch_slot, uint32_t cc) return slot_ue(); } - return carriers[cc]->try_reserve(pdcch_slot, cfg(), dl_pending_bytes, ul_pending_bytes); + return carriers[cc]->try_reserve(pdcch_slot, dl_pending_bytes, ul_pending_bytes); } } // namespace sched_nr_impl From 73859a5b6a86ee077d19e33eba2d26ac33ead0dd Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 13 Oct 2021 17:57:13 +0100 Subject: [PATCH 131/208] nr,sched: improve logging of PDSCH and PUSCH in scheduler to also show coreset id and buffer state --- srsenb/src/stack/mac/nr/sched_nr_helpers.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/srsenb/src/stack/mac/nr/sched_nr_helpers.cc b/srsenb/src/stack/mac/nr/sched_nr_helpers.cc index f45900c81..015059778 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_helpers.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_helpers.cc @@ -145,17 +145,19 @@ void log_sched_bwp_result(srslog::basic_logger& logger, if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_c) { const slot_ue& ue = slot_ues[pdcch.dci.ctx.rnti]; fmt::format_to(fmtbuf, - "SCHED: DL {}, cc={}, rnti=0x{:x}, pid={}, f={}, prbs={}, nrtx={}, dai={}, tbs={}, " - "pdsch_slot={}, tti_ack={}", + "SCHED: DL {}, cc={}, rnti=0x{:x}, pid={}, cs={}, f={}, prbs={}, nrtx={}, dai={}, " + "tbs={}, bs={}, pdsch_slot={}, tti_ack={}", ue.h_dl->nof_retx() == 0 ? "tx" : "retx", res_grid.cfg->cc, ue.rnti, pdcch.dci.pid, + pdcch.dci.ctx.coreset_id, srsran_dci_format_nr_string(pdcch.dci.ctx.format), ue.h_dl->prbs(), ue.h_dl->nof_retx(), pdcch.dci.dai, ue.h_dl->tbs(), + ue.dl_pending_bytes, ue.pdsch_slot, ue.uci_slot); } else if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_ra) { @@ -164,7 +166,7 @@ void log_sched_bwp_result(srslog::basic_logger& logger, uint32_t start_idx = std::distance(prbs.begin(), std::find(prbs.begin(), prbs.end(), true)); uint32_t end_idx = std::distance(prbs.begin(), std::find(prbs.begin() + start_idx, prbs.end(), false)); fmt::format_to(fmtbuf, - "SCHED: DL RAR, cc={}, ra-rnti=0x{:x}, prbs={}, pdsch_slot={}, msg3_slot={}, nof_grants={}", + "SCHED: RAR, cc={}, ra-rnti=0x{:x}, prbs={}, pdsch_slot={}, msg3_slot={}, nof_grants={}", res_grid.cfg->cc, pdcch.dci.ctx.rnti, srsran::interval{start_idx, end_idx}, @@ -183,15 +185,16 @@ void log_sched_bwp_result(srslog::basic_logger& logger, if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_c) { const slot_ue& ue = slot_ues[pdcch.dci.ctx.rnti]; fmt::format_to(fmtbuf, - "SCHED: UL {}, cc={}, rnti=0x{:x}, pid={}, f={}, nrtx={}, pending_bytes={}, tbs={}, tti_pusch={}", + "SCHED: UL {}, cc={}, rnti=0x{:x}, pid={}, cs={}, f={}, nrtx={}, tbs={}, bs={}, tti_pusch={}", ue.h_ul->nof_retx() == 0 ? "tx" : "retx", res_grid.cfg->cc, ue.rnti, pdcch.dci.pid, + pdcch.dci.ctx.coreset_id, srsran_dci_format_nr_string(pdcch.dci.ctx.format), ue.h_ul->nof_retx(), - ue.ul_pending_bytes, ue.h_ul->tbs(), + ue.ul_pending_bytes, ue.pusch_slot); } else if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_tc) { const slot_ue& ue = slot_ues[pdcch.dci.ctx.rnti]; From efdd249cb34181454ae6517c455af0d91427f186 Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 13 Oct 2021 23:27:13 +0100 Subject: [PATCH 132/208] nr,sched: fix dangling reference to ue_cfg in scheduler --- srsenb/src/stack/mac/nr/sched_nr_ue.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/stack/mac/nr/sched_nr_ue.cc b/srsenb/src/stack/mac/nr/sched_nr_ue.cc index ed0349a0d..054342294 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_ue.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_ue.cc @@ -89,7 +89,7 @@ void ue::set_cfg(const ue_cfg_t& cfg) for (auto& ue_cc_cfg : cfg.carriers) { if (ue_cc_cfg.active) { if (carriers[ue_cc_cfg.cc] == nullptr) { - carriers[ue_cc_cfg.cc].reset(new ue_carrier(rnti, cfg, sched_cfg.cells[ue_cc_cfg.cc])); + carriers[ue_cc_cfg.cc].reset(new ue_carrier(rnti, ue_cfg, sched_cfg.cells[ue_cc_cfg.cc])); } else { carriers[ue_cc_cfg.cc]->set_cfg(ue_cfg); } From ecd1a15e1f82d9f00e37b024a1dc1e92e3619625 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Wed, 13 Oct 2021 19:20:52 +0200 Subject: [PATCH 133/208] mac: revert order of processing MAC subPDUs Signed-off-by: Carlo Galiotto --- srsenb/src/stack/mac/nr/ue_nr.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc index 05c40c343..88ae1a2a4 100644 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ b/srsenb/src/stack/mac/nr/ue_nr.cc @@ -74,7 +74,10 @@ int ue_nr::process_pdu(srsran::unique_byte_buffer_t pdu) logger.info("Rx PDU: rnti=0x%x, %s", rnti, srsran::to_c_str(str_buffer)); } - for (uint32_t i = 0; i < mac_pdu_ul.get_num_subpdus(); ++i) { + // Reverse the order in which MAC subPDUs get processed. + // First, process MAC CEs, then MAC MAC subPDUs with MAC SDUs + for (uint32_t n = mac_pdu_ul.get_num_subpdus(), i = mac_pdu_ul.get_num_subpdus() - 1; n > 0; + --n, i = n - 1) { srsran::mac_sch_subpdu_nr subpdu = mac_pdu_ul.get_subpdu(i); logger.debug("Handling subPDU %d/%d: lcid=%d, sdu_len=%d", i, From d708f05869ecdf75ca9baedf8c00cd6365fb1ed8 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 13 Oct 2021 23:05:22 +0200 Subject: [PATCH 134/208] rrc_endc: disable DC-PHR reporting in the UE this solves #3432 until we've fully implemented the parsing/handling of the DC-PHR --- srsenb/src/stack/rrc/rrc_endc.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index cbdc5cefa..ae6a720d8 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -138,7 +138,6 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn auto& mac_main_cfg = conn_recfg->rr_cfg_ded.mac_main_cfg.explicit_value(); - mac_main_cfg.ext = true; mac_main_cfg.time_align_timer_ded = time_align_timer_opts::infinity; mac_main_cfg.phr_cfg_present = true; mac_main_cfg.phr_cfg.set_setup(); @@ -149,6 +148,8 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn mac_main_cfg.phr_cfg.setup().prohibit_phr_timer = asn1::rrc::mac_main_cfg_s::phr_cfg_c_::setup_s_::prohibit_phr_timer_opts::sf200; + // Disable DC-PHR reporting + mac_main_cfg.ext = false; mac_main_cfg.mac_main_cfg_v1020.set_present(); mac_main_cfg.dual_connect_phr.set_present(); mac_main_cfg.dual_connect_phr.get()->set_setup(); From cc0255e4f122f2995bbfe31993d9ad786ffa3938 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 14 Oct 2021 18:08:08 +0200 Subject: [PATCH 135/208] enb,rrc_nr: reduce log level to info when C-RNTI is received for current RNTI it might happen (cause by the UE or eNB) that the Msg3 with C-RNTI is passed twice (e.g. Retx). It's ok to be logged for now but not in Error level. Reduce to warning. --- srsenb/src/stack/rrc/rrc_nr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index f8ea9348d..d107e3afe 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -182,7 +182,7 @@ void rrc_nr::rem_user(uint16_t rnti) int rrc_nr::update_user(uint16_t new_rnti, uint16_t old_rnti) { if (new_rnti == old_rnti) { - logger.error("rnti=0x%x received MAC CRNTI CE with same rnti", new_rnti); + logger.warning("rnti=0x%x received MAC CRNTI CE with same rnti", new_rnti); return SRSRAN_ERROR; } From ea324e8cbe5d6e8ea9affceef5c2c1ec4865df81 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 12 Oct 2021 20:54:25 +0100 Subject: [PATCH 136/208] nr,sched,test: update sched nr test to better reflect MAC-PHY FAPI --- lib/include/srsran/adt/circular_buffer.h | 15 +- lib/include/srsran/common/thread_pool.h | 34 ++++ lib/src/common/thread_pool.cc | 69 ++++++++ srsenb/src/stack/mac/nr/sched_nr_harq.cc | 2 +- srsenb/test/mac/nr/sched_nr_sim_ue.cc | 152 ++++++++++++---- srsenb/test/mac/nr/sched_nr_sim_ue.h | 121 +++++++++---- srsenb/test/mac/nr/sched_nr_test.cc | 163 +++++++----------- .../test/mac/nr/sched_nr_ue_ded_test_suite.cc | 2 +- .../test/mac/nr/sched_nr_ue_ded_test_suite.h | 2 +- 9 files changed, 382 insertions(+), 178 deletions(-) diff --git a/lib/include/srsran/adt/circular_buffer.h b/lib/include/srsran/adt/circular_buffer.h index c674a59f1..72f636dff 100644 --- a/lib/include/srsran/adt/circular_buffer.h +++ b/lib/include/srsran/adt/circular_buffer.h @@ -282,10 +282,13 @@ public: bool push_blocking(const T& t) { return push_(t, true); } srsran::error_type push_blocking(T&& t) { return push_(std::move(t), true); } bool try_pop(T& obj) { return pop_(obj, false); } - T pop_blocking() + T pop_blocking(bool* success = nullptr) { - T obj{}; - pop_(obj, true); + T obj{}; + bool ret = pop_(obj, true); + if (success != nullptr) { + *success = ret; + } return obj; } bool pop_wait_until(T& obj, const std::chrono::system_clock::time_point& until) { return pop_(obj, true, &until); } @@ -590,12 +593,6 @@ public: base_t(push_callback, pop_callback, size) {} void set_size(size_t size) { base_t::circ_buffer.set_size(size); } - - template - bool apply_first(const F& func) - { - return base_t::apply_first(func); - } }; } // namespace srsran diff --git a/lib/include/srsran/common/thread_pool.h b/lib/include/srsran/common/thread_pool.h index bc0973d64..7626a33c5 100644 --- a/lib/include/srsran/common/thread_pool.h +++ b/lib/include/srsran/common/thread_pool.h @@ -144,6 +144,40 @@ private: bool running = false; }; +/// Class used to create a single worker with an input task queue with a single reader +class task_worker : public thread +{ + using task_t = srsran::move_callback; + +public: + task_worker(std::string thread_name_, + uint32_t queue_size, + bool start_deferred = false, + int32_t prio_ = -1, + uint32_t mask_ = 255); + task_worker(const task_worker&) = delete; + task_worker(task_worker&&) = delete; + task_worker& operator=(const task_worker&) = delete; + task_worker& operator=(task_worker&&) = delete; + ~task_worker(); + + void stop(); + void start(int32_t prio_ = -1, uint32_t mask_ = 255); + + void push_task(task_t&& task); + uint32_t nof_pending_tasks() const; + +private: + void run_thread() override; + + // args + int32_t prio = -1; + uint32_t mask = 255; + srslog::basic_logger& logger; + + srsran::dyn_blocking_queue pending_tasks; +}; + srsran::task_thread_pool& get_background_workers(); } // namespace srsran diff --git a/lib/src/common/thread_pool.cc b/lib/src/common/thread_pool.cc index f01327c75..10ea76658 100644 --- a/lib/src/common/thread_pool.cc +++ b/lib/src/common/thread_pool.cc @@ -392,6 +392,75 @@ void task_thread_pool::worker_t::run_thread() running = false; } +task_worker::task_worker(std::string thread_name_, + uint32_t queue_size, + bool start_deferred, + int32_t prio_, + uint32_t mask_) : + thread(std::move(thread_name_)), + prio(prio_), + mask(mask_), + pending_tasks(queue_size), + logger(srslog::fetch_basic_logger("POOL")) +{ + if (not start_deferred) { + start(prio_, mask_); + } +} + +task_worker::~task_worker() +{ + stop(); +} + +void task_worker::stop() +{ + if (not pending_tasks.is_stopped()) { + pending_tasks.stop(); + wait_thread_finish(); + } +} + +void task_worker::start(int32_t prio_, uint32_t mask_) +{ + prio = prio_; + mask = mask_; + + if (mask == 255) { + thread::start(prio); + } else { + thread::start_cpu_mask(prio, mask); + } +} + +void task_worker::push_task(task_t&& task) +{ + auto ret = pending_tasks.try_push(std::move(task)); + if (ret.is_error()) { + logger.error("Cannot push anymore tasks into the worker queue. maximum size is %u", + uint32_t(pending_tasks.max_size())); + return; + } +} + +uint32_t task_worker::nof_pending_tasks() const +{ + return pending_tasks.size(); +} + +void task_worker::run_thread() +{ + while (true) { + bool success; + task_t task = pending_tasks.pop_blocking(&success); + if (not success) { + break; + } + task(); + } + logger.info("Task worker %s finished.", thread::get_name().c_str()); +} + // Global thread pool for long, low-priority tasks task_thread_pool& get_background_workers() { diff --git a/srsenb/src/stack/mac/nr/sched_nr_harq.cc b/srsenb/src/stack/mac/nr/sched_nr_harq.cc index 0b184f38f..003925a3a 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_harq.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_harq.cc @@ -25,7 +25,7 @@ int harq_proc::ack_info(uint32_t tb_idx, bool ack) if (ack) { tb[tb_idx].active = false; } - return tb[tb_idx].tbs; + return ack ? tb[tb_idx].tbs : 0; } void harq_proc::new_slot(slot_point slot_rx) diff --git a/srsenb/test/mac/nr/sched_nr_sim_ue.cc b/srsenb/test/mac/nr/sched_nr_sim_ue.cc index 5034e6cb1..39f45222d 100644 --- a/srsenb/test/mac/nr/sched_nr_sim_ue.cc +++ b/srsenb/test/mac/nr/sched_nr_sim_ue.cc @@ -37,7 +37,7 @@ sched_nr_ue_sim::sched_nr_ue_sim(uint16_t rnti_, } } -int sched_nr_ue_sim::update(const sched_nr_cc_output_res_t& cc_out) +int sched_nr_ue_sim::update(const sched_nr_cc_result_view& cc_out) { update_dl_harqs(cc_out); @@ -60,7 +60,7 @@ int sched_nr_ue_sim::update(const sched_nr_cc_output_res_t& cc_out) return SRSRAN_SUCCESS; } -void sched_nr_ue_sim::update_dl_harqs(const sched_nr_cc_output_res_t& cc_out) +void sched_nr_ue_sim::update_dl_harqs(const sched_nr_cc_result_view& cc_out) { uint32_t cc = cc_out.cc; for (uint32_t i = 0; i < cc_out.dl_cc_result->dl_sched.pdcch_dl.size(); ++i) { @@ -90,6 +90,8 @@ void sched_nr_ue_sim::update_dl_harqs(const sched_nr_cc_output_res_t& cc_out) } } +namespace detail { + sched_nr_sim_base::sched_nr_sim_base(const sched_nr_interface::sched_args_t& sched_args, const std::vector& cell_cfg_list, std::string test_name_) : @@ -105,6 +107,8 @@ sched_nr_sim_base::sched_nr_sim_base(const sched_nr_interface::sched_args_t& } sched_ptr->config(sched_args, cell_cfg_list); // call parent cfg + cc_results.resize(cell_params.size()); + TESTASSERT(cell_params.size() > 0); } @@ -118,9 +122,11 @@ int sched_nr_sim_base::add_user(uint16_t rnti, slot_point tti_rx, uint32_t preamble_idx) { + sched_ptr->ue_cfg(rnti, ue_cfg_); + + std::lock_guard lock(std::mutex); TESTASSERT(ue_db.count(rnti) == 0); - sched_ptr->ue_cfg(rnti, ue_cfg_); ue_db.insert(std::make_pair(rnti, sched_nr_ue_sim(rnti, ue_cfg_, current_slot_tx, preamble_idx))); sched_nr_interface::rar_info_t rach_info{}; @@ -133,17 +139,18 @@ int sched_nr_sim_base::add_user(uint16_t rnti, return SRSRAN_SUCCESS; } -void sched_nr_sim_base::new_slot(slot_point slot_tx) +void sched_nr_sim_base::new_slot_(slot_point slot_tx) { - std::unique_lock lock(mutex); - while (cc_finished > 0) { - cvar.wait(lock); - } logger.set_context(slot_tx.to_uint()); mac_logger.set_context(slot_tx.to_uint()); + + // Clear previous slot results + for (uint32_t cc = 0; cc < cc_results.size(); ++cc) { + cc_results[cc] = {}; + } logger.info("---------------- TTI=%d ---------------", slot_tx.to_uint()); - current_slot_tx = slot_tx; - cc_finished = cell_params.size(); + + // Process pending feedback for (auto& ue : ue_db) { ue_nr_slot_events events; set_default_slot_events(ue.second.get_ctxt(), events); @@ -152,27 +159,42 @@ void sched_nr_sim_base::new_slot(slot_point slot_tx) } } -void sched_nr_sim_base::update(sched_nr_cc_output_res_t& cc_out) +void sched_nr_sim_base::generate_cc_result_(uint32_t cc) { - std::unique_lock lock(mutex); - - sim_nr_enb_ctxt_t ctxt; - ctxt = get_enb_ctxt(); - - // Run common tests - test_dl_pdcch_consistency(cc_out.dl_cc_result->dl_sched.pdcch_dl); - test_pdsch_consistency(cc_out.dl_cc_result->dl_sched.pdsch); - test_ssb_scheduled_grant(cc_out.slot, ctxt.cell_params[cc_out.cc].cfg, cc_out.dl_cc_result->dl_sched.ssb); - - // Run UE-dedicated tests - test_dl_sched_result(ctxt, cc_out); - - for (auto& u : ue_db) { - u.second.update(cc_out); - } + // Run scheduler + auto tp1 = std::chrono::steady_clock::now(); + sched_ptr->run_slot(current_slot_tx, cc, cc_results[cc].dl_res); + sched_ptr->get_ul_sched(current_slot_tx, cc, cc_results[cc].ul_res); + auto tp2 = std::chrono::steady_clock::now(); + cc_results[cc].sched_latency_ns = std::chrono::duration_cast(tp2 - tp1); +} - if (--cc_finished <= 0) { - cvar.notify_one(); +void sched_nr_sim_base::process_results() +{ + sched_nr_cc_result_view cc_out; + cc_out.slot = current_slot_tx; + for (uint32_t cc = 0; cc < cell_params.size(); ++cc) { + cc_out.cc = cc; + cc_out.dl_cc_result = &cc_results[cc].dl_res; + cc_out.ul_cc_result = &cc_results[cc].ul_res; + + // Run common tests + test_dl_pdcch_consistency(cc_out.dl_cc_result->dl_sched.pdcch_dl); + test_pdsch_consistency(cc_out.dl_cc_result->dl_sched.pdsch); + test_ssb_scheduled_grant(cc_out.slot, cell_params[cc_out.cc].cfg, cc_out.dl_cc_result->dl_sched.ssb); + + // Run UE-dedicated tests + sim_nr_enb_ctxt_t ctxt; + ctxt = get_enb_ctxt(); + test_dl_sched_result(ctxt, cc_out); + + // Derived class-defined tests + process_cc_result(cc_results[cc]); + + // Update UE state + for (auto& u : ue_db) { + u.second.update(cc_out); + } } } @@ -263,4 +285,76 @@ sim_nr_enb_ctxt_t sched_nr_sim_base::get_enb_ctxt() const return ctxt; } +} // namespace detail + +void sched_nr_sim::new_slot(slot_point slot_tx) +{ + current_slot_tx = slot_tx; + nof_cc_remaining = cell_params.size(); + this->new_slot_(slot_tx); +} + +void sched_nr_sim::generate_cc_result(uint32_t cc) +{ + // Run scheduler + this->generate_cc_result_(cc); + + if (--nof_cc_remaining > 0) { + // there are still missing CC results + return; + } + + // Run tests and update UE state + this->process_results(); +} + +void sched_nr_sim_parallel::new_slot(slot_point slot_tx) +{ + // Block concurrent or out-of-order calls to the scheduler + { + std::unique_lock lock(mutex); + while (nof_cc_remaining > 0 or (current_slot_tx.valid() and current_slot_tx + 1 != slot_tx)) { + cvar.wait(lock); + } + current_slot_tx = slot_tx; + nof_cc_remaining = cell_params.size(); + } + + // Run common new_slot updates + this->new_slot_(slot_tx); +} + +void sched_nr_sim_parallel::generate_cc_result(uint32_t cc) +{ + // Run scheduler + this->generate_cc_result_(cc); + + { + std::unique_lock lock(mutex); + if (--nof_cc_remaining > 0) { + // there are still missing CC results + return; + } + + // Run tests and update UE state + this->process_results(); + } + + // Notify waiting workers + cvar.notify_one(); +} + +sched_nr_sim_parallel::~sched_nr_sim_parallel() +{ + stop(); +} + +void sched_nr_sim_parallel::stop() +{ + std::unique_lock lock(mutex); + while (nof_cc_remaining > 0) { + cvar.wait(lock); + } +} + } // namespace srsenb \ No newline at end of file diff --git a/srsenb/test/mac/nr/sched_nr_sim_ue.h b/srsenb/test/mac/nr/sched_nr_sim_ue.h index 05a347b7e..47f360a83 100644 --- a/srsenb/test/mac/nr/sched_nr_sim_ue.h +++ b/srsenb/test/mac/nr/sched_nr_sim_ue.h @@ -33,7 +33,7 @@ struct ue_nr_harq_ctxt_t { uint32_t tbs = 0; slot_point last_slot_tx, first_slot_tx, last_slot_ack; }; -struct sched_nr_cc_output_res_t { +struct sched_nr_cc_result_view { slot_point slot; uint32_t cc; const sched_nr_interface::dl_sched_res_t* dl_cc_result; @@ -86,21 +86,32 @@ public: slot_point prach_slot_rx, uint32_t preamble_idx); - int update(const sched_nr_cc_output_res_t& cc_out); + int update(const sched_nr_cc_result_view& cc_out); const sim_nr_ue_ctxt_t& get_ctxt() const { return ctxt; } sim_nr_ue_ctxt_t& get_ctxt() { return ctxt; } private: - void update_dl_harqs(const sched_nr_cc_output_res_t& sf_out); + void update_dl_harqs(const sched_nr_cc_result_view& sf_out); srslog::basic_logger& logger; sim_nr_ue_ctxt_t ctxt; }; +namespace detail { + +/// Implementation of features common to sched_nr_sim_parallel and sched_nr_sim class sched_nr_sim_base { public: + struct cc_result_t { + slot_point slot_tx; + uint32_t cc; + sched_nr_interface::dl_sched_res_t dl_res; + sched_nr_interface::ul_sched_t ul_res; + std::chrono::nanoseconds sched_latency_ns; + }; + sched_nr_sim_base(const sched_nr_interface::sched_args_t& sched_args, const std::vector& cell_params_, std::string test_name); @@ -108,8 +119,77 @@ public: int add_user(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg_, slot_point tti_rx, uint32_t preamble_idx); + srsran::const_span get_cell_params() { return cell_params; } + + // configurable by simulator concrete implementation + virtual void set_external_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_slot_events& pending_events) {} + + // configurable by simulator concrete implementation + virtual void process_cc_result(const cc_result_t& cc_out) {} + +protected: + void new_slot_(slot_point slot_tx); + void generate_cc_result_(uint32_t cc); + sim_nr_enb_ctxt_t get_enb_ctxt() const; + + int set_default_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_slot_events& pending_events); + int apply_slot_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_nr_slot_events& events); + + /// Runs general tests to verify result consistency, and updates UE state + void process_results(); + + std::string test_name; + srslog::basic_logger& logger; + srslog::basic_logger& mac_logger; + std::unique_ptr sched_ptr; + std::vector cell_params; + + uint32_t nof_cc_remaining = 0; + slot_point current_slot_tx; + std::vector cc_results; + + std::map ue_db; +}; +} // namespace detail + +class sched_nr_sim_parallel : public detail::sched_nr_sim_base +{ + using base_t = detail::sched_nr_sim_base; + +public: + using base_t::base_t; + ~sched_nr_sim_parallel(); + + void stop(); + + int add_user(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg_, slot_point tti_rx, uint32_t preamble_idx) + { + std::lock_guard lock(mutex); + return base_t::add_user(rnti, ue_cfg_, tti_rx, preamble_idx); + } + slot_point get_slot_tx() const + { + std::lock_guard lock(mutex); + return current_slot_tx; + } + void new_slot(slot_point slot_tx); - void update(sched_nr_cc_output_res_t& cc_out); + void generate_cc_result(uint32_t cc); + +private: + mutable std::mutex mutex; + std::condition_variable cvar; +}; + +class sched_nr_sim : public detail::sched_nr_sim_base +{ + using base_t = detail::sched_nr_sim_base; + +public: + using sched_nr_sim_base::sched_nr_sim_base; + + void new_slot(slot_point slot_tx); + void generate_cc_result(uint32_t cc); sched_nr_ue_sim& at(uint16_t rnti) { return ue_db.at(rnti); } const sched_nr_ue_sim& at(uint16_t rnti) const { return ue_db.at(rnti); } @@ -123,45 +203,18 @@ public: auto it = ue_db.find(rnti); return it != ue_db.end() ? &it->second : nullptr; } - bool user_exists(uint16_t rnti) const { return ue_db.count(rnti) > 0; } const sched_nr_interface::ue_cfg_t* get_user_cfg(uint16_t rnti) const { const sched_nr_ue_sim* ret = find_rnti(rnti); return ret == nullptr ? nullptr : &ret->get_ctxt().ue_cfg; } - sched_nr* get_sched() { return sched_ptr.get(); } - srsran::const_span get_cell_params() { return cell_params; } - slot_point get_slot_rx() const - { - std::lock_guard lock(mutex); - return current_slot_tx; - } - - sim_nr_enb_ctxt_t get_enb_ctxt() const; + bool user_exists(uint16_t rnti) const { return ue_db.count(rnti) > 0; } + sched_nr* get_sched() { return sched_ptr.get(); } std::map::iterator begin() { return ue_db.begin(); } std::map::iterator end() { return ue_db.end(); } - // configurable by simulator concrete implementation - virtual void set_external_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_slot_events& pending_events) {} - -private: - int set_default_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_slot_events& pending_events); - int apply_slot_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_nr_slot_events& events); - - std::string test_name; - srslog::basic_logger& logger; - srslog::basic_logger& mac_logger; - std::unique_ptr sched_ptr; - std::vector cell_params; - - slot_point current_slot_tx; - int cc_finished = 0; - - std::map ue_db; - - mutable std::mutex mutex; - std::condition_variable cvar; + slot_point get_slot_tx() const { return current_slot_tx; } }; } // namespace srsenb diff --git a/srsenb/test/mac/nr/sched_nr_test.cc b/srsenb/test/mac/nr/sched_nr_test.cc index 035413727..1cd6f18b0 100644 --- a/srsenb/test/mac/nr/sched_nr_test.cc +++ b/srsenb/test/mac/nr/sched_nr_test.cc @@ -24,155 +24,114 @@ using dl_sched_t = sched_nr_interface::dl_sched_t; static const srsran::phy_cfg_nr_t default_phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}}; -struct task_job_manager { - std::mutex mutex; - int res_count = 0; - int pdsch_count = 0; - srslog::basic_logger& test_logger = srslog::fetch_basic_logger("TEST"); - struct slot_guard { - int count = 0; - std::condition_variable cvar; - }; - srsran::bounded_vector slot_counter{}; - - explicit task_job_manager(int max_concurrent_slots = 4) : slot_counter(max_concurrent_slots) {} +class sched_nr_tester : public sched_nr_sim_parallel +{ +public: + using sched_nr_sim_parallel::sched_nr_sim_parallel; - void start_slot(slot_point slot, int nof_sectors) - { - std::unique_lock lock(mutex); - auto& sl = slot_counter[slot.to_uint() % slot_counter.size()]; - while (sl.count > 0) { - sl.cvar.wait(lock); - } - sl.count = nof_sectors; - } - void finish_cc(slot_point slot, - const sched_nr_interface::dl_sched_res_t& dl_res, - const sched_nr_interface::ul_sched_t& ul_res) + void process_cc_result(const cc_result_t& cc_result) override { - std::unique_lock lock(mutex); - TESTASSERT(dl_res.dl_sched.pdcch_dl.size() <= 1); - res_count++; - pdsch_count += dl_res.dl_sched.pdcch_dl.size(); - auto& sl = slot_counter[slot.to_uint() % slot_counter.size()]; - if (--sl.count == 0) { - sl.cvar.notify_one(); - } - } - void wait_task_finish() - { - std::unique_lock lock(mutex); - for (auto& sl : slot_counter) { - while (sl.count > 0) { - sl.cvar.wait(lock); - } - sl.count = 1; + tot_latency_sched_ns += cc_result.sched_latency_ns.count(); + result_count++; + pdsch_count += cc_result.dl_res.dl_sched.pdcch_dl.size(); + + TESTASSERT(cc_result.dl_res.dl_sched.pdcch_dl.size() <= 1); + if (srsran_duplex_nr_is_dl(&cell_params[cc_result.cc].cfg.duplex, 0, current_slot_tx.slot_idx())) { + TESTASSERT(cc_result.dl_res.dl_sched.pdcch_dl.size() == 1 or not cc_result.dl_res.dl_sched.ssb.empty()); } } + void print_results() const { - test_logger.info("TESTER: %f PDSCH/{slot,cc} were allocated", pdsch_count / (double)res_count); + test_logger.info("TESTER: %f PDSCH/{slot,cc} were allocated", pdsch_count / (double)result_count); srslog::flush(); } + + srslog::basic_logger& test_logger = srslog::fetch_basic_logger("TEST"); + + uint64_t tot_latency_sched_ns = 0; + uint32_t result_count = 0; + uint32_t pdsch_count = 0; }; void sched_nr_cfg_serialized_test() { - uint32_t max_nof_ttis = 1000, nof_sectors = 4; - task_job_manager tasks; + uint32_t max_nof_ttis = 1000, nof_sectors = 4; + uint16_t rnti = 0x4601; sched_nr_interface::sched_args_t cfg; cfg.auto_refill_buffer = true; std::vector cells_cfg = get_default_cells_cfg(nof_sectors); - sched_nr_sim_base sched_tester(cfg, cells_cfg, "Serialized Test"); + sched_nr_tester tester(cfg, cells_cfg, "Serialized Test"); sched_nr_interface::ue_cfg_t uecfg = get_default_ue_cfg(nof_sectors); - sched_tester.add_user(0x46, uecfg, slot_point{0, 0}, 0); + tester.add_user(rnti, uecfg, slot_point{0, 0}, 0); - std::vector count_per_cc(nof_sectors, 0); for (uint32_t nof_slots = 0; nof_slots < max_nof_ttis; ++nof_slots) { slot_point slot_rx(0, nof_slots % 10240); slot_point slot_tx = slot_rx + TX_ENB_DELAY; - tasks.start_slot(slot_rx, nof_sectors); - sched_tester.new_slot(slot_tx); - for (uint32_t cc = 0; cc < cells_cfg.size(); ++cc) { - sched_nr_interface::dl_sched_res_t dl_res; - sched_nr_interface::ul_sched_t ul_res; - auto tp1 = std::chrono::steady_clock::now(); - TESTASSERT(sched_tester.get_sched()->run_slot(slot_tx, cc, dl_res) == SRSRAN_SUCCESS); - TESTASSERT(sched_tester.get_sched()->get_ul_sched(slot_tx, cc, ul_res) == SRSRAN_SUCCESS); - auto tp2 = std::chrono::steady_clock::now(); - count_per_cc[cc] += std::chrono::duration_cast(tp2 - tp1).count(); - sched_nr_cc_output_res_t out{slot_tx, cc, &dl_res, &ul_res}; - sched_tester.update(out); - tasks.finish_cc(slot_rx, dl_res, ul_res); - TESTASSERT(not srsran_duplex_nr_is_dl(&cells_cfg[cc].duplex, 0, (slot_tx).slot_idx()) or - (dl_res.dl_sched.pdcch_dl.size() == 1 or not dl_res.dl_sched.ssb.empty())); + tester.new_slot(slot_tx); + for (uint32_t cc = 0; cc != cells_cfg.size(); ++cc) { + tester.generate_cc_result(cc); } } - tasks.print_results(); + tester.stop(); + tester.print_results(); // TESTASSERT(tasks.pdsch_count == (int)(max_nof_ttis * nof_sectors * 0.6)); - double final_avg_usec = 0; - for (uint32_t cc = 0; cc < cells_cfg.size(); ++cc) { - final_avg_usec += count_per_cc[cc]; - } - final_avg_usec = final_avg_usec / 1000.0 / max_nof_ttis; + double final_avg_usec = tester.tot_latency_sched_ns; + final_avg_usec = final_avg_usec / 1000.0 / max_nof_ttis; printf("Total time taken per slot: %f usec\n", final_avg_usec); } void sched_nr_cfg_parallel_cc_test() { - uint32_t nof_sectors = 4; - uint32_t max_nof_ttis = 1000; - task_job_manager tasks; + uint32_t nof_sectors = 4; + uint32_t max_nof_ttis = 1000; + uint16_t rnti = 0x4601; + + // Initiate CC Workers + std::vector > cc_workers; + cc_workers.reserve(nof_sectors - 1); + for (uint32_t i = 0; i < nof_sectors - 1; ++i) { + fmt::memory_buffer fmtbuf; + fmt::format_to(fmtbuf, "worker{}", i); + cc_workers.emplace_back(new srsran::task_worker{to_string(fmtbuf), 10}); + } sched_nr_interface::sched_args_t cfg; cfg.auto_refill_buffer = true; std::vector cells_cfg = get_default_cells_cfg(nof_sectors); - sched_nr_sim_base sched_tester(cfg, cells_cfg, "Parallel CC Test"); + sched_nr_tester tester(cfg, cells_cfg, "Parallel CC Test"); sched_nr_interface::ue_cfg_t uecfg = get_default_ue_cfg(cells_cfg.size()); - sched_tester.add_user(0x46, uecfg, slot_point{0, 0}, 0); + tester.add_user(rnti, uecfg, slot_point{0, 0}, 0); - std::array, SRSRAN_MAX_CARRIERS> nano_count{}; for (uint32_t nof_slots = 0; nof_slots < max_nof_ttis; ++nof_slots) { slot_point slot_rx(0, nof_slots % 10240); slot_point slot_tx = slot_rx + TX_ENB_DELAY; - tasks.start_slot(slot_tx, nof_sectors); - sched_tester.new_slot(slot_tx); - for (uint32_t cc = 0; cc < cells_cfg.size(); ++cc) { - srsran::get_background_workers().push_task([cc, slot_tx, &tasks, &sched_tester, &nano_count]() { - sched_nr_interface::dl_sched_res_t dl_res; - sched_nr_interface::ul_sched_t ul_res; - auto tp1 = std::chrono::steady_clock::now(); - TESTASSERT(sched_tester.get_sched()->run_slot(slot_tx, cc, dl_res) == SRSRAN_SUCCESS); - TESTASSERT(sched_tester.get_sched()->get_ul_sched(slot_tx, cc, ul_res) == SRSRAN_SUCCESS); - auto tp2 = std::chrono::steady_clock::now(); - nano_count[cc].fetch_add(std::chrono::duration_cast(tp2 - tp1).count(), - std::memory_order_relaxed); - sched_nr_cc_output_res_t out{slot_tx, cc, &dl_res, &ul_res}; - sched_tester.update(out); - tasks.finish_cc(slot_tx, dl_res, ul_res); - }); + tester.new_slot(slot_tx); + // Run scheduler in parallel for {0, cc-2} and in the same thread for last cc + for (uint32_t cc = 0; cc != cells_cfg.size() - 1; ++cc) { + cc_workers[cc]->push_task([cc, &tester]() { tester.generate_cc_result(cc); }); } + tester.generate_cc_result(cells_cfg.size() - 1); } - tasks.wait_task_finish(); + // Wait for all jobs to finish + tester.stop(); + + tester.print_results(); - tasks.print_results(); // TESTASSERT(tasks.pdsch_count == (int)(max_nof_ttis * nof_sectors * 0.6)); - double final_avg_usec = 0; - for (uint32_t i = 0; i < nof_sectors; ++i) { - final_avg_usec += nano_count[i]; - } - final_avg_usec = final_avg_usec / 1000.0 / max_nof_ttis / nof_sectors; + double final_avg_usec = tester.tot_latency_sched_ns; + final_avg_usec = final_avg_usec / 1000.0 / max_nof_ttis / nof_sectors; printf("Total time taken per slot [usec]: %f\n", final_avg_usec); } @@ -181,17 +140,15 @@ void sched_nr_cfg_parallel_cc_test() int main() { auto& test_logger = srslog::fetch_basic_logger("TEST"); - test_logger.set_level(srslog::basic_levels::info); - auto& mac_logger = srslog::fetch_basic_logger("MAC"); - mac_logger.set_level(srslog::basic_levels::info); + test_logger.set_level(srslog::basic_levels::error); + auto& mac_nr_logger = srslog::fetch_basic_logger("MAC-NR"); + mac_nr_logger.set_level(srslog::basic_levels::error); auto& pool_logger = srslog::fetch_basic_logger("POOL"); - pool_logger.set_level(srslog::basic_levels::info); + pool_logger.set_level(srslog::basic_levels::debug); // Start the log backend. srslog::init(); - srsran::get_background_workers().set_nof_workers(6); - srsenb::sched_nr_cfg_serialized_test(); srsenb::sched_nr_cfg_parallel_cc_test(); } diff --git a/srsenb/test/mac/nr/sched_nr_ue_ded_test_suite.cc b/srsenb/test/mac/nr/sched_nr_ue_ded_test_suite.cc index 5e9fadc10..22d33e251 100644 --- a/srsenb/test/mac/nr/sched_nr_ue_ded_test_suite.cc +++ b/srsenb/test/mac/nr/sched_nr_ue_ded_test_suite.cc @@ -18,7 +18,7 @@ namespace srsenb { using namespace srsenb::sched_nr_impl; -void test_dl_sched_result(const sim_nr_enb_ctxt_t& enb_ctxt, const sched_nr_cc_output_res_t& cc_out) +void test_dl_sched_result(const sim_nr_enb_ctxt_t& enb_ctxt, const sched_nr_cc_result_view& cc_out) { slot_point pdcch_slot = cc_out.slot; const pdcch_dl_list_t& pdcchs = cc_out.dl_cc_result->dl_sched.pdcch_dl; diff --git a/srsenb/test/mac/nr/sched_nr_ue_ded_test_suite.h b/srsenb/test/mac/nr/sched_nr_ue_ded_test_suite.h index 3bc19f74f..69b067649 100644 --- a/srsenb/test/mac/nr/sched_nr_ue_ded_test_suite.h +++ b/srsenb/test/mac/nr/sched_nr_ue_ded_test_suite.h @@ -17,7 +17,7 @@ namespace srsenb { -void test_dl_sched_result(const sim_nr_enb_ctxt_t& enb_ctxt, const sched_nr_cc_output_res_t& cc_out); +void test_dl_sched_result(const sim_nr_enb_ctxt_t& enb_ctxt, const sched_nr_cc_result_view& cc_out); } From bc4264277a8db7e636f9462fc0e32a50e702bc3d Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 14 Oct 2021 15:17:03 +0100 Subject: [PATCH 137/208] sched,nr: update NR scheduler tester to support parallel CC workers --- srsenb/test/mac/nr/sched_nr_sim_ue.cc | 181 ++++++++++++-------------- srsenb/test/mac/nr/sched_nr_sim_ue.h | 104 ++++----------- srsenb/test/mac/nr/sched_nr_test.cc | 102 +++++---------- 3 files changed, 138 insertions(+), 249 deletions(-) diff --git a/srsenb/test/mac/nr/sched_nr_sim_ue.cc b/srsenb/test/mac/nr/sched_nr_sim_ue.cc index 39f45222d..1f4ba8b3b 100644 --- a/srsenb/test/mac/nr/sched_nr_sim_ue.cc +++ b/srsenb/test/mac/nr/sched_nr_sim_ue.cc @@ -14,6 +14,7 @@ #include "sched_nr_common_test.h" #include "sched_nr_ue_ded_test_suite.h" #include "srsran/common/test_common.h" +#include "srsran/common/thread_pool.h" namespace srsenb { @@ -90,41 +91,63 @@ void sched_nr_ue_sim::update_dl_harqs(const sched_nr_cc_result_view& cc_out) } } -namespace detail { - -sched_nr_sim_base::sched_nr_sim_base(const sched_nr_interface::sched_args_t& sched_args, - const std::vector& cell_cfg_list, - std::string test_name_) : +sched_nr_base_tester::sched_nr_base_tester(const sched_nr_interface::sched_args_t& sched_args, + const std::vector& cell_cfg_list, + std::string test_name_, + uint32_t nof_workers) : logger(srslog::fetch_basic_logger("TEST")), mac_logger(srslog::fetch_basic_logger("MAC")), sched_ptr(new sched_nr()), test_name(std::move(test_name_)) { - logger.info("\n=========== Start %s ===========", test_name.c_str()); + sem_init(&slot_sem, 0, 1); + + printf("\n=========== Start %s ===========\n", test_name.c_str()); cell_params.reserve(cell_cfg_list.size()); for (uint32_t cc = 0; cc < cell_cfg_list.size(); ++cc) { cell_params.emplace_back(cc, cell_cfg_list[cc], sched_args); } sched_ptr->config(sched_args, cell_cfg_list); // call parent cfg + cc_workers.resize(nof_workers - 1); + for (uint32_t i = 0; i < cc_workers.size(); ++i) { + fmt::memory_buffer fmtbuf; + fmt::format_to(fmtbuf, "worker{}", i + 1); + cc_workers[i].reset(new srsran::task_worker{to_string(fmtbuf), 10}); + } + cc_results.resize(cell_params.size()); TESTASSERT(cell_params.size() > 0); } -sched_nr_sim_base::~sched_nr_sim_base() +sched_nr_base_tester::~sched_nr_base_tester() { - logger.info("=========== End %s ==========\n", test_name.c_str()); + stop(); +} + +void sched_nr_base_tester::stop() +{ + bool stopping = not stopped.exchange(true); + if (stopping) { + sem_wait(&slot_sem); + sem_post(&slot_sem); + for (auto& worker : cc_workers) { + worker->stop(); + } + sem_destroy(&slot_sem); + printf("============ End %s ===========\n", test_name.c_str()); + } } -int sched_nr_sim_base::add_user(uint16_t rnti, - const sched_nr_interface::ue_cfg_t& ue_cfg_, - slot_point tti_rx, - uint32_t preamble_idx) +int sched_nr_base_tester::add_user(uint16_t rnti, + const sched_nr_interface::ue_cfg_t& ue_cfg_, + slot_point tti_rx, + uint32_t preamble_idx) { + sem_wait(&slot_sem); sched_ptr->ue_cfg(rnti, ue_cfg_); - std::lock_guard lock(std::mutex); TESTASSERT(ue_db.count(rnti) == 0); ue_db.insert(std::make_pair(rnti, sched_nr_ue_sim(rnti, ue_cfg_, current_slot_tx, preamble_idx))); @@ -136,11 +159,19 @@ int sched_nr_sim_base::add_user(uint16_t rnti, rach_info.msg3_size = 7; sched_ptr->dl_rach_info(ue_cfg_.carriers[0].cc, rach_info); + sem_post(&slot_sem); + return SRSRAN_SUCCESS; } -void sched_nr_sim_base::new_slot_(slot_point slot_tx) +void sched_nr_base_tester::run_slot(slot_point slot_tx) { + srsran_assert(not stopped.load(std::memory_order_relaxed), "Running scheduler when it has already been stopped"); + // Block concurrent or out-of-order calls to the scheduler + sem_wait(&slot_sem); + current_slot_tx = slot_tx; + nof_cc_remaining = cell_params.size(); + logger.set_context(slot_tx.to_uint()); mac_logger.set_context(slot_tx.to_uint()); @@ -157,20 +188,47 @@ void sched_nr_sim_base::new_slot_(slot_point slot_tx) set_external_slot_events(ue.second.get_ctxt(), events); apply_slot_events(ue.second.get_ctxt(), events); } + + slot_ctxt = get_enb_ctxt(); + slot_start_tp = std::chrono::steady_clock::now(); + + // Generate CC result (parallel or serialized) + uint32_t worker_idx = 0; + for (uint32_t cc = 0; cc < cell_params.size(); ++cc) { + if (worker_idx == cc_workers.size()) { + generate_cc_result(cc); + } else { + cc_workers[worker_idx]->push_task([this, cc]() { generate_cc_result(cc); }); + } + worker_idx = (worker_idx + 1) % (cc_workers.size() + 1); + } } -void sched_nr_sim_base::generate_cc_result_(uint32_t cc) +void sched_nr_base_tester::generate_cc_result(uint32_t cc) { // Run scheduler - auto tp1 = std::chrono::steady_clock::now(); sched_ptr->run_slot(current_slot_tx, cc, cc_results[cc].dl_res); sched_ptr->get_ul_sched(current_slot_tx, cc, cc_results[cc].ul_res); - auto tp2 = std::chrono::steady_clock::now(); - cc_results[cc].sched_latency_ns = std::chrono::duration_cast(tp2 - tp1); + auto tp2 = std::chrono::steady_clock::now(); + cc_results[cc].cc_latency_ns = std::chrono::duration_cast(tp2 - slot_start_tp); + + if (--nof_cc_remaining > 0) { + // there are still missing CC results + return; + } + + // Run tests and update UE state + process_results(); + + // Notify awaiting new slot worker + sem_post(&slot_sem); } -void sched_nr_sim_base::process_results() +void sched_nr_base_tester::process_results() { + // Derived class-defined tests + process_slot_result(slot_ctxt, cc_results); + sched_nr_cc_result_view cc_out; cc_out.slot = current_slot_tx; for (uint32_t cc = 0; cc < cell_params.size(); ++cc) { @@ -184,12 +242,7 @@ void sched_nr_sim_base::process_results() test_ssb_scheduled_grant(cc_out.slot, cell_params[cc_out.cc].cfg, cc_out.dl_cc_result->dl_sched.ssb); // Run UE-dedicated tests - sim_nr_enb_ctxt_t ctxt; - ctxt = get_enb_ctxt(); - test_dl_sched_result(ctxt, cc_out); - - // Derived class-defined tests - process_cc_result(cc_results[cc]); + test_dl_sched_result(slot_ctxt, cc_out); // Update UE state for (auto& u : ue_db) { @@ -198,7 +251,7 @@ void sched_nr_sim_base::process_results() } } -int sched_nr_sim_base::set_default_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_slot_events& pending_events) +int sched_nr_base_tester::set_default_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_slot_events& pending_events) { pending_events.cc_list.clear(); pending_events.cc_list.resize(cell_params.size()); @@ -229,7 +282,7 @@ int sched_nr_sim_base::set_default_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, return SRSRAN_SUCCESS; } -int sched_nr_sim_base::apply_slot_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_nr_slot_events& events) +int sched_nr_base_tester::apply_slot_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_nr_slot_events& events) { for (uint32_t enb_cc_idx = 0; enb_cc_idx < events.cc_list.size(); ++enb_cc_idx) { const auto& cc_feedback = events.cc_list[enb_cc_idx]; @@ -273,7 +326,7 @@ int sched_nr_sim_base::apply_slot_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_nr_ return SRSRAN_SUCCESS; } -sim_nr_enb_ctxt_t sched_nr_sim_base::get_enb_ctxt() const +sim_nr_enb_ctxt_t sched_nr_base_tester::get_enb_ctxt() const { sim_nr_enb_ctxt_t ctxt; ctxt.cell_params = cell_params; @@ -285,76 +338,4 @@ sim_nr_enb_ctxt_t sched_nr_sim_base::get_enb_ctxt() const return ctxt; } -} // namespace detail - -void sched_nr_sim::new_slot(slot_point slot_tx) -{ - current_slot_tx = slot_tx; - nof_cc_remaining = cell_params.size(); - this->new_slot_(slot_tx); -} - -void sched_nr_sim::generate_cc_result(uint32_t cc) -{ - // Run scheduler - this->generate_cc_result_(cc); - - if (--nof_cc_remaining > 0) { - // there are still missing CC results - return; - } - - // Run tests and update UE state - this->process_results(); -} - -void sched_nr_sim_parallel::new_slot(slot_point slot_tx) -{ - // Block concurrent or out-of-order calls to the scheduler - { - std::unique_lock lock(mutex); - while (nof_cc_remaining > 0 or (current_slot_tx.valid() and current_slot_tx + 1 != slot_tx)) { - cvar.wait(lock); - } - current_slot_tx = slot_tx; - nof_cc_remaining = cell_params.size(); - } - - // Run common new_slot updates - this->new_slot_(slot_tx); -} - -void sched_nr_sim_parallel::generate_cc_result(uint32_t cc) -{ - // Run scheduler - this->generate_cc_result_(cc); - - { - std::unique_lock lock(mutex); - if (--nof_cc_remaining > 0) { - // there are still missing CC results - return; - } - - // Run tests and update UE state - this->process_results(); - } - - // Notify waiting workers - cvar.notify_one(); -} - -sched_nr_sim_parallel::~sched_nr_sim_parallel() -{ - stop(); -} - -void sched_nr_sim_parallel::stop() -{ - std::unique_lock lock(mutex); - while (nof_cc_remaining > 0) { - cvar.wait(lock); - } -} - } // namespace srsenb \ No newline at end of file diff --git a/srsenb/test/mac/nr/sched_nr_sim_ue.h b/srsenb/test/mac/nr/sched_nr_sim_ue.h index 47f360a83..1c62b20e5 100644 --- a/srsenb/test/mac/nr/sched_nr_sim_ue.h +++ b/srsenb/test/mac/nr/sched_nr_sim_ue.h @@ -17,6 +17,11 @@ #include "srsenb/hdr/stack/mac/nr/sched_nr.h" #include "srsran/adt/circular_array.h" #include +#include + +namespace srsran { +class task_worker; +} namespace srsenb { @@ -98,10 +103,8 @@ private: sim_nr_ue_ctxt_t ctxt; }; -namespace detail { - /// Implementation of features common to sched_nr_sim_parallel and sched_nr_sim -class sched_nr_sim_base +class sched_nr_base_tester { public: struct cc_result_t { @@ -109,13 +112,17 @@ public: uint32_t cc; sched_nr_interface::dl_sched_res_t dl_res; sched_nr_interface::ul_sched_t ul_res; - std::chrono::nanoseconds sched_latency_ns; + std::chrono::nanoseconds cc_latency_ns; }; - sched_nr_sim_base(const sched_nr_interface::sched_args_t& sched_args, - const std::vector& cell_params_, - std::string test_name); - virtual ~sched_nr_sim_base(); + sched_nr_base_tester(const sched_nr_interface::sched_args_t& sched_args, + const std::vector& cell_params_, + std::string test_name, + uint32_t nof_workers = 1); + virtual ~sched_nr_base_tester(); + + void run_slot(slot_point slot_tx); + void stop(); int add_user(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg_, slot_point tti_rx, uint32_t preamble_idx); @@ -125,11 +132,10 @@ public: virtual void set_external_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_slot_events& pending_events) {} // configurable by simulator concrete implementation - virtual void process_cc_result(const cc_result_t& cc_out) {} + virtual void process_slot_result(const sim_nr_enb_ctxt_t& enb_ctxt, srsran::const_span cc_out) {} protected: - void new_slot_(slot_point slot_tx); - void generate_cc_result_(uint32_t cc); + void generate_cc_result(uint32_t cc); sim_nr_enb_ctxt_t get_enb_ctxt() const; int set_default_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_slot_events& pending_events); @@ -144,77 +150,19 @@ protected: std::unique_ptr sched_ptr; std::vector cell_params; - uint32_t nof_cc_remaining = 0; - slot_point current_slot_tx; - std::vector cc_results; + std::vector > cc_workers; std::map ue_db; -}; -} // namespace detail - -class sched_nr_sim_parallel : public detail::sched_nr_sim_base -{ - using base_t = detail::sched_nr_sim_base; - -public: - using base_t::base_t; - ~sched_nr_sim_parallel(); - - void stop(); - - int add_user(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg_, slot_point tti_rx, uint32_t preamble_idx) - { - std::lock_guard lock(mutex); - return base_t::add_user(rnti, ue_cfg_, tti_rx, preamble_idx); - } - slot_point get_slot_tx() const - { - std::lock_guard lock(mutex); - return current_slot_tx; - } - - void new_slot(slot_point slot_tx); - void generate_cc_result(uint32_t cc); - -private: - mutable std::mutex mutex; - std::condition_variable cvar; -}; - -class sched_nr_sim : public detail::sched_nr_sim_base -{ - using base_t = detail::sched_nr_sim_base; - -public: - using sched_nr_sim_base::sched_nr_sim_base; - - void new_slot(slot_point slot_tx); - void generate_cc_result(uint32_t cc); - - sched_nr_ue_sim& at(uint16_t rnti) { return ue_db.at(rnti); } - const sched_nr_ue_sim& at(uint16_t rnti) const { return ue_db.at(rnti); } - sched_nr_ue_sim* find_rnti(uint16_t rnti) - { - auto it = ue_db.find(rnti); - return it != ue_db.end() ? &it->second : nullptr; - } - const sched_nr_ue_sim* find_rnti(uint16_t rnti) const - { - auto it = ue_db.find(rnti); - return it != ue_db.end() ? &it->second : nullptr; - } - const sched_nr_interface::ue_cfg_t* get_user_cfg(uint16_t rnti) const - { - const sched_nr_ue_sim* ret = find_rnti(rnti); - return ret == nullptr ? nullptr : &ret->get_ctxt().ue_cfg; - } - bool user_exists(uint16_t rnti) const { return ue_db.count(rnti) > 0; } - sched_nr* get_sched() { return sched_ptr.get(); } - std::map::iterator begin() { return ue_db.begin(); } - std::map::iterator end() { return ue_db.end(); } + // slot-specific + slot_point current_slot_tx; + std::chrono::steady_clock::time_point slot_start_tp; + sim_nr_enb_ctxt_t slot_ctxt; + std::vector cc_results; - slot_point get_slot_tx() const { return current_slot_tx; } + std::atomic stopped{false}; + mutable sem_t slot_sem; + std::atomic nof_cc_remaining{0}; }; } // namespace srsenb diff --git a/srsenb/test/mac/nr/sched_nr_test.cc b/srsenb/test/mac/nr/sched_nr_test.cc index 1cd6f18b0..0f36b9c42 100644 --- a/srsenb/test/mac/nr/sched_nr_test.cc +++ b/srsenb/test/mac/nr/sched_nr_test.cc @@ -14,7 +14,6 @@ #include "sched_nr_sim_ue.h" #include "srsran/common/phy_cfg_nr_default.h" #include "srsran/common/test_common.h" -#include "srsran/common/thread_pool.h" #include namespace srsenb { @@ -24,38 +23,45 @@ using dl_sched_t = sched_nr_interface::dl_sched_t; static const srsran::phy_cfg_nr_t default_phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}}; -class sched_nr_tester : public sched_nr_sim_parallel +class sched_nr_tester : public sched_nr_base_tester { public: - using sched_nr_sim_parallel::sched_nr_sim_parallel; + using sched_nr_base_tester::sched_nr_base_tester; - void process_cc_result(const cc_result_t& cc_result) override + void process_slot_result(const sim_nr_enb_ctxt_t& slot_ctxt, srsran::const_span cc_list) override { - tot_latency_sched_ns += cc_result.sched_latency_ns.count(); - result_count++; - pdsch_count += cc_result.dl_res.dl_sched.pdcch_dl.size(); - - TESTASSERT(cc_result.dl_res.dl_sched.pdcch_dl.size() <= 1); - if (srsran_duplex_nr_is_dl(&cell_params[cc_result.cc].cfg.duplex, 0, current_slot_tx.slot_idx())) { - TESTASSERT(cc_result.dl_res.dl_sched.pdcch_dl.size() == 1 or not cc_result.dl_res.dl_sched.ssb.empty()); + tot_latency_sched_ns += + std::max_element(cc_list.begin(), cc_list.end(), [](const cc_result_t& lhs, const cc_result_t& rhs) { + return lhs.cc_latency_ns < rhs.cc_latency_ns; + })->cc_latency_ns.count(); + + for (auto& cc_out : cc_list) { + pdsch_count += cc_out.dl_res.dl_sched.pdcch_dl.size(); + cc_res_count++; + + TESTASSERT(cc_out.dl_res.dl_sched.pdcch_dl.size() <= 1); + if (srsran_duplex_nr_is_dl(&cell_params[cc_out.cc].cfg.duplex, 0, current_slot_tx.slot_idx())) { + TESTASSERT(cc_out.dl_res.dl_sched.pdcch_dl.size() == 1 or not cc_out.dl_res.dl_sched.ssb.empty()); + } } } void print_results() const { - test_logger.info("TESTER: %f PDSCH/{slot,cc} were allocated", pdsch_count / (double)result_count); + test_logger.info("TESTER: %f PDSCH/{slot,cc} were allocated", pdsch_count / (double)cc_res_count); srslog::flush(); } srslog::basic_logger& test_logger = srslog::fetch_basic_logger("TEST"); uint64_t tot_latency_sched_ns = 0; - uint32_t result_count = 0; + uint32_t cc_res_count = 0; uint32_t pdsch_count = 0; }; -void sched_nr_cfg_serialized_test() +void run_sched_nr_test(uint32_t nof_workers) { + srsran_assert(nof_workers > 0, "There must be at least one worker"); uint32_t max_nof_ttis = 1000, nof_sectors = 4; uint16_t rnti = 0x4601; @@ -64,7 +70,11 @@ void sched_nr_cfg_serialized_test() std::vector cells_cfg = get_default_cells_cfg(nof_sectors); - sched_nr_tester tester(cfg, cells_cfg, "Serialized Test"); + std::string test_name = "Serialized Test"; + if (nof_workers > 1) { + test_name = fmt::format("Parallel Test with {} workers", nof_workers); + } + sched_nr_tester tester(cfg, cells_cfg, test_name, nof_workers); sched_nr_interface::ue_cfg_t uecfg = get_default_ue_cfg(nof_sectors); tester.add_user(rnti, uecfg, slot_point{0, 0}, 0); @@ -72,10 +82,7 @@ void sched_nr_cfg_serialized_test() for (uint32_t nof_slots = 0; nof_slots < max_nof_ttis; ++nof_slots) { slot_point slot_rx(0, nof_slots % 10240); slot_point slot_tx = slot_rx + TX_ENB_DELAY; - tester.new_slot(slot_tx); - for (uint32_t cc = 0; cc != cells_cfg.size(); ++cc) { - tester.generate_cc_result(cc); - } + tester.run_slot(slot_tx); } tester.stop(); @@ -87,68 +94,21 @@ void sched_nr_cfg_serialized_test() printf("Total time taken per slot: %f usec\n", final_avg_usec); } -void sched_nr_cfg_parallel_cc_test() -{ - uint32_t nof_sectors = 4; - uint32_t max_nof_ttis = 1000; - uint16_t rnti = 0x4601; - - // Initiate CC Workers - std::vector > cc_workers; - cc_workers.reserve(nof_sectors - 1); - for (uint32_t i = 0; i < nof_sectors - 1; ++i) { - fmt::memory_buffer fmtbuf; - fmt::format_to(fmtbuf, "worker{}", i); - cc_workers.emplace_back(new srsran::task_worker{to_string(fmtbuf), 10}); - } - - sched_nr_interface::sched_args_t cfg; - cfg.auto_refill_buffer = true; - - std::vector cells_cfg = get_default_cells_cfg(nof_sectors); - - sched_nr_tester tester(cfg, cells_cfg, "Parallel CC Test"); - - sched_nr_interface::ue_cfg_t uecfg = get_default_ue_cfg(cells_cfg.size()); - tester.add_user(rnti, uecfg, slot_point{0, 0}, 0); - - for (uint32_t nof_slots = 0; nof_slots < max_nof_ttis; ++nof_slots) { - slot_point slot_rx(0, nof_slots % 10240); - slot_point slot_tx = slot_rx + TX_ENB_DELAY; - tester.new_slot(slot_tx); - // Run scheduler in parallel for {0, cc-2} and in the same thread for last cc - for (uint32_t cc = 0; cc != cells_cfg.size() - 1; ++cc) { - cc_workers[cc]->push_task([cc, &tester]() { tester.generate_cc_result(cc); }); - } - tester.generate_cc_result(cells_cfg.size() - 1); - } - - // Wait for all jobs to finish - tester.stop(); - - tester.print_results(); - - // TESTASSERT(tasks.pdsch_count == (int)(max_nof_ttis * nof_sectors * 0.6)); - - double final_avg_usec = tester.tot_latency_sched_ns; - final_avg_usec = final_avg_usec / 1000.0 / max_nof_ttis / nof_sectors; - printf("Total time taken per slot [usec]: %f\n", final_avg_usec); -} - } // namespace srsenb int main() { auto& test_logger = srslog::fetch_basic_logger("TEST"); - test_logger.set_level(srslog::basic_levels::error); + test_logger.set_level(srslog::basic_levels::warning); auto& mac_nr_logger = srslog::fetch_basic_logger("MAC-NR"); - mac_nr_logger.set_level(srslog::basic_levels::error); + mac_nr_logger.set_level(srslog::basic_levels::warning); auto& pool_logger = srslog::fetch_basic_logger("POOL"); pool_logger.set_level(srslog::basic_levels::debug); // Start the log backend. srslog::init(); - srsenb::sched_nr_cfg_serialized_test(); - srsenb::sched_nr_cfg_parallel_cc_test(); + srsenb::run_sched_nr_test(1); + srsenb::run_sched_nr_test(2); + srsenb::run_sched_nr_test(4); } From 1068a84bd0e6ddddbfb25aa55e88928424bf07db Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 13 Oct 2021 09:20:32 +0200 Subject: [PATCH 138/208] sync: fix typo --- srsue/hdr/phy/sync.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/hdr/phy/sync.h b/srsue/hdr/phy/sync.h index 97b3c91d7..cb41e41a6 100644 --- a/srsue/hdr/phy/sync.h +++ b/srsue/hdr/phy/sync.h @@ -259,7 +259,7 @@ private: search::ret_code cell_search_ret = search::CELL_NOT_FOUND; - // Sampling rate mode (find is 1.96 MHz, camp is the full cell BW) + // Sampling rate mode (find is 1.92 MHz, camp is the full cell BW) class srate_safe { public: From 908c469f3049005d721d516b6b6f3d80cf268ee7 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 13 Oct 2021 09:20:43 +0200 Subject: [PATCH 139/208] sync: don't fail camping on cell if current and target srate match this fixes #3437. The check/requirement for target srate to be different to current srate isn't needed, and in fact fails for 6 PRBs where both are indentical always. --- srsue/hdr/phy/sync.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/hdr/phy/sync.h b/srsue/hdr/phy/sync.h index cb41e41a6..677ac6a1f 100644 --- a/srsue/hdr/phy/sync.h +++ b/srsue/hdr/phy/sync.h @@ -282,7 +282,7 @@ private: bool set_camp(float new_srate) { std::lock_guard lock(mutex); - if (current_srate != new_srate || srate_mode != SRATE_CAMP) { + if (srate_mode != SRATE_CAMP) { current_srate = new_srate; srate_mode = SRATE_CAMP; return true; From 255ddb1329b2a61748e83437bf4aa39f0379d912 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 14 Oct 2021 17:43:09 +0200 Subject: [PATCH 140/208] enb,gnb: add basic support for sgnb release procedure the procedure is currently started when the EUTRA UE object is deleted (after RRC release) in order to clean-up the ENDC resources on the gNB. --- .../srsran/interfaces/enb_x2_interfaces.h | 10 ++++++ srsenb/hdr/stack/enb_stack_lte.h | 1 + srsenb/hdr/stack/gnb_stack_nr.h | 1 + srsenb/hdr/stack/rrc/rrc.h | 1 + srsenb/hdr/stack/rrc/rrc_endc.h | 36 +++++++++++++++++-- srsenb/hdr/stack/rrc/rrc_nr.h | 1 + srsenb/hdr/x2_adapter.h | 16 +++++++++ srsenb/src/stack/rrc/rrc.cc | 34 +++++++++++++++--- srsenb/src/stack/rrc/rrc_endc.cc | 20 +++++++++++ srsenb/src/stack/rrc/rrc_nr.cc | 10 ++++++ 10 files changed, 123 insertions(+), 7 deletions(-) diff --git a/lib/include/srsran/interfaces/enb_x2_interfaces.h b/lib/include/srsran/interfaces/enb_x2_interfaces.h index 5d3b871dc..367fa7d9a 100644 --- a/lib/include/srsran/interfaces/enb_x2_interfaces.h +++ b/lib/include/srsran/interfaces/enb_x2_interfaces.h @@ -40,6 +40,9 @@ public: /// 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; + + /// Trigger release for specific UE + virtual int sgnb_release_request(uint16_t nr_rnti) = 0; }; /// X2AP inspired interface for response from NR RRC to EUTRA RRC @@ -82,6 +85,13 @@ public: */ virtual void sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_rnti) = 0; + /** + * @brief Signal release of all UE resources on the NR cell + * + * @param eutra_rnti The RNTI that the EUTRA RRC used to request the SgNB addition + */ + virtual void sgnb_release_ack(uint16_t eutra_rnti) = 0; + /** * @brief Signal user activity (i.e. DL/UL traffic) for given RNTI * diff --git a/srsenb/hdr/stack/enb_stack_lte.h b/srsenb/hdr/stack/enb_stack_lte.h index cb5053f46..ef7544697 100644 --- a/srsenb/hdr/stack/enb_stack_lte.h +++ b/srsenb/hdr/stack/enb_stack_lte.h @@ -126,6 +126,7 @@ 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); } // 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 2161b8ca9..3ae39545f 100644 --- a/srsenb/hdr/stack/gnb_stack_nr.h +++ b/srsenb/hdr/stack/gnb_stack_nr.h @@ -89,6 +89,7 @@ public: { return rrc.sgnb_reconfiguration_complete(eutra_rnti, reconfig_response); }; + int sgnb_release_request(uint16_t nr_rnti) final { 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 { diff --git a/srsenb/hdr/stack/rrc/rrc.h b/srsenb/hdr/stack/rrc/rrc.h index 25ee18bb2..5a1c2adb3 100644 --- a/srsenb/hdr/stack/rrc/rrc.h +++ b/srsenb/hdr/stack/rrc/rrc.h @@ -131,6 +131,7 @@ public: void sgnb_addition_ack(uint16_t eutra_rnti, const sgnb_addition_ack_params_t params) override; void sgnb_addition_reject(uint16_t eutra_rnti) override; void sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_rnti) override; + void sgnb_release_ack(uint16_t eutra_rnti) override; // rrc_interface_pdcp void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) override; diff --git a/srsenb/hdr/stack/rrc/rrc_endc.h b/srsenb/hdr/stack/rrc/rrc_endc.h index 3f82acb10..9d41171ab 100644 --- a/srsenb/hdr/stack/rrc/rrc_endc.h +++ b/srsenb/hdr/stack/rrc/rrc_endc.h @@ -49,12 +49,30 @@ public: uint16_t nr_rnti; /// RNTI assigned to UE on NR carrier }; + /** + * @brief Called from EUTRA-RRC when EN-DC (for UE) shall be removed/released + * + */ + struct sgnb_rel_req_ev { + uint16_t nr_rnti; /// RNTI assigned to UE on NR carrier + }; + + /** + * @brief Event sent from NR-RRC to EUTRA when UE has been removed from SgNB + * + * sent in response to SgNB Release Request + */ + struct sgnb_rel_req_ack_ev {}; + rrc_endc(srsenb::rrc::ue* outer_ue, const rrc_endc_cfg_t& endc_cfg_); + ~rrc_endc(); bool fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_recfg); void handle_eutra_capabilities(const asn1::rrc::ue_eutra_cap_s& eutra_caps); void handle_ue_meas_report(const asn1::rrc::meas_report_s& msg); + void start_sgnb_release(); + bool is_endc_supported(); private: @@ -70,6 +88,7 @@ private: // vars bool endc_supported = false; rrc_endc_cfg_t endc_cfg = {}; + uint16_t nr_rnti = SRSRAN_INVALID_RNTI; // C-RNTI assigned to UE on NR side asn1::rrc::rrc_conn_recfg_complete_s pending_recfg_complete; // fixed ENDC variables @@ -94,22 +113,30 @@ private: }; struct wait_add_complete_st {}; // user needs to complete RA procedure and send C-RNTI CE struct endc_activated_st {}; // user has enabled EN-DC successfully and is currently served + struct wait_sgnb_rel_req_resp_st {}; // release EN-DC // FSM guards // FSM transition handlers void handle_sgnb_add_req_ack(wait_sgnb_add_req_resp_st& s, const sgnb_add_req_ack_ev& ev); + void handle_sgnb_rel_req(endc_activated_st& s, const sgnb_rel_req_ev& ev); void handle_rrc_reest(wait_add_complete_st& s, const rrc_reest_rx_ev& ev); protected: // states - state_list + state_list states{this, endc_deactivated_st{}, wait_sgnb_add_req_resp_st{}, prepare_recfg_st{this}, wait_add_complete_st{}, - endc_activated_st{}}; + endc_activated_st{}, + wait_sgnb_rel_req_resp_st{}}; // transitions using fsm = rrc_endc; @@ -123,8 +150,11 @@ protected: row< wait_sgnb_add_req_resp_st, endc_deactivated_st, sgnb_add_req_reject_ev >, row< prepare_recfg_st, wait_add_complete_st, rrc_recfg_sent_ev >, row< wait_add_complete_st, endc_activated_st, sgnb_add_complete_ev >, - row< wait_add_complete_st, endc_deactivated_st, rrc_reest_rx_ev, &fsm::handle_rrc_reest > + row< wait_add_complete_st, endc_deactivated_st, rrc_reest_rx_ev, &fsm::handle_rrc_reest >, // +---------------------------+--------------------------+------------------------+------------------------------+-------------------------+ + row< endc_activated_st, wait_sgnb_rel_req_resp_st, sgnb_rel_req_ev, &fsm::handle_sgnb_rel_req >, + row< wait_sgnb_rel_req_resp_st, endc_deactivated_st, sgnb_rel_req_ack_ev > + >; // clang-format on }; diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 5341bbbb9..394a657f8 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -88,6 +88,7 @@ public: // 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); // 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 df5d0f8c8..30c619dee 100644 --- a/srsenb/hdr/x2_adapter.h +++ b/srsenb/hdr/x2_adapter.h @@ -80,6 +80,14 @@ public: eutra_stack->sgnb_addition_complete(eutra_rnti, nr_rnti); } + void sgnb_release_ack(uint16_t eutra_rnti) override + { + if (eutra_stack == nullptr) { + return; + } + eutra_stack->sgnb_release_ack(eutra_rnti); + } + void set_activity_user(uint16_t eutra_rnti) override { if (eutra_stack == nullptr) { @@ -88,6 +96,14 @@ public: eutra_stack->set_activity_user(eutra_rnti); } + int sgnb_release_request(uint16_t nr_rnti) override + { + if (nr_stack == nullptr) { + return SRSRAN_ERROR; + } + return nr_stack->sgnb_release_request(nr_rnti); + } + // pdcp_interface_gtpu void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu, int pdcp_sn = -1) override { diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index 9e478f8ca..f4fbd6245 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -570,22 +570,48 @@ void rrc::set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_st void rrc::sgnb_addition_ack(uint16_t eutra_rnti, sgnb_addition_ack_params_t params) { logger.info("Received SgNB addition acknowledgement for rnti=%d", eutra_rnti); - users.at(eutra_rnti)->endc_handler->trigger(ue::rrc_endc::sgnb_add_req_ack_ev{params}); + auto ue_it = users.find(eutra_rnti); + if (ue_it == users.end()) { + logger.warning("rnti=0x%x does not exist", eutra_rnti); + return; + } + ue_it->second->endc_handler->trigger(ue::rrc_endc::sgnb_add_req_ack_ev{params}); // trigger RRC Reconfiguration to send NR config to UE - users.at(eutra_rnti)->send_connection_reconf(); + ue_it->second->send_connection_reconf(); } void rrc::sgnb_addition_reject(uint16_t eutra_rnti) { logger.error("Received SgNB addition reject for rnti=%d", eutra_rnti); - users.at(eutra_rnti)->endc_handler->trigger(ue::rrc_endc::sgnb_add_req_reject_ev{}); + auto ue_it = users.find(eutra_rnti); + if (ue_it == users.end()) { + logger.warning("rnti=0x%x does not exist", eutra_rnti); + return; + } + ue_it->second->endc_handler->trigger(ue::rrc_endc::sgnb_add_req_reject_ev{}); } void rrc::sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_rnti) { logger.info("User rnti=0x%x successfully enabled EN-DC", eutra_rnti); - users.at(eutra_rnti)->endc_handler->trigger(ue::rrc_endc::sgnb_add_complete_ev{nr_rnti}); + auto ue_it = users.find(eutra_rnti); + if (ue_it == users.end()) { + logger.warning("rnti=0x%x does not exist", eutra_rnti); + return; + } + ue_it->second->endc_handler->trigger(ue::rrc_endc::sgnb_add_complete_ev{nr_rnti}); +} + +void rrc::sgnb_release_ack(uint16_t eutra_rnti) +{ + logger.info("Received SgNB release acknowledgement for rnti=%d", eutra_rnti); + auto ue_it = users.find(eutra_rnti); + if (ue_it == users.end()) { + logger.warning("rnti=0x%x does not exist", eutra_rnti); + return; + } + ue_it->second->endc_handler->trigger(ue::rrc_endc::sgnb_rel_req_ack_ev{}); } /******************************************************************************* diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index ae6a720d8..a0b16707a 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -42,6 +42,11 @@ rrc::ue::rrc_endc::rrc_endc(rrc::ue* outer_ue, const rrc_endc_cfg_t& endc_cfg_) } } +rrc::ue::rrc_endc::~rrc_endc() +{ + start_sgnb_release(); +} + //! Method to add NR fields to a RRC Connection Reconfiguration Message bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_recfg) { @@ -285,6 +290,12 @@ void rrc::ue::rrc_endc::start_sgnb_addition() trigger(sgnb_add_req); } +void rrc::ue::rrc_endc::start_sgnb_release() +{ + sgnb_rel_req_ev sgnb_rel_req{nr_rnti}; + trigger(sgnb_rel_req); +} + rrc::ue::rrc_endc::prepare_recfg_st::prepare_recfg_st(rrc_endc* parent_) : logger(parent_->logger) {} void rrc::ue::rrc_endc::prepare_recfg_st::enter(rrc_endc* f, const sgnb_add_req_ack_ev& ev) @@ -313,6 +324,15 @@ void rrc::ue::rrc_endc::handle_sgnb_add_req_ack(wait_sgnb_add_req_resp_st& s, co // change GTPU tunnel RNTI to match NR RNTI rrc_enb->gtpu->mod_bearer_rnti(rrc_ue->rnti, ev.params.nr_rnti); + + // store RNTI for later + nr_rnti = ev.params.nr_rnti; +} + +void rrc::ue::rrc_endc::handle_sgnb_rel_req(endc_activated_st& s, const sgnb_rel_req_ev& ev) +{ + logger.info("Triggering SgNB release"); + rrc_enb->rrc_nr->sgnb_release_request(nr_rnti); } bool rrc::ue::rrc_endc::is_endc_supported() diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index d107e3afe..e496b01b2 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -511,6 +511,16 @@ int rrc_nr::sgnb_reconfiguration_complete(uint16_t eutra_rnti, asn1::dyn_octstri return SRSRAN_SUCCESS; } +int rrc_nr::sgnb_release_request(uint16_t nr_rnti) +{ + task_sched.defer_task([this, nr_rnti]() { + // remove user + rem_user(nr_rnti); + rrc_eutra->sgnb_release_ack(nr_rnti); + }); + return SRSRAN_SUCCESS; +} + /******************************************************************************* UE class From 9df6c6b9367431fa7984613b0749c042e6de1be7 Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 14 Oct 2021 16:45:18 +0100 Subject: [PATCH 141/208] sched,nr: ensure the ue_cfg_t passed to the scheduler in NR FDD mode has the correct harq delay --- .../srsran/interfaces/gnb_interfaces.h | 8 ++++-- .../srsran/interfaces/gnb_mac_interfaces.h | 2 +- srsenb/hdr/stack/mac/nr/mac_nr.h | 2 +- srsenb/hdr/stack/mac/nr/sched_nr_interface.h | 25 +++++++++-------- srsenb/hdr/stack/rrc/rrc_nr.h | 4 +-- srsenb/src/stack/mac/nr/mac_nr.cc | 28 +++++++++++-------- srsenb/src/stack/rrc/rrc_nr.cc | 24 ++++++++++++---- srsenb/test/common/dummy_classes_nr.h | 4 +-- test/phy/dummy_gnb_stack.h | 5 ++-- 9 files changed, 63 insertions(+), 39 deletions(-) diff --git a/lib/include/srsran/interfaces/gnb_interfaces.h b/lib/include/srsran/interfaces/gnb_interfaces.h index 48ab3d340..c3c5bc3f1 100644 --- a/lib/include/srsran/interfaces/gnb_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_interfaces.h @@ -27,6 +27,8 @@ namespace srsenb { +struct sched_nr_ue_cfg_t; + /***************************** * RLC INTERFACES ****************************/ @@ -134,9 +136,9 @@ public: virtual int read_pdu_bcch_dlsch(uint32_t sib_index, srsran::unique_byte_buffer_t& buffer) = 0; /// User management - virtual int add_user(uint16_t rnti) = 0; - virtual int update_user(uint16_t new_rnti, uint16_t old_rnti) = 0; - virtual void set_activity_user(uint16_t rnti) = 0; + virtual int add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg) = 0; + virtual int update_user(uint16_t new_rnti, uint16_t old_rnti) = 0; + virtual void set_activity_user(uint16_t rnti) = 0; }; // NR interface is almost identical to EUTRA version diff --git a/lib/include/srsran/interfaces/gnb_mac_interfaces.h b/lib/include/srsran/interfaces/gnb_mac_interfaces.h index 482909617..bd1f29136 100644 --- a/lib/include/srsran/interfaces/gnb_mac_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_mac_interfaces.h @@ -24,7 +24,7 @@ public: virtual int cell_cfg(const std::vector& nr_cells) = 0; /// Allocates a new user/RNTI at MAC. Returns RNTI on success or SRSRAN_INVALID_RNTI otherwise. - virtual uint16_t reserve_rnti(uint32_t enb_cc_idx) = 0; + virtual uint16_t reserve_rnti(uint32_t enb_cc_idx, const sched_nr_interface::ue_cfg_t& uecfg) = 0; virtual int ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) = 0; diff --git a/srsenb/hdr/stack/mac/nr/mac_nr.h b/srsenb/hdr/stack/mac/nr/mac_nr.h index e11a0e32f..33f0d08de 100644 --- a/srsenb/hdr/stack/mac/nr/mac_nr.h +++ b/srsenb/hdr/stack/mac/nr/mac_nr.h @@ -53,7 +53,7 @@ public: // MAC interface for RRC int cell_cfg(const std::vector& nr_cells) override; - uint16_t reserve_rnti(uint32_t enb_cc_idx) override; + uint16_t reserve_rnti(uint32_t enb_cc_idx, const sched_nr_interface::ue_cfg_t& uecfg) override; int read_pdu_bcch_bch(uint8_t* payload); int ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) override; int remove_ue(uint16_t rnti) override; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index c3a6f0551..46f70270f 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -33,6 +33,18 @@ const static size_t SCHED_NR_MAX_BWP_PER_CELL = 2; const static size_t SCHED_NR_MAX_LCID = 32; const static size_t SCHED_NR_MAX_LC_GROUP = 7; +struct sched_nr_ue_cc_cfg_t { + bool active = false; + uint32_t cc = 0; +}; + +struct sched_nr_ue_cfg_t { + uint32_t maxharq_tx = 4; + srsran::bounded_vector carriers; + std::array ue_bearers = {}; + srsran::phy_cfg_nr_t phy_cfg = {}; +}; + class sched_nr_interface { public: @@ -76,17 +88,8 @@ public: std::string logger_name = "MAC-NR"; }; - struct ue_cc_cfg_t { - bool active = false; - uint32_t cc = 0; - }; - - struct ue_cfg_t { - uint32_t maxharq_tx = 4; - srsran::bounded_vector carriers; - std::array ue_bearers = {}; - srsran::phy_cfg_nr_t phy_cfg = {}; - }; + using ue_cc_cfg_t = sched_nr_ue_cc_cfg_t; + using ue_cfg_t = sched_nr_ue_cfg_t; ////// RA procedure ////// diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 394a657f8..8f2ff2316 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -69,7 +69,7 @@ public: int read_pdu_bcch_dlsch(uint32_t sib_index, srsran::unique_byte_buffer_t& buffer) final; /// User manegement - int add_user(uint16_t rnti); + int add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg); void rem_user(uint16_t rnti); int update_user(uint16_t new_rnti, uint16_t old_rnti); void set_activity_user(uint16_t rnti); @@ -104,7 +104,7 @@ public: class ue { public: - ue(rrc_nr* parent_, uint16_t rnti_); + ue(rrc_nr* parent_, uint16_t rnti_, const sched_nr_ue_cfg_t& uecfg); void send_connection_setup(); void send_dl_ccch(asn1::rrc_nr::dl_ccch_msg_s* dl_dcch_msg); diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 6d5411286..23c59c594 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -136,21 +136,13 @@ int mac_nr::ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) return SRSRAN_SUCCESS; } -uint16_t mac_nr::reserve_rnti(uint32_t enb_cc_idx) +uint16_t mac_nr::reserve_rnti(uint32_t enb_cc_idx, const sched_nr_ue_cfg_t& uecfg) { uint16_t rnti = alloc_ue(enb_cc_idx); if (rnti == SRSRAN_INVALID_RNTI) { return rnti; } - // Add new user to the scheduler so that it can RX/TX SRB0 - srsenb::sched_nr_interface::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; - uecfg.phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}}; - uecfg.phy_cfg.csi = {}; // disable CSI until RA is complete sched.ue_cfg(rnti, uecfg); return rnti; @@ -165,7 +157,21 @@ void mac_nr::rach_detected(const rach_info_t& rach_info) uint32_t enb_cc_idx = 0; stack_task_queue.push([this, rach_info, enb_cc_idx, rach_tprof_meas]() mutable { rach_tprof_meas.defer_stop(); - uint16_t rnti = reserve_rnti(enb_cc_idx); + + // Add new user to the scheduler so that it can RX/TX SRB0 + 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 = cell_config[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 rnti = reserve_rnti(enb_cc_idx, uecfg); // Log this event. ++detected_rachs[enb_cc_idx]; @@ -178,7 +184,7 @@ void mac_nr::rach_detected(const rach_info_t& rach_info) rar_info.prach_slot = slot_point{NUMEROLOGY_IDX, rach_info.slot_index}; // TODO: fill remaining fields as required sched.dl_rach_info(enb_cc_idx, rar_info); - rrc->add_user(rnti); + rrc->add_user(rnti, uecfg); logger.info("RACH: slot=%d, cc=%d, preamble=%d, offset=%d, temp_crnti=0x%x", rach_info.slot_index, diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index e496b01b2..10e1a6904 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -145,10 +145,10 @@ rrc_nr_cfg_t rrc_nr::update_default_cfg(const rrc_nr_cfg_t& current) } // This function is called from PRACH worker (can wait) -int rrc_nr::add_user(uint16_t rnti) +int rrc_nr::add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg) { if (users.count(rnti) == 0) { - users.insert(std::make_pair(rnti, std::unique_ptr(new ue(this, rnti)))); + users.insert(std::make_pair(rnti, std::unique_ptr(new ue(this, rnti, uecfg)))); rlc->add_user(rnti); pdcp->add_user(rnti); logger.info("Added new user rnti=0x%x", rnti); @@ -478,14 +478,26 @@ int rrc_nr::sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_p { task_sched.defer_task([this, eutra_rnti, params]() { // try to allocate new user - uint16_t nr_rnti = mac->reserve_rnti(0); + 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) != SRSRAN_SUCCESS) { + if (add_user(nr_rnti, uecfg) != SRSRAN_SUCCESS) { logger.error("Failed to allocate RNTI at RRC"); rrc_eutra->sgnb_addition_reject(eutra_rnti); return; @@ -527,7 +539,9 @@ int rrc_nr::sgnb_release_request(uint16_t nr_rnti) Every function in UE class is called from a mutex environment thus does not need extra protection. *******************************************************************************/ -rrc_nr::ue::ue(rrc_nr* parent_, uint16_t rnti_) : parent(parent_), rnti(rnti_), uecfg(srsenb::get_rach_ue_cfg(0)) {} +rrc_nr::ue::ue(rrc_nr* parent_, uint16_t rnti_, const sched_nr_ue_cfg_t& uecfg_) : + parent(parent_), rnti(rnti_), uecfg(uecfg_) +{} void rrc_nr::ue::send_connection_setup() { diff --git a/srsenb/test/common/dummy_classes_nr.h b/srsenb/test/common/dummy_classes_nr.h index 2148aa810..018599afa 100644 --- a/srsenb/test/common/dummy_classes_nr.h +++ b/srsenb/test/common/dummy_classes_nr.h @@ -23,7 +23,7 @@ class rrc_nr_dummy : public rrc_interface_mac_nr public: int read_pdu_bcch_bch(const uint32_t tti, srsran::unique_byte_buffer_t& buffer) { return SRSRAN_SUCCESS; } int read_pdu_bcch_dlsch(uint32_t sib_index, srsran::unique_byte_buffer_t& buffer) { return SRSRAN_SUCCESS; } - int add_user(uint16_t rnti) { return SRSRAN_SUCCESS; } + int add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg) { return SRSRAN_SUCCESS; } int update_user(uint16_t new_rnti, uint16_t old_rnti) { return SRSRAN_SUCCESS; } void set_activity_user(uint16_t rnti) {} }; @@ -40,7 +40,7 @@ class mac_nr_dummy : public mac_interface_rrc_nr { public: int cell_cfg(const std::vector& nr_cells) override { return SRSRAN_SUCCESS; } - uint16_t reserve_rnti(uint32_t enb_cc_idx) override { return 0x4601; } + uint16_t reserve_rnti(uint32_t enb_cc_idx, const sched_nr_ue_cfg_t& uecfg) override { return 0x4601; } int ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) override { return SRSRAN_SUCCESS; } diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index 4f70c6269..c0f470b44 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -374,11 +374,10 @@ public: // add UE to scheduler if (not use_dummy_mac and not args.wait_preamble) { - mac->reserve_rnti(0); - srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1, phy_cfg); ue_cfg.ue_bearers[4].direction = srsenb::mac_lc_ch_cfg_t::BOTH; - mac->ue_cfg(args.rnti, ue_cfg); + + mac->reserve_rnti(0, ue_cfg); } dl.mcs = args.pdsch.mcs; From ed2e88524f6a8132324381e189cad4b0b5c7cab4 Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 14 Oct 2021 12:18:03 +0100 Subject: [PATCH 142/208] asn1,rrc_nr: implement to_json in setup_release_c --- lib/include/srsran/asn1/asn1_utils.h | 29 +++++++++++++++++++++++++++- lib/include/srsran/asn1/rrc_nr.h | 7 +++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/lib/include/srsran/asn1/asn1_utils.h b/lib/include/srsran/asn1/asn1_utils.h index c50038b6a..af8c3770e 100644 --- a/lib/include/srsran/asn1/asn1_utils.h +++ b/lib/include/srsran/asn1/asn1_utils.h @@ -599,7 +599,7 @@ public: IntType value; integer() = default; integer(IntType value_) : value(value_) {} - operator IntType() { return value; } + operator IntType() const { return value; } SRSASN_CODE pack(bit_ref& bref) const { return pack_integer(bref, value, lb, ub, has_ext, is_aligned); } SRSASN_CODE unpack(cbit_ref& bref) { return unpack_integer(value, bref, lb, ub, has_ext, is_aligned); } }; @@ -1359,6 +1359,33 @@ private: separator_t sep; }; +template +inline auto to_json(json_writer& j, const T& obj) -> decltype(obj.to_json(j)) +{ + obj.to_json(j); +} + +template +inline void to_json(json_writer& j, const asn1::enumerated& obj) +{ + j.write_str(obj.to_string()); +} + +template +inline void to_json(json_writer& j, const asn1::dyn_array& lst) +{ + j.start_array(); + for (const auto& o : lst) { + to_json(j, o); + } + j.end_array(); +} + +inline void to_json(json_writer& j, int64_t number) +{ + j.write_int(number); +} + /******************* Test pack/unpack *******************/ diff --git a/lib/include/srsran/asn1/rrc_nr.h b/lib/include/srsran/asn1/rrc_nr.h index 8e1362f56..2eba2ff82 100644 --- a/lib/include/srsran/asn1/rrc_nr.h +++ b/lib/include/srsran/asn1/rrc_nr.h @@ -2254,7 +2254,7 @@ struct setup_release_c { // choice methods setup_release_c() = default; - types type() const { return type_; } + types type() const { return type_; } // getters elem_type_paramT_& setup() @@ -2267,7 +2267,7 @@ struct setup_release_c { assert_choice_type(types::setup, type_, "SetupRelease"); return c; } - void set_release() { set(types::release); } + void set_release() { set(types::release); } void set(typename types::options e) { type_ = e; } @@ -2276,8 +2276,11 @@ struct setup_release_c { j.start_obj(); switch (type_) { case types::release: + j.write_null("release"); break; case types::setup: + j.write_fieldname("setup"); + asn1::to_json(j, setup()); break; default: log_invalid_choice_id(type_, "setup_release_c"); From 5f648d195c839cac0995f224e7ec75cdc6b26790 Mon Sep 17 00:00:00 2001 From: faluco Date: Wed, 13 Oct 2021 12:15:25 +0200 Subject: [PATCH 143/208] Implement JSON reporting in the scell search test. --- srsue/src/phy/test/scell_search_test.cc | 54 ++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/srsue/src/phy/test/scell_search_test.cc b/srsue/src/phy/test/scell_search_test.cc index 6518e44c5..d82e5d3fc 100644 --- a/srsue/src/phy/test/scell_search_test.cc +++ b/srsue/src/phy/test/scell_search_test.cc @@ -11,6 +11,7 @@ */ #include "srsran/interfaces/phy_interface_types.h" +#include "srsran/srslog/bundled/fmt/chrono.h" #include "srsran/srslog/srslog.h" #include "srsue/hdr/phy/scell/intra_measure_lte.h" #include @@ -36,6 +37,8 @@ static std::string active_cell_list; static std::string simulation_cell_list; static int phy_lib_log_level; static srsue::phy_args_t phy_args; +static bool enable_json_report; +static std::string json_report_filename; // On the Fly parameters static int earfcn_dl; @@ -212,8 +215,31 @@ public: } }; +/// Cell container metrics. +DECLARE_METRIC("earfcn_dl", metric_earfcn, int, ""); +DECLARE_METRIC("PCI", metric_pci, uint32_t, ""); +DECLARE_METRIC("RSRP", metric_rsrp, float, ""); +DECLARE_METRIC("RSRQ", metric_rsrq, float, ""); +DECLARE_METRIC("false_alarm", metric_false_alarm, std::string, ""); +DECLARE_METRIC_SET("cell_container", + mset_cell_container, + metric_earfcn, + metric_pci, + metric_rsrp, + metric_rsrq, + metric_false_alarm); + +/// Report root object. +DECLARE_METRIC("timestamp", metric_timestamp_tag, std::string, ""); +DECLARE_METRIC_LIST("cell_list", mlist_cell, std::vector); + +/// Report context. +using report_context_t = srslog::build_context_type; + class meas_itf_listener : public srsue::scell::intra_measure_base::meas_itf { + srslog::log_channel& json_channel; + public: typedef struct { float rsrp_avg; @@ -225,6 +251,8 @@ public: uint32_t count; } cell_meas_t; + explicit meas_itf_listener(srslog::log_channel& json_channel) : json_channel(json_channel) {} + std::map cells; void cell_meas_reset(uint32_t cc_idx) override {} @@ -262,6 +290,14 @@ public: uint32_t ideal_true_counts = (pcis_to_simulate.size() - 1) * tti_count; uint32_t ideal_false_counts = tti_count * cells.size() - ideal_true_counts; + report_context_t ctx("JSON Report"); + auto current_time = fmt::localtime(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now())); + fmt::memory_buffer ts_buffer; + fmt::format_to(ts_buffer, "{:%F}T{:%T}", current_time, current_time); + ctx.write(srsran::to_c_str(ts_buffer)); + + auto& cell_list = ctx.get(); + for (auto& e : cells) { bool false_alarm = pcis_to_simulate.find(e.first) == pcis_to_simulate.end(); @@ -281,8 +317,19 @@ public: e.second.rsrq_min, e.second.rsrq_avg, e.second.rsrq_max); + + cell_list.emplace_back(); + auto& cell_container = cell_list.back(); + + cell_container.write(e.first); + cell_container.write(earfcn_dl); + cell_container.write(e.second.rsrp_avg); + cell_container.write(e.second.rsrq_avg); + cell_container.write(false_alarm ? "yes" : "no"); } + json_channel(ctx); + float prob_detection = (ideal_true_counts) ? (float)true_counts / (float)ideal_true_counts : 0.0f; float prob_false_alarm = (ideal_false_counts) ? (float)false_counts / (float)ideal_false_counts : 0.0f; printf("\n"); @@ -315,6 +362,8 @@ int parse_args(int argc, char** argv) ("intra_freq_meas_period_ms", bpo::value(&phy_args.intra_freq_meas_period_ms)->default_value(200), "Intra measurement measurement period") ("phy_lib_log_level", bpo::value(&phy_lib_log_level)->default_value(SRSRAN_VERBOSE_NONE), "Phy lib log level (0: none, 1: info, 2: debug)") ("active_cell_list", bpo::value(&active_cell_list)->default_value("10,17,24,31,38,45,52"), "Comma separated neighbour PCI cell list") + ("enable_json_report", bpo::value(&enable_json_report)->default_value(false), "Enable JSON file reporting") + ("json_report_filename", bpo::value(&json_report_filename)->default_value("/tmp/scell_search.json"), "JSON report filename") ; over_the_air.add_options() @@ -394,11 +443,14 @@ int main(int argc, char** argv) // Common for simulation and over-the-air srslog::basic_logger& logger = srslog::fetch_basic_logger("intra_measure"); + srslog::sink& json_sink = srslog::fetch_file_sink(json_report_filename, 0, false, srslog::create_json_formatter()); + srslog::log_channel& json_channel = srslog::fetch_log_channel("JSON_channel", json_sink, {}); + json_channel.set_enabled(enable_json_report); srslog::init(); cf_t* baseband_buffer = srsran_vec_cf_malloc(SRSRAN_SF_LEN_MAX); srsran::rf_timestamp_t ts = {}; - meas_itf_listener rrc; + meas_itf_listener rrc(json_channel); srsue::scell::intra_measure_lte intra_measure(logger, rrc); // Simulation only From fb75cbaadcc1c2a5b21caf37129024a938729699 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Thu, 14 Oct 2021 16:15:24 +0200 Subject: [PATCH 144/208] rrc: disable MAC bearers when RNTI gets updated When the RRC handles the C-RNTI CE to update the RNTI, all the bearers associated with the new RNTI (that will no longer be used) need to be disabled. This commit implements this. Signed-off-by: Carlo Galiotto --- srsenb/hdr/stack/rrc/rrc_nr.h | 1 + srsenb/src/stack/rrc/rrc_nr.cc | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 8f2ff2316..e6fa16b73 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -122,6 +122,7 @@ public: // setters int pack_rrc_reconfiguration(); + int deactivate_bearers(); private: rrc_nr* parent = nullptr; diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 10e1a6904..c4d62dc1c 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -189,6 +189,8 @@ int rrc_nr::update_user(uint16_t new_rnti, uint16_t old_rnti) // Remove new_rnti auto new_ue_it = users.find(new_rnti); if (new_ue_it != users.end()) { + // There is no need to check the return code, as this function should always return SUCCESS + new_ue_it->second->deactivate_bearers(); task_sched.defer_task([this, new_rnti]() { rem_user(new_rnti); }); } @@ -1496,4 +1498,26 @@ int rrc_nr::ue::add_drb() return SRSRAN_SUCCESS; } +/** + * @brief Deactivate all Bearers (MAC logical channel) for this specific RNTI + * + * The function iterates over the bearers or MAC logical channels and deactivates them by setting each of them to IDLE + * + * @return int SRSRAN_SUCCESS on success (only fails if the called sub-functions assert) + */ +int rrc_nr::ue::deactivate_bearers() +{ + // Iterate over the bearers (MAC LC CH) and set each of them to IDLE + for (auto& ue_bearer : uecfg.ue_bearers) { + ue_bearer.direction = mac_lc_ch_cfg_t::IDLE; + } + + // No need to check the returned value, as the function will return SRSRAN_SUCCESS + parent->mac->ue_cfg(rnti, uecfg); + + // Technically, the only way this function fails is if parent->mac->ue_cfg(rnti, uecfg) asserts + // Should we still return SRSRAN_SUCCESS or can we make it void? + return SRSRAN_SUCCESS; +} + } // namespace srsenb From dc3dad6e20e96ce7f35b1c0c08f1af2920569603 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Thu, 14 Oct 2021 18:09:51 +0200 Subject: [PATCH 145/208] rrc,nr: implements PR review comments Signed-off-by: Carlo Galiotto --- srsenb/hdr/stack/rrc/rrc_nr.h | 2 +- srsenb/src/stack/rrc/rrc_nr.cc | 13 +++---------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index e6fa16b73..03bf34376 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -122,7 +122,7 @@ public: // setters int pack_rrc_reconfiguration(); - int deactivate_bearers(); + void deactivate_bearers(); private: rrc_nr* parent = nullptr; diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index c4d62dc1c..fab5cb97d 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -189,7 +189,6 @@ int rrc_nr::update_user(uint16_t new_rnti, uint16_t old_rnti) // Remove new_rnti auto new_ue_it = users.find(new_rnti); if (new_ue_it != users.end()) { - // There is no need to check the return code, as this function should always return SUCCESS new_ue_it->second->deactivate_bearers(); task_sched.defer_task([this, new_rnti]() { rem_user(new_rnti); }); } @@ -1501,23 +1500,17 @@ int rrc_nr::ue::add_drb() /** * @brief Deactivate all Bearers (MAC logical channel) for this specific RNTI * - * The function iterates over the bearers or MAC logical channels and deactivates them by setting each of them to IDLE - * - * @return int SRSRAN_SUCCESS on success (only fails if the called sub-functions assert) + * The function iterates over the bearers or MAC logical channels and deactivates them by setting each one to IDLE */ -int rrc_nr::ue::deactivate_bearers() +void rrc_nr::ue::deactivate_bearers() { // Iterate over the bearers (MAC LC CH) and set each of them to IDLE for (auto& ue_bearer : uecfg.ue_bearers) { ue_bearer.direction = mac_lc_ch_cfg_t::IDLE; } - // No need to check the returned value, as the function will return SRSRAN_SUCCESS + // No need to check the returned value, as the function ue_cfg will return SRSRAN_SUCCESS (it asserts if it fails) parent->mac->ue_cfg(rnti, uecfg); - - // Technically, the only way this function fails is if parent->mac->ue_cfg(rnti, uecfg) asserts - // Should we still return SRSRAN_SUCCESS or can we make it void? - return SRSRAN_SUCCESS; } } // namespace srsenb From c467c3c0e68ebe650247f2a361cb2009ad92e83f Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 14 Oct 2021 11:40:25 +0200 Subject: [PATCH 146/208] ue,rrc_nr: remove warning when zp_csi_rs_res_to_add_mod_list is not present we currently don't enable ZP CSI in the eNB so the warning can be removed. --- srsue/src/stack/rrc/rrc_nr.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/srsue/src/stack/rrc/rrc_nr.cc b/srsue/src/stack/rrc/rrc_nr.cc index e0e59c991..39a7db192 100644 --- a/srsue/src/stack/rrc/rrc_nr.cc +++ b/srsue/src/stack/rrc/rrc_nr.cc @@ -658,12 +658,14 @@ bool rrc_nr::apply_sp_cell_init_dl_pdsch(const asn1::rrc_nr::pdsch_cfg_s& pdsch_ return false; } } - } else { - logger.warning("Option zp_csi_rs_res_to_add_mod_list not present"); - return false; } if (pdsch_cfg.p_zp_csi_rs_res_set_present) { + // check if resources have been processed + if (not pdsch_cfg.zp_csi_rs_res_to_add_mod_list_present) { + logger.warning("Can't build ZP-CSI config, option zp_csi_rs_res_to_add_mod_list not present"); + return false; + } if (pdsch_cfg.p_zp_csi_rs_res_set.type() == setup_release_c::types_opts::setup) { for (uint32_t i = 0; i < pdsch_cfg.p_zp_csi_rs_res_set.setup().zp_csi_rs_res_id_list.size(); i++) { uint8_t res = pdsch_cfg.p_zp_csi_rs_res_set.setup().zp_csi_rs_res_id_list[i]; @@ -1219,7 +1221,10 @@ bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg) if (sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdsch_cfg_present) { if (sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdsch_cfg.type() == setup_release_c::types_opts::setup) { - apply_sp_cell_init_dl_pdsch(sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdsch_cfg.setup()); + if (apply_sp_cell_init_dl_pdsch(sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdsch_cfg.setup()) == false) { + logger.error("Couldn't apply PDSCH config for initial DL BWP in SpCell Cfg dedicated"); + return false; + }; } else { logger.warning("Option pdsch_cfg_cfg not of type setup"); return false; From f7dd327d08ba96cdb6fcd36486499bbda9ceb4f9 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 14 Oct 2021 11:41:25 +0200 Subject: [PATCH 147/208] enb,rrc_nr: send PUSCH nominal power --- srsenb/src/stack/rrc/rrc_nr.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index fab5cb97d..35f9b183d 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -1194,6 +1194,7 @@ int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bw pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[1].map_type = asn1::rrc_nr::pusch_time_domain_res_alloc_s::map_type_opts::type_a; pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[1].start_symbol_and_len = 27; + pusch_cfg_common_pack.setup().p0_nominal_with_grant_present = true; pusch_cfg_common_pack.setup().p0_nominal_with_grant = -90; // PUCCH config common From f427a25a30d940286e6d839c428b40f680f9b7f7 Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 14 Oct 2021 10:35:35 +0100 Subject: [PATCH 148/208] nr,gnb,mac: account for header space larger than 2 when packing PDSCH --- lib/include/srsran/mac/mac_sch_pdu_nr.h | 3 ++- lib/src/mac/mac_sch_pdu_nr.cc | 7 +------ srsenb/src/stack/mac/nr/ue_nr.cc | 5 +++-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/lib/include/srsran/mac/mac_sch_pdu_nr.h b/lib/include/srsran/mac/mac_sch_pdu_nr.h index 1ff74110d..fb15b1768 100644 --- a/lib/include/srsran/mac/mac_sch_pdu_nr.h +++ b/lib/include/srsran/mac/mac_sch_pdu_nr.h @@ -198,8 +198,9 @@ public: void to_string(fmt::memory_buffer& buffer); -private: uint32_t size_header_sdu(const uint32_t lcid_, const uint32_t nbytes); + +private: /// Private helper that adds a subPDU to the MAC PDU uint32_t add_sudpdu(mac_sch_subpdu_nr& subpdu); diff --git a/lib/src/mac/mac_sch_pdu_nr.cc b/lib/src/mac/mac_sch_pdu_nr.cc index f87289230..28645ff0b 100644 --- a/lib/src/mac/mac_sch_pdu_nr.cc +++ b/lib/src/mac/mac_sch_pdu_nr.cc @@ -423,13 +423,8 @@ uint32_t mac_sch_pdu_nr::size_header_sdu(const uint32_t lcid, const uint32_t nby { if (ulsch && (lcid == mac_sch_subpdu_nr::CCCH_SIZE_48 || lcid == mac_sch_subpdu_nr::CCCH_SIZE_64)) { return 1; - } else { - if (nbytes < 256) { - return 2; - } else { - return 3; - } } + return nbytes < 256 ? 2 : 3; } uint32_t mac_sch_pdu_nr::get_remaing_len() diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc index 88ae1a2a4..4e79a257d 100644 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ b/srsenb/src/stack/mac/nr/ue_nr.cc @@ -146,8 +146,9 @@ int ue_nr::generate_pdu(srsran::byte_buffer_t* pdu, uint32_t grant_size) // read RLC PDU ue_rlc_buffer->clear(); - int lcid = 4; - int pdu_len = rlc->read_pdu(rnti, lcid, ue_rlc_buffer->msg, grant_size - 2); + int lcid = 4; + int pdu_len = + rlc->read_pdu(rnti, lcid, ue_rlc_buffer->msg, grant_size - mac_pdu_dl.size_header_sdu(lcid, grant_size)); // Only create PDU if RLC has something to tx if (pdu_len > 0) { From b034a9c9839889a48d9877f4454a3a24fd90f92c Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Tue, 12 Oct 2021 10:58:11 +0200 Subject: [PATCH 149/208] Lock mutex when setting common cfg. --- srsenb/src/phy/nr/slot_worker.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/srsenb/src/phy/nr/slot_worker.cc b/srsenb/src/phy/nr/slot_worker.cc index fed1aa6e5..2ff2880c1 100644 --- a/srsenb/src/phy/nr/slot_worker.cc +++ b/srsenb/src/phy/nr/slot_worker.cc @@ -401,10 +401,12 @@ void slot_worker::work_imp() common.worker_end(context, true, tx_rf_buffer); } + bool slot_worker::set_common_cfg(const srsran_carrier_nr_t& carrier, const srsran_pdcch_cfg_nr_t& pdcch_cfg_, const srsran_ssb_cfg_t& ssb_cfg_) { + std::lock_guard lock(mutex); // Set gNb DL carrier if (srsran_gnb_dl_set_carrier(&gnb_dl, &carrier) < SRSRAN_SUCCESS) { logger.error("Error setting DL carrier"); From 01d8814f3998b7938499dfa4cb6bc11f6eb5a1cb Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 14 Oct 2021 15:46:22 +0100 Subject: [PATCH 150/208] sched,nr: when sched allocates PUSCH, SR doesn't need to be decoded --- srsenb/src/stack/mac/nr/sched_nr_worker.cc | 4 ++++ test/phy/dummy_gnb_stack.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc index 0fd5d0f5e..ce992962c 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_worker.cc @@ -167,6 +167,10 @@ void slot_cc_worker::postprocess_decisions() if (pusch.sch.grant.rnti == ue.rnti) { // Put UCI configuration in PUSCH config has_pusch = true; + + // If has PUSCH, no SR shall be received + uci_cfg.o_sr = 0; + if (not ue.cfg->phy().get_pusch_uci_cfg(slot_cfg, uci_cfg, pusch.sch)) { logger.error("Error setting UCI configuration in PUSCH"); continue; diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index c0f470b44..cbc88d002 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -570,6 +570,9 @@ public: // Schedule PUSCH if (has_pusch) { + // If has PUSCH, no SR shall be received + uci_cfg.o_sr = 0; + // Put UCI configuration in PUSCH config if (not phy_cfg.get_pusch_uci_cfg(slot_cfg, uci_cfg, pusch.sch)) { logger.error("Error setting UCI configuration in PUSCH"); From 33df51a1f5e2a3eec7821806eb8871f086932336 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Mon, 11 Oct 2021 16:44:39 +0200 Subject: [PATCH 151/208] Remove error message if dl_freq and ul_freq are not specified. --- srsenb/src/enb_cfg_parser.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 6c55e2c38..1bcd57b4c 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -898,8 +898,8 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) HANDLEPARSERCODE(parse_required_field(cell_cfg.pci, cellroot, "pci")); cell_cfg.pci = cell_cfg.pci % SRSRAN_NUM_PCI; HANDLEPARSERCODE(parse_required_field(cell_cfg.dl_earfcn, cellroot, "dl_earfcn")); - parse_required_field(cell_cfg.dl_freq_hz, cellroot, "dl_freq"); - parse_required_field(cell_cfg.ul_freq_hz, cellroot, "ul_freq"); + parse_default_field(cell_cfg.dl_freq_hz, cellroot, "dl_freq", 0.0); // will be derived from DL EARFCN If not set + parse_default_field(cell_cfg.ul_freq_hz, cellroot, "ul_freq", 0.0); // will be derived from DL EARFCN If not set parse_default_field(cell_cfg.ul_earfcn, cellroot, "ul_earfcn", 0u); // will be derived from DL EARFCN If not set parse_default_field( cell_cfg.root_seq_idx, cellroot, "root_seq_idx", rrc_cfg->sibs[1].sib2().rr_cfg_common.prach_cfg.root_seq_idx); @@ -1179,7 +1179,7 @@ int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, rrc_nr_cfg_t* rrc_nr // 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.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; From 44de4996e8ae18caa7c0fe5bbbd31d1721dfaf48 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Tue, 12 Oct 2021 10:05:00 +0200 Subject: [PATCH 152/208] Fix log message. --- lib/src/phy/rf/rf_zmq_imp_rx.c | 2 +- lib/src/phy/rf/rf_zmq_imp_tx.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/phy/rf/rf_zmq_imp_rx.c b/lib/src/phy/rf/rf_zmq_imp_rx.c index 4d0678c61..85567c1fe 100644 --- a/lib/src/phy/rf/rf_zmq_imp_rx.c +++ b/lib/src/phy/rf/rf_zmq_imp_rx.c @@ -161,7 +161,7 @@ int rf_zmq_rx_open(rf_zmq_rx_t* q, rf_zmq_opts_t opts, void* zmq_ctx, char* sock } if (zmq_setsockopt(q->sock, ZMQ_SNDTIMEO, &timeout, sizeof(timeout)) == -1) { - fprintf(stderr, "Error: setting receive timeout on rx socket\n"); + fprintf(stderr, "Error: setting send timeout on rx socket\n"); goto clean_exit; } diff --git a/lib/src/phy/rf/rf_zmq_imp_tx.c b/lib/src/phy/rf/rf_zmq_imp_tx.c index 3a53f1f49..a7e8bf5db 100644 --- a/lib/src/phy/rf/rf_zmq_imp_tx.c +++ b/lib/src/phy/rf/rf_zmq_imp_tx.c @@ -57,7 +57,7 @@ int rf_zmq_tx_open(rf_zmq_tx_t* q, rf_zmq_opts_t opts, void* zmq_ctx, char* sock } if (zmq_setsockopt(q->sock, ZMQ_SNDTIMEO, &timeout, sizeof(timeout)) == -1) { - fprintf(stderr, "Error: setting receive timeout on tx socket\n"); + fprintf(stderr, "Error: setting send timeout on tx socket\n"); goto clean_exit; } From 0507d9df2bb55a0fb1a5db28736d4beb040139b3 Mon Sep 17 00:00:00 2001 From: Bedran Karakoc Date: Tue, 12 Oct 2021 15:32:20 +0200 Subject: [PATCH 153/208] nas,nr: Fix ciphering and sequence numbers in NAS --- srsue/hdr/stack/upper/nas_5g.h | 1 + srsue/src/stack/upper/nas_5g.cc | 71 ++++++++++++++++++++++++++++++--- 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/srsue/hdr/stack/upper/nas_5g.h b/srsue/hdr/stack/upper/nas_5g.h index 3d916bdc1..c0bf9e5fa 100644 --- a/srsue/hdr/stack/upper/nas_5g.h +++ b/srsue/hdr/stack/upper/nas_5g.h @@ -140,6 +140,7 @@ private: const pdu_session_cfg_t& pdu_session); int send_deregistration_request_ue_originating(bool switch_off); int send_identity_response(srsran::nas_5g::identity_type_5gs_t::identity_types_::options requested_identity_type); + int send_configuration_update_complete(); // Helper functions void fill_security_caps(srsran::nas_5g::ue_security_capability_t& sec_caps); diff --git a/srsue/src/stack/upper/nas_5g.cc b/srsue/src/stack/upper/nas_5g.cc index 8253a57db..8353759a9 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -226,6 +226,9 @@ int nas_5g::write_pdu(srsran::unique_byte_buffer_t pdu) case msg_opts::options::deregistration_accept_ue_originating: handle_deregistration_accept_ue_originating(nas_msg.deregistration_accept_ue_originating()); break; + case msg_opts::options::configuration_update_command: + handle_configuration_update_command(nas_msg.configuration_update_command()); + break; default: logger.error( "Not handling NAS message type: %s (0x%02x)", nas_msg.hdr.message_type.to_string(), nas_msg.hdr.message_type); @@ -304,23 +307,30 @@ int nas_5g::send_registration_complete() return SRSRAN_ERROR; } - logger.info("Generating Registration Complete"); - nas_5gs_msg nas_msg; registration_complete_t& reg_comp = nas_msg.set_registration_complete(); + nas_msg.hdr.security_header_type = nas_5gs_hdr::security_header_type_opts::integrity_protected_and_ciphered; + nas_msg.hdr.sequence_number = ctxt_base.tx_count; if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { logger.error("Failed to pack registration complete."); return SRSRAN_ERROR; } + cipher_encrypt(pdu.get()); + integrity_generate(&ctxt_base.k_nas_int[16], + ctxt_base.tx_count, + SECURITY_DIRECTION_UPLINK, + &pdu->msg[SEQ_5G_OFFSET], + pdu->N_bytes - SEQ_5G_OFFSET, + &pdu->msg[MAC_5G_OFFSET]); + if (pcap != nullptr) { pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); } - logger.info("Sending Registration Complete"); rrc_nr->write_sdu(std::move(pdu)); - + ctxt_base.tx_count++; return SRSRAN_SUCCESS; } @@ -351,6 +361,7 @@ int nas_5g::send_authentication_response(const uint8_t res[16]) logger.info("Sending Authentication Response"); rrc_nr->write_sdu(std::move(pdu)); + ctxt_base.tx_count++; return SRSRAN_SUCCESS; } @@ -493,6 +504,7 @@ uint32_t nas_5g::allocate_next_proc_trans_id() i++; if (pdu_trans_id == false) { pdu_trans_id = true; + break; } } // TODO if Trans ID exhausted @@ -522,11 +534,12 @@ int nas_5g::send_pdu_session_establishment_request(uint32_t tran nas_5gs_msg nas_msg; nas_msg.hdr.pdu_session_identity = pdu_session_id; nas_msg.hdr.procedure_transaction_identity = transaction_identity; + nas_msg.hdr.sequence_number = ctxt_base.tx_count; pdu_session_establishment_request_t& pdu_ses_est_req = nas_msg.set_pdu_session_establishment_request(); - pdu_ses_est_req.integrity_protection_maximum_data_rate.max_data_rate_upip_downlink = + pdu_ses_est_req.integrity_protection_maximum_data_rate.max_data_rate_upip_downlink.value = integrity_protection_maximum_data_rate_t::max_data_rate_UPIP_downlink_type_::options::full_data_rate; - pdu_ses_est_req.integrity_protection_maximum_data_rate.max_data_rate_upip_uplink = + pdu_ses_est_req.integrity_protection_maximum_data_rate.max_data_rate_upip_uplink.value = integrity_protection_maximum_data_rate_t::max_data_rate_UPIP_uplink_type_::options::full_data_rate; pdu_ses_est_req.pdu_session_type_present = true; @@ -592,6 +605,7 @@ int nas_5g::send_pdu_session_establishment_request(uint32_t tran logger.info("Sending PDU Session Establishment Request in UL NAS transport."); rrc_nr->write_sdu(std::move(pdu)); + ctxt_base.tx_count++; return SRSRAN_SUCCESS; } @@ -705,6 +719,43 @@ int nas_5g::send_identity_response(srsran::nas_5g::identity_type_5gs_t::identity return SRSRAN_SUCCESS; } +int nas_5g::send_configuration_update_complete() +{ + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (!pdu) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return SRSRAN_ERROR; + } + + logger.info("Generating Configuration Update Complete"); + + nas_5gs_msg nas_msg; + configuration_update_complete_t& config_update_complete = nas_msg.set_configuration_update_complete(); + nas_msg.hdr.security_header_type = nas_5gs_hdr::security_header_type_opts::integrity_protected_and_ciphered; + nas_msg.hdr.sequence_number = ctxt_base.tx_count; + + if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { + logger.error("Failed to pack Identity Response."); + return SRSRAN_ERROR; + } + + if (pcap != nullptr) { + pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); + } + + cipher_encrypt(pdu.get()); + integrity_generate(&ctxt_base.k_nas_int[16], + ctxt_base.tx_count, + SECURITY_DIRECTION_UPLINK, + &pdu->msg[SEQ_5G_OFFSET], + pdu->N_bytes - SEQ_5G_OFFSET, + &pdu->msg[MAC_5G_OFFSET]); + + rrc_nr->write_sdu(std::move(pdu)); + ctxt_base.tx_count++; + return SRSRAN_SUCCESS; +} + // Message handler int nas_5g::handle_registration_accept(registration_accept_t& registration_accept) { @@ -962,6 +1013,14 @@ int nas_5g::handle_deregistration_accept_ue_originating( return SRSASN_SUCCESS; } +int nas_5g::handle_configuration_update_command( + srsran::nas_5g::configuration_update_command_t& configuration_update_command) +{ + logger.info("Handling Configuration Update Command"); + send_configuration_update_complete(); + return SRSRAN_SUCCESS; +} + /******************************************************************************* * NAS Timers ******************************************************************************/ From 2c1e9c0c55712601ed7da637d11dade2b09fe3da Mon Sep 17 00:00:00 2001 From: faluco Date: Wed, 13 Oct 2021 17:03:05 +0200 Subject: [PATCH 154/208] Implement an emergency cleanup handler registration mechanism to allow modules to clean themselves before application gets killed. Flush PCAP contents just before killing the application. --- .../srsran/common/emergency_handlers.h | 25 ++++++++ lib/include/srsran/common/mac_pcap_base.h | 6 +- lib/include/srsran/common/s1ap_pcap.h | 5 +- lib/include/srsran/common/signal_handler.h | 6 +- lib/src/common/CMakeLists.txt | 1 + lib/src/common/emergency_handlers.cc | 59 +++++++++++++++++++ lib/src/common/mac_pcap_base.cc | 14 ++++- lib/src/common/s1ap_pcap.cc | 15 +++++ 8 files changed, 125 insertions(+), 6 deletions(-) create mode 100644 lib/include/srsran/common/emergency_handlers.h create mode 100644 lib/src/common/emergency_handlers.cc diff --git a/lib/include/srsran/common/emergency_handlers.h b/lib/include/srsran/common/emergency_handlers.h new file mode 100644 index 000000000..818f1a211 --- /dev/null +++ b/lib/include/srsran/common/emergency_handlers.h @@ -0,0 +1,25 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#ifndef SRSRAN_EMERGENCY_HANDLERS_H +#define SRSRAN_EMERGENCY_HANDLERS_H + +using emergency_cleanup_callback = void (*)(void*); + +// Add a cleanup function to be called when a kill signal is about to be delivered to the process. The handler may +// optionally pass a pointer to identify what instance of the handler is being called. +void add_emergency_cleanup_handler(emergency_cleanup_callback callback, void* data); + +// Executes all registered emergency cleanup handlers. +void execute_emergency_cleanup_handlers(); + +#endif // SRSRAN_EMERGENCY_HANDLERS_H diff --git a/lib/include/srsran/common/mac_pcap_base.h b/lib/include/srsran/common/mac_pcap_base.h index f80167853..544df52dc 100644 --- a/lib/include/srsran/common/mac_pcap_base.h +++ b/lib/include/srsran/common/mac_pcap_base.h @@ -28,6 +28,10 @@ class mac_pcap_base : protected srsran::thread { public: mac_pcap_base(); + + mac_pcap_base(const mac_pcap_base& other) = delete; + mac_pcap_base& operator=(const mac_pcap_base& other) = delete; + ~mac_pcap_base(); void enable(bool enable); virtual uint32_t close() = 0; @@ -36,7 +40,7 @@ public: // EUTRA void - write_ul_crnti(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t crnti, uint32_t reTX, uint32_t tti, uint8_t cc_idx); + write_ul_crnti(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t crnti, uint32_t reTX, uint32_t tti, uint8_t cc_idx); void write_dl_crnti(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t crnti, bool crc_ok, uint32_t tti, uint8_t cc_idx); void write_dl_ranti(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t ranti, bool crc_ok, uint32_t tti, uint8_t cc_idx); diff --git a/lib/include/srsran/common/s1ap_pcap.h b/lib/include/srsran/common/s1ap_pcap.h index f2a0b1164..c62797a2e 100644 --- a/lib/include/srsran/common/s1ap_pcap.h +++ b/lib/include/srsran/common/s1ap_pcap.h @@ -21,7 +21,10 @@ namespace srsran { class s1ap_pcap { public: - s1ap_pcap() = default; + s1ap_pcap(); + s1ap_pcap(const s1ap_pcap& other) = delete; + s1ap_pcap& operator=(const s1ap_pcap& other) = delete; + void enable(); void open(const char* filename_); void close(); diff --git a/lib/include/srsran/common/signal_handler.h b/lib/include/srsran/common/signal_handler.h index fefb23f02..29d4307fb 100644 --- a/lib/include/srsran/common/signal_handler.h +++ b/lib/include/srsran/common/signal_handler.h @@ -18,6 +18,7 @@ #ifndef SRSRAN_SIGNAL_HANDLER_H #define SRSRAN_SIGNAL_HANDLER_H +#include "srsran/common/emergency_handlers.h" #include "srsran/srslog/sink.h" #include "srsran/srslog/srslog.h" #include @@ -30,7 +31,7 @@ extern "C" { #define SRSRAN_TERM_TIMEOUT_S (5) // static vars required by signal handling -static srslog::sink* log_sink = nullptr; +static srslog::sink* log_sink = nullptr; static std::atomic running = {true}; void srsran_dft_exit(); @@ -41,11 +42,12 @@ static void srsran_signal_handler(int signal) case SIGALRM: fprintf(stderr, "Couldn't stop after %ds. Forcing exit.\n", SRSRAN_TERM_TIMEOUT_S); srslog::flush(); - //:TODO: refactor the sighandler, should not depend on log utilities + //: TODO: refactor the sighandler, should not depend on log utilities if (log_sink) { log_sink->flush(); } srsran_dft_exit(); + execute_emergency_cleanup_handlers(); raise(SIGKILL); default: // all other registered signals try to stop the app gracefully diff --git a/lib/src/common/CMakeLists.txt b/lib/src/common/CMakeLists.txt index 2cb75a650..cc8d08470 100644 --- a/lib/src/common/CMakeLists.txt +++ b/lib/src/common/CMakeLists.txt @@ -28,6 +28,7 @@ set(SOURCES arch_select.cc rlc_pcap.cc s1ap_pcap.cc security.cc + emergency_handlers.cc standard_streams.cc thread_pool.cc threads.c diff --git a/lib/src/common/emergency_handlers.cc b/lib/src/common/emergency_handlers.cc new file mode 100644 index 000000000..3377153ac --- /dev/null +++ b/lib/src/common/emergency_handlers.cc @@ -0,0 +1,59 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "srsran/common/emergency_handlers.h" +#include "srsran/support/srsran_assert.h" + +namespace { + +/// Holds the callback function pointer and the associated user provided data pointer. +struct handler_instance { + std::atomic data{}; + std::atomic callback{}; +}; + +} // namespace + +// Handlers are added in a thread safe manner without using locks to avoid possible issues if a signal is emitted while +// modifying the callback array. +static constexpr unsigned max_handlers = 12; +static handler_instance registered_handlers[max_handlers]; +static std::atomic num_handlers; + +void add_emergency_cleanup_handler(emergency_cleanup_callback callback, void* data) +{ + // Reserve a slot in the array. + auto pos = num_handlers.fetch_add(1); + + // Check if we have space in the array. + if (pos >= max_handlers) { + srsran_assert(0, "Exceeded the emergency cleanup handler registered limit"); + return; + } + + // Order is important here: write last the callback member as it is used to signal that the handler is valid when + // reading the array. + registered_handlers[pos].data.store(data); + registered_handlers[pos].callback.store(callback); +} + +void execute_emergency_cleanup_handlers() +{ + for (unsigned i = 0, e = num_handlers; i != e; ++i) { + auto callback = registered_handlers[i].callback.load(); + // Test the validity of the callback as it may have not been written yet into the array even if num_callbacks has + // been updated. + if (callback) { + callback(registered_handlers[i].data.load()); + } + } +} diff --git a/lib/src/common/mac_pcap_base.cc b/lib/src/common/mac_pcap_base.cc index c7fe8bd3c..48d825199 100644 --- a/lib/src/common/mac_pcap_base.cc +++ b/lib/src/common/mac_pcap_base.cc @@ -11,13 +11,23 @@ */ #include "srsran/common/mac_pcap_base.h" +#include "srsran/common/emergency_handlers.h" #include "srsran/config.h" #include "srsran/phy/common/phy_common.h" #include namespace srsran { -mac_pcap_base::mac_pcap_base() : logger(srslog::fetch_basic_logger("MAC")), thread("PCAP_WRITER_MAC") {} +/// Try to flush the contents of the pcap class before the application is killed. +static void emergency_cleanup_handler(void* data) +{ + reinterpret_cast(data)->close(); +} + +mac_pcap_base::mac_pcap_base() : logger(srslog::fetch_basic_logger("MAC")), thread("PCAP_WRITER_MAC") +{ + add_emergency_cleanup_handler(emergency_cleanup_handler, this); +} mac_pcap_base::~mac_pcap_base() {} @@ -45,7 +55,7 @@ void mac_pcap_base::run_thread() } // write remainder of queue - pcap_pdu_t pdu = {}; + pcap_pdu_t pdu = {}; while (queue.try_pop(pdu)) { std::lock_guard lock(mutex); write_pdu(pdu); diff --git a/lib/src/common/s1ap_pcap.cc b/lib/src/common/s1ap_pcap.cc index ce06c5a6e..e87e77ad9 100644 --- a/lib/src/common/s1ap_pcap.cc +++ b/lib/src/common/s1ap_pcap.cc @@ -11,12 +11,24 @@ */ #include "srsran/common/s1ap_pcap.h" +#include "srsran/common/emergency_handlers.h" #include "srsran/common/pcap.h" #include "srsran/srsran.h" #include namespace srsran { +/// Try to flush the contents of the pcap class before the application is killed. +static void emergency_cleanup_handler(void* data) +{ + reinterpret_cast(data)->close(); +} + +s1ap_pcap::s1ap_pcap() +{ + add_emergency_cleanup_handler(emergency_cleanup_handler, this); +} + void s1ap_pcap::enable() { enable_write = true; @@ -29,6 +41,9 @@ void s1ap_pcap::open(const char* filename_) } void s1ap_pcap::close() { + if (!enable_write) { + return; + } fprintf(stdout, "Saving S1AP PCAP file (DLT=%d) to %s\n", S1AP_LTE_DLT, filename.c_str()); DLT_PCAP_Close(pcap_file); } From 90752516277dd990e75f36fe5e930a77d1401144 Mon Sep 17 00:00:00 2001 From: faluco Date: Thu, 14 Oct 2021 11:16:32 +0200 Subject: [PATCH 155/208] Move the cleanup code from the signal handlers down to the new emergency handlers for the ue, epc and enb. --- lib/include/srsran/common/signal_handler.h | 11 +------- srsenb/src/main.cc | 17 ++++++++++-- srsepc/src/main.cc | 31 +++++++++++++++------- srsue/src/main.cc | 12 +++++++++ 4 files changed, 49 insertions(+), 22 deletions(-) diff --git a/lib/include/srsran/common/signal_handler.h b/lib/include/srsran/common/signal_handler.h index 29d4307fb..36e48ebb2 100644 --- a/lib/include/srsran/common/signal_handler.h +++ b/lib/include/srsran/common/signal_handler.h @@ -31,22 +31,13 @@ extern "C" { #define SRSRAN_TERM_TIMEOUT_S (5) // static vars required by signal handling -static srslog::sink* log_sink = nullptr; -static std::atomic running = {true}; - -void srsran_dft_exit(); +static std::atomic running = {true}; static void srsran_signal_handler(int signal) { switch (signal) { case SIGALRM: fprintf(stderr, "Couldn't stop after %ds. Forcing exit.\n", SRSRAN_TERM_TIMEOUT_S); - srslog::flush(); - //: TODO: refactor the sighandler, should not depend on log utilities - if (log_sink) { - log_sink->flush(); - } - srsran_dft_exit(); execute_emergency_cleanup_handlers(); raise(SIGKILL); default: diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index f95349ebf..d2c69a83b 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -45,8 +45,9 @@ namespace bpo = boost::program_options; /********************************************************************** * Program arguments processing ***********************************************************************/ -string config_file; -static bool stdout_ts_enable = false; +string config_file; +static bool stdout_ts_enable = false; +static srslog::sink* log_sink = nullptr; void parse_args(all_args_t* args, int argc, char* argv[]) { @@ -534,9 +535,21 @@ static size_t fixup_log_file_maxsize(int x) return (x < 0) ? 0 : size_t(x) * 1024u; } +extern "C" void srsran_dft_exit(); +static void emergency_cleanup_handler(void* data) +{ + srslog::flush(); + if (log_sink) { + log_sink->flush(); + } + srsran_dft_exit(); +} + int main(int argc, char* argv[]) { srsran_register_signal_handler(); + add_emergency_cleanup_handler(emergency_cleanup_handler, nullptr); + all_args_t args = {}; srsran::metrics_hub metricshub; metrics_stdout metrics_screen; diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index e2f33abaf..62e2fce09 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -55,6 +55,8 @@ typedef struct { log_args_t log_args; } all_args_t; +static srslog::sink* log_sink = nullptr; + /********************************************************************** * Program arguments processing ***********************************************************************/ @@ -261,18 +263,18 @@ void parse_args(all_args_t* args, int argc, char* argv[]) cout << "Using default mme.integrity_algo: EIA1" << endl; } - args->mme_args.s1ap_args.mme_bind_addr = mme_bind_addr; - args->mme_args.s1ap_args.mme_name = mme_name; - args->mme_args.s1ap_args.dns_addr = dns_addr; + args->mme_args.s1ap_args.mme_bind_addr = mme_bind_addr; + args->mme_args.s1ap_args.mme_name = mme_name; + args->mme_args.s1ap_args.dns_addr = dns_addr; args->mme_args.s1ap_args.full_net_name = full_net_name; args->mme_args.s1ap_args.short_net_name = short_net_name; - args->mme_args.s1ap_args.mme_apn = mme_apn; - args->mme_args.s1ap_args.paging_timer = paging_timer; - args->spgw_args.gtpu_bind_addr = spgw_bind_addr; - args->spgw_args.sgi_if_addr = sgi_if_addr; - args->spgw_args.sgi_if_name = sgi_if_name; - args->spgw_args.max_paging_queue = max_paging_queue; - args->hss_args.db_file = hss_db_file; + args->mme_args.s1ap_args.mme_apn = mme_apn; + args->mme_args.s1ap_args.paging_timer = paging_timer; + args->spgw_args.gtpu_bind_addr = spgw_bind_addr; + args->spgw_args.sgi_if_addr = sgi_if_addr; + args->spgw_args.sgi_if_name = sgi_if_name; + args->spgw_args.max_paging_queue = max_paging_queue; + args->hss_args.db_file = hss_db_file; // Apply all_level to any unset layers if (vm.count("log.all_level")) { @@ -353,9 +355,18 @@ std::string get_build_string() return ss.str(); } +static void emergency_cleanup_handler(void* data) +{ + srslog::flush(); + if (log_sink) { + log_sink->flush(); + } +} + int main(int argc, char* argv[]) { srsran_register_signal_handler(); + add_emergency_cleanup_handler(emergency_cleanup_handler, nullptr); // print build info cout << endl << get_build_string() << endl; diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 05e43934b..7a9de3f76 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -47,6 +47,7 @@ namespace bpo = boost::program_options; static bool do_metrics = false; static metrics_stdout* metrics_screen = nullptr; +static srslog::sink* log_sink = nullptr; /********************************************************************** * Program arguments processing @@ -656,9 +657,20 @@ static size_t fixup_log_file_maxsize(int x) return (x < 0) ? 0 : size_t(x) * 1024u; } +extern "C" void srsran_dft_exit(); +static void emergency_cleanup_handler(void* data) +{ + srslog::flush(); + if (log_sink) { + log_sink->flush(); + } + srsran_dft_exit(); +} + int main(int argc, char* argv[]) { srsran_register_signal_handler(); + add_emergency_cleanup_handler(emergency_cleanup_handler, nullptr); srsran_debug_handle_crash(argc, argv); all_args_t args = {}; From dacf40f63e029529a8f3c8d2128a0d408eb22cf3 Mon Sep 17 00:00:00 2001 From: faluco Date: Thu, 14 Oct 2021 17:14:25 +0200 Subject: [PATCH 156/208] Delete move constructor and move assignment operator explictly for mac_pcap_base and s1ap_pcap classes. Move emergency handlers header file into the support folder. Refactored signal handling: - Remove the dependency with the running static variable in the header file. - Move implementations down to cc files. - Allow specifying a new signal handler that will be used to stop the applications. - Move signal handling files to support. --- lib/include/srsran/common/mac_pcap_base.h | 2 + lib/include/srsran/common/s1ap_pcap.h | 2 + .../{common => support}/emergency_handlers.h | 0 lib/include/srsran/support/signal_handler.h | 27 +++++++++++ lib/src/CMakeLists.txt | 1 + lib/src/common/CMakeLists.txt | 3 +- lib/src/common/mac_pcap_base.cc | 2 +- lib/src/common/s1ap_pcap.cc | 2 +- lib/src/support/CMakeLists.txt | 12 +++++ .../{common => support}/emergency_handlers.cc | 2 +- .../support/signal_handler.cc} | 47 +++++++------------ srsenb/src/CMakeLists.txt | 2 +- srsenb/src/main.cc | 17 +++++-- srsepc/src/CMakeLists.txt | 1 + srsepc/src/main.cc | 13 +++-- srsue/src/CMakeLists.txt | 2 +- srsue/src/main.cc | 18 +++++-- 17 files changed, 103 insertions(+), 50 deletions(-) rename lib/include/srsran/{common => support}/emergency_handlers.h (100%) create mode 100644 lib/include/srsran/support/signal_handler.h create mode 100644 lib/src/support/CMakeLists.txt rename lib/src/{common => support}/emergency_handlers.cc (97%) rename lib/{include/srsran/common/signal_handler.h => src/support/signal_handler.cc} (52%) diff --git a/lib/include/srsran/common/mac_pcap_base.h b/lib/include/srsran/common/mac_pcap_base.h index 544df52dc..f9394bfbd 100644 --- a/lib/include/srsran/common/mac_pcap_base.h +++ b/lib/include/srsran/common/mac_pcap_base.h @@ -31,6 +31,8 @@ public: mac_pcap_base(const mac_pcap_base& other) = delete; mac_pcap_base& operator=(const mac_pcap_base& other) = delete; + mac_pcap_base(mac_pcap_base&& other) = delete; + mac_pcap_base& operator=(mac_pcap_base&& other) = delete; ~mac_pcap_base(); void enable(bool enable); diff --git a/lib/include/srsran/common/s1ap_pcap.h b/lib/include/srsran/common/s1ap_pcap.h index c62797a2e..0e9cae421 100644 --- a/lib/include/srsran/common/s1ap_pcap.h +++ b/lib/include/srsran/common/s1ap_pcap.h @@ -24,6 +24,8 @@ public: s1ap_pcap(); s1ap_pcap(const s1ap_pcap& other) = delete; s1ap_pcap& operator=(const s1ap_pcap& other) = delete; + s1ap_pcap(s1ap_pcap&& other) = delete; + s1ap_pcap& operator=(s1ap_pcap&& other) = delete; void enable(); void open(const char* filename_); diff --git a/lib/include/srsran/common/emergency_handlers.h b/lib/include/srsran/support/emergency_handlers.h similarity index 100% rename from lib/include/srsran/common/emergency_handlers.h rename to lib/include/srsran/support/emergency_handlers.h diff --git a/lib/include/srsran/support/signal_handler.h b/lib/include/srsran/support/signal_handler.h new file mode 100644 index 000000000..e21440bf9 --- /dev/null +++ b/lib/include/srsran/support/signal_handler.h @@ -0,0 +1,27 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +/** + * @file signal_handler.h + * @brief Common signal handling methods for all srsRAN applications. + */ + +#ifndef SRSRAN_SIGNAL_HANDLER_H +#define SRSRAN_SIGNAL_HANDLER_H + +using srsran_signal_hanlder = void (*)(); + +/// Registers the specified function to be called when the user interrupts the program execution (eg: via Ctrl+C). +/// Passing a null function pointer disables the current installed handler. +void srsran_register_signal_handler(srsran_signal_hanlder handler); + +#endif // SRSRAN_SIGNAL_HANDLER_H diff --git a/lib/src/CMakeLists.txt b/lib/src/CMakeLists.txt index fb5f62463..d6bb50635 100644 --- a/lib/src/CMakeLists.txt +++ b/lib/src/CMakeLists.txt @@ -15,4 +15,5 @@ add_subdirectory(rlc) add_subdirectory(pdcp) add_subdirectory(gtpu) add_subdirectory(srslog) +add_subdirectory(support) add_subdirectory(system) diff --git a/lib/src/common/CMakeLists.txt b/lib/src/common/CMakeLists.txt index cc8d08470..811f25b9e 100644 --- a/lib/src/common/CMakeLists.txt +++ b/lib/src/common/CMakeLists.txt @@ -28,7 +28,6 @@ set(SOURCES arch_select.cc rlc_pcap.cc s1ap_pcap.cc security.cc - emergency_handlers.cc standard_streams.cc thread_pool.cc threads.c @@ -48,7 +47,7 @@ add_dependencies(srsran_common gen_build_info) add_executable(arch_select arch_select.cc) target_include_directories(srsran_common PUBLIC ${SEC_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR} ${BACKWARD_INCLUDE_DIRS}) -target_link_libraries(srsran_common srsran_phy srslog ${SEC_LIBRARIES} ${BACKWARD_LIBRARIES} ${SCTP_LIBRARIES}) +target_link_libraries(srsran_common srsran_phy support srslog ${SEC_LIBRARIES} ${BACKWARD_LIBRARIES} ${SCTP_LIBRARIES}) target_compile_definitions(srsran_common PRIVATE ${BACKWARD_DEFINITIONS}) INSTALL(TARGETS srsran_common DESTINATION ${LIBRARY_DIR}) diff --git a/lib/src/common/mac_pcap_base.cc b/lib/src/common/mac_pcap_base.cc index 48d825199..2a12110d7 100644 --- a/lib/src/common/mac_pcap_base.cc +++ b/lib/src/common/mac_pcap_base.cc @@ -11,9 +11,9 @@ */ #include "srsran/common/mac_pcap_base.h" -#include "srsran/common/emergency_handlers.h" #include "srsran/config.h" #include "srsran/phy/common/phy_common.h" +#include "srsran/support/emergency_handlers.h" #include namespace srsran { diff --git a/lib/src/common/s1ap_pcap.cc b/lib/src/common/s1ap_pcap.cc index e87e77ad9..3909673d4 100644 --- a/lib/src/common/s1ap_pcap.cc +++ b/lib/src/common/s1ap_pcap.cc @@ -11,9 +11,9 @@ */ #include "srsran/common/s1ap_pcap.h" -#include "srsran/common/emergency_handlers.h" #include "srsran/common/pcap.h" #include "srsran/srsran.h" +#include "srsran/support/emergency_handlers.h" #include namespace srsran { diff --git a/lib/src/support/CMakeLists.txt b/lib/src/support/CMakeLists.txt new file mode 100644 index 000000000..0be443c35 --- /dev/null +++ b/lib/src/support/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Copyright 2013-2021 Software Radio Systems Limited +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the distribution. +# + +set(SOURCES emergency_handlers.cc + signal_handler.cc) + +add_library(support STATIC ${SOURCES}) diff --git a/lib/src/common/emergency_handlers.cc b/lib/src/support/emergency_handlers.cc similarity index 97% rename from lib/src/common/emergency_handlers.cc rename to lib/src/support/emergency_handlers.cc index 3377153ac..b4e2cdc9a 100644 --- a/lib/src/common/emergency_handlers.cc +++ b/lib/src/support/emergency_handlers.cc @@ -10,7 +10,7 @@ * */ -#include "srsran/common/emergency_handlers.h" +#include "srsran/support/emergency_handlers.h" #include "srsran/support/srsran_assert.h" namespace { diff --git a/lib/include/srsran/common/signal_handler.h b/lib/src/support/signal_handler.cc similarity index 52% rename from lib/include/srsran/common/signal_handler.h rename to lib/src/support/signal_handler.cc index 36e48ebb2..33620d6cc 100644 --- a/lib/include/srsran/common/signal_handler.h +++ b/lib/src/support/signal_handler.cc @@ -10,28 +10,17 @@ * */ -/** - * @file signal_handler.h - * @brief Common signal handling methods for all srsRAN applications. - */ - -#ifndef SRSRAN_SIGNAL_HANDLER_H -#define SRSRAN_SIGNAL_HANDLER_H - -#include "srsran/common/emergency_handlers.h" -#include "srsran/srslog/sink.h" -#include "srsran/srslog/srslog.h" -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus +#include "srsran/support/signal_handler.h" +#include "srsran/support/emergency_handlers.h" +#include +#include +#include +#include #define SRSRAN_TERM_TIMEOUT_S (5) -// static vars required by signal handling -static std::atomic running = {true}; +/// Handler called after the user interrupts the program. +static std::atomic user_handler; static void srsran_signal_handler(int signal) { @@ -42,26 +31,24 @@ static void srsran_signal_handler(int signal) raise(SIGKILL); default: // all other registered signals try to stop the app gracefully - if (running) { - running = false; - fprintf(stdout, "Stopping ..\n"); - alarm(SRSRAN_TERM_TIMEOUT_S); + // Call the user handler if present and remove it so that further signals are treated by the default handler. + if (auto handler = user_handler.exchange(nullptr)) { + handler(); } else { - // already waiting for alarm to go off .. + return; } + fprintf(stdout, "Stopping ..\n"); + alarm(SRSRAN_TERM_TIMEOUT_S); break; } } -void srsran_register_signal_handler() +void srsran_register_signal_handler(srsran_signal_hanlder handler) { + user_handler.store(handler); + signal(SIGINT, srsran_signal_handler); signal(SIGTERM, srsran_signal_handler); signal(SIGHUP, srsran_signal_handler); signal(SIGALRM, srsran_signal_handler); } - -#ifdef __cplusplus -} -#endif // __cplusplus -#endif // SRSRAN_SIGNAL_HANDLER_H diff --git a/srsenb/src/CMakeLists.txt b/srsenb/src/CMakeLists.txt index 67224468b..e4e26793d 100644 --- a/srsenb/src/CMakeLists.txt +++ b/srsenb/src/CMakeLists.txt @@ -27,7 +27,7 @@ target_link_libraries(enb_cfg_parser srsran_common ${LIBCONFIGPP_LIBRARIES}) add_executable(srsenb main.cc enb.cc metrics_stdout.cc metrics_csv.cc metrics_json.cc) set(SRSENB_SOURCES srsenb_phy srsenb_stack srsenb_common srsenb_s1ap srsenb_upper srsenb_mac srsenb_rrc srslog system) -set(SRSRAN_SOURCES srsran_common srsran_mac srsran_phy srsran_gtpu srsran_rlc srsran_pdcp srsran_radio rrc_asn1 s1ap_asn1 enb_cfg_parser srslog system) +set(SRSRAN_SOURCES srsran_common srsran_mac srsran_phy srsran_gtpu srsran_rlc srsran_pdcp srsran_radio rrc_asn1 s1ap_asn1 enb_cfg_parser srslog support system) set(SRSENB_SOURCES ${SRSENB_SOURCES} srsgnb_stack srsgnb_ngap srsgnb_upper srsgnb_mac srsgnb_rrc) set(SRSRAN_SOURCES ${SRSRAN_SOURCES} rrc_nr_asn1 ngap_nr_asn1) diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index d2c69a83b..118444b1d 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -20,10 +20,11 @@ #include "srsran/common/common_helper.h" #include "srsran/common/config_file.h" #include "srsran/common/crash_handler.h" -#include "srsran/common/signal_handler.h" #include "srsran/common/tsan_options.h" #include "srsran/srslog/event_trace.h" #include "srsran/srslog/srslog.h" +#include "srsran/support/emergency_handlers.h" +#include "srsran/support/signal_handler.h" #include #include @@ -45,9 +46,10 @@ namespace bpo = boost::program_options; /********************************************************************** * Program arguments processing ***********************************************************************/ -string config_file; -static bool stdout_ts_enable = false; -static srslog::sink* log_sink = nullptr; +string config_file; +static bool stdout_ts_enable = false; +static srslog::sink* log_sink = nullptr; +static std::atomic running = {true}; void parse_args(all_args_t* args, int argc, char* argv[]) { @@ -545,9 +547,14 @@ static void emergency_cleanup_handler(void* data) srsran_dft_exit(); } +static void signal_handler() +{ + running = false; +} + int main(int argc, char* argv[]) { - srsran_register_signal_handler(); + srsran_register_signal_handler(signal_handler); add_emergency_cleanup_handler(emergency_cleanup_handler, nullptr); all_args_t args = {}; diff --git a/srsepc/src/CMakeLists.txt b/srsepc/src/CMakeLists.txt index fac9a9ca5..b88e0517c 100644 --- a/srsepc/src/CMakeLists.txt +++ b/srsepc/src/CMakeLists.txt @@ -31,6 +31,7 @@ target_link_libraries( srsepc srsepc_mme srsran_asn1 srsran_common srslog + support ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} ${SEC_LIBRARIES} diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index 62e2fce09..c2ace4cb2 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -18,9 +18,10 @@ #include "srsran/common/common_helper.h" #include "srsran/common/config_file.h" #include "srsran/common/crash_handler.h" -#include "srsran/common/signal_handler.h" #include "srsran/srslog/srslog.h" #include "srsran/srsran.h" +#include "srsran/support/emergency_handlers.h" +#include "srsran/support/signal_handler.h" #include #include @@ -55,7 +56,8 @@ typedef struct { log_args_t log_args; } all_args_t; -static srslog::sink* log_sink = nullptr; +static srslog::sink* log_sink = nullptr; +static std::atomic running = {true}; /********************************************************************** * Program arguments processing @@ -363,9 +365,14 @@ static void emergency_cleanup_handler(void* data) } } +static void signal_handler() +{ + running = false; +} + int main(int argc, char* argv[]) { - srsran_register_signal_handler(); + srsran_register_signal_handler(signal_handler); add_emergency_cleanup_handler(emergency_cleanup_handler, nullptr); // print build info diff --git a/srsue/src/CMakeLists.txt b/srsue/src/CMakeLists.txt index 7b37cff78..8b4043623 100644 --- a/srsue/src/CMakeLists.txt +++ b/srsue/src/CMakeLists.txt @@ -22,7 +22,7 @@ endif (RPATH) add_executable(srsue main.cc ue.cc metrics_stdout.cc metrics_csv.cc metrics_json.cc) set(SRSUE_SOURCES srsue_phy srsue_stack srsue_upper srsue_mac srsue_rrc srslog system) -set(SRSRAN_SOURCES srsran_common srsran_mac srsran_phy srsran_radio srsran_gtpu srsran_rlc srsran_pdcp rrc_asn1 srslog system) +set(SRSRAN_SOURCES srsran_common srsran_mac srsran_phy srsran_radio srsran_gtpu srsran_rlc srsran_pdcp rrc_asn1 srslog support system) set(SRSUE_SOURCES ${SRSUE_SOURCES} srsue_nr_stack srsue_rrc_nr srsue_mac_nr) set(SRSRAN_SOURCES ${SRSRAN_SOURCES} rrc_nr_asn1 ngap_nr_asn1) diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 7a9de3f76..b80f8a292 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -15,11 +15,12 @@ #include "srsran/common/crash_handler.h" #include "srsran/common/metrics_hub.h" #include "srsran/common/multiqueue.h" -#include "srsran/common/signal_handler.h" #include "srsran/common/tsan_options.h" #include "srsran/srslog/event_trace.h" #include "srsran/srslog/srslog.h" #include "srsran/srsran.h" +#include "srsran/support/emergency_handlers.h" +#include "srsran/support/signal_handler.h" #include "srsran/version.h" #include "srsue/hdr/metrics_csv.h" #include "srsue/hdr/metrics_json.h" @@ -27,6 +28,7 @@ #include "srsue/hdr/ue.h" #include #include +#include #include #include #include @@ -45,9 +47,10 @@ namespace bpo = boost::program_options; * Local static variables ***********************************************************************/ -static bool do_metrics = false; -static metrics_stdout* metrics_screen = nullptr; -static srslog::sink* log_sink = nullptr; +static bool do_metrics = false; +static metrics_stdout* metrics_screen = nullptr; +static srslog::sink* log_sink = nullptr; +static std::atomic running = {true}; /********************************************************************** * Program arguments processing @@ -667,9 +670,14 @@ static void emergency_cleanup_handler(void* data) srsran_dft_exit(); } +static void signal_handler() +{ + running = false; +} + int main(int argc, char* argv[]) { - srsran_register_signal_handler(); + srsran_register_signal_handler(signal_handler); add_emergency_cleanup_handler(emergency_cleanup_handler, nullptr); srsran_debug_handle_crash(argc, argv); From 73260fb3358325cf39d908dbb47c151cbb0917b2 Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 15 Oct 2021 10:14:33 +0100 Subject: [PATCH 157/208] sched,nr: fix stack overflow in sched_nr_test --- srsenb/src/stack/mac/nr/sched_nr.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/srsenb/src/stack/mac/nr/sched_nr.cc b/srsenb/src/stack/mac/nr/sched_nr.cc index 63c56220d..b0acfabf4 100644 --- a/srsenb/src/stack/mac/nr/sched_nr.cc +++ b/srsenb/src/stack/mac/nr/sched_nr.cc @@ -140,7 +140,8 @@ int sched_nr::get_ul_sched(slot_point slot_ul, uint32_t cc, ul_sched_t& result) { if (not pending_results->has_ul_result(slot_ul, cc)) { // sched result hasn't been generated - result = {}; + result.pucch.clear(); + result.pusch.clear(); return SRSRAN_SUCCESS; } From 003c6e524cfb2fa48e47f823f41147982ce70183 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 13 Oct 2021 11:39:12 +0200 Subject: [PATCH 158/208] Added short NR CSI information --- lib/include/srsran/phy/common/phy_common_nr.h | 11 ++++++++++- lib/src/phy/common/phy_common_nr.c | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/include/srsran/phy/common/phy_common_nr.h b/lib/include/srsran/phy/common/phy_common_nr.h index 7347ce934..059674a89 100644 --- a/lib/include/srsran/phy/common/phy_common_nr.h +++ b/lib/include/srsran/phy/common/phy_common_nr.h @@ -645,7 +645,7 @@ SRSRAN_API bool srsran_duplex_nr_is_ul(const srsran_duplex_config_nr_t* cfg, uin SRSRAN_API int srsran_carrier_to_cell(const srsran_carrier_nr_t* carrier, srsran_cell_t* cell); /** - * @brief Writes Channel State Information measurement into a string + * @brief Writes detailed Channel State Information measurement into a string * @param meas Provides the measurement * @param str Provides string * @param str_len Maximum string length @@ -653,6 +653,15 @@ SRSRAN_API int srsran_carrier_to_cell(const srsran_carrier_nr_t* carrier, srsran */ SRSRAN_API uint32_t srsran_csi_meas_info(const srsran_csi_trs_measurements_t* meas, char* str, uint32_t str_len); +/** + * @brief Writes short Channel State Information measurement into a string + * @param meas Provides the measurement + * @param str Provides string + * @param str_len Maximum string length + * @return The number of writen characters + */ +SRSRAN_API uint32_t srsran_csi_meas_info_short(const srsran_csi_trs_measurements_t* meas, char* str, uint32_t str_len); + /** * @brief Converts a given string into a subcarrier spacing * @param str Provides the string diff --git a/lib/src/phy/common/phy_common_nr.c b/lib/src/phy/common/phy_common_nr.c index 253b6618d..af1703f06 100644 --- a/lib/src/phy/common/phy_common_nr.c +++ b/lib/src/phy/common/phy_common_nr.c @@ -434,6 +434,22 @@ uint32_t srsran_csi_meas_info(const srsran_csi_trs_measurements_t* meas, char* s meas->delay_us); } +uint32_t srsran_csi_meas_info_short(const srsran_csi_trs_measurements_t* meas, char* str, uint32_t str_len) +{ + if (meas == NULL || str == NULL || str_len == 0) { + return 0; + } + + return srsran_print_check(str, + str_len, + 0, + "epre=%+.1f snr=%+.1f cfo=%+.1f delay=%+.1f ", + meas->epre_dB, + meas->snr_dB, + meas->cfo_hz, + meas->delay_us); +} + srsran_subcarrier_spacing_t srsran_subcarrier_spacing_from_str(const char* str) { if (str == NULL) { From a5f6aa9f31a27f2dec53cabe8f3aff9fc348f18a Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 13 Oct 2021 11:42:00 +0200 Subject: [PATCH 159/208] Added CSI string in PDSCH and PUSCH decode --- lib/include/srsran/phy/ue/ue_dl_nr.h | 10 +++++----- lib/src/phy/gnb/gnb_ul.c | 3 ++- lib/src/phy/phch/pdsch_nr.c | 4 ++++ lib/src/phy/phch/pusch_nr.c | 4 ++++ lib/src/phy/ue/ue_dl_nr.c | 16 ++++++++-------- srsenb/src/phy/nr/slot_worker.cc | 2 +- 6 files changed, 24 insertions(+), 15 deletions(-) diff --git a/lib/include/srsran/phy/ue/ue_dl_nr.h b/lib/include/srsran/phy/ue/ue_dl_nr.h index f1f1240ce..4bd69e5da 100644 --- a/lib/include/srsran/phy/ue/ue_dl_nr.h +++ b/lib/include/srsran/phy/ue/ue_dl_nr.h @@ -112,11 +112,11 @@ SRSRAN_API int srsran_ue_dl_nr_decode_pdsch(srsran_ue_dl_nr_t* q, const srsran_sch_cfg_nr_t* cfg, srsran_pdsch_res_nr_t* res); -SRSRAN_API int srsran_ue_dl_nr_pdsch_info(const srsran_ue_dl_nr_t* q, - const srsran_sch_cfg_nr_t* cfg, - const srsran_pdsch_res_nr_t res[SRSRAN_MAX_CODEWORDS], - char* str, - uint32_t str_len); +SRSRAN_API uint32_t srsran_ue_dl_nr_pdsch_info(const srsran_ue_dl_nr_t* q, + const srsran_sch_cfg_nr_t* cfg, + const srsran_pdsch_res_nr_t res[SRSRAN_MAX_CODEWORDS], + char* str, + uint32_t str_len); SRSRAN_API int srsran_ue_dl_nr_csi_measure_trs(const srsran_ue_dl_nr_t* q, diff --git a/lib/src/phy/gnb/gnb_ul.c b/lib/src/phy/gnb/gnb_ul.c index 94259e69b..bf09799d5 100644 --- a/lib/src/phy/gnb/gnb_ul.c +++ b/lib/src/phy/gnb/gnb_ul.c @@ -333,7 +333,8 @@ uint32_t srsran_gnb_ul_pusch_info(srsran_gnb_ul_t* q, len += srsran_pusch_nr_rx_info(&q->pusch, cfg, &cfg->grant, res, str, str_len - len); - len = srsran_print_check(str, str_len, len, "snr=%+.1f", q->chest_pusch.snr_db); + // Append channel estimator info + len += srsran_csi_meas_info_short(&q->dmrs.csi, &str[len], str_len - len); return len; } \ No newline at end of file diff --git a/lib/src/phy/phch/pdsch_nr.c b/lib/src/phy/phch/pdsch_nr.c index b047b1ceb..22076a106 100644 --- a/lib/src/phy/phch/pdsch_nr.c +++ b/lib/src/phy/phch/pdsch_nr.c @@ -568,6 +568,10 @@ static uint32_t pdsch_nr_grant_info(const srsran_pdsch_nr_t* q, } } + // Append RNTI type and id + len = + srsran_print_check(str, str_len, len, "%s-rnti=0x%x ", srsran_rnti_type_str_short(grant->rnti_type), grant->rnti); + // Append time-domain resource mapping len = srsran_print_check(str, str_len, diff --git a/lib/src/phy/phch/pusch_nr.c b/lib/src/phy/phch/pusch_nr.c index 9950a57a4..c7ab719d7 100644 --- a/lib/src/phy/phch/pusch_nr.c +++ b/lib/src/phy/phch/pusch_nr.c @@ -1010,6 +1010,10 @@ static uint32_t pusch_nr_grant_info(const srsran_pusch_nr_t* q, } } + // Append RNTI type and id + len = + srsran_print_check(str, str_len, len, "%s-rnti=0x%x ", srsran_rnti_type_str_short(grant->rnti_type), grant->rnti); + // Append time-domain resource mapping len = srsran_print_check(str, str_len, diff --git a/lib/src/phy/ue/ue_dl_nr.c b/lib/src/phy/ue/ue_dl_nr.c index e83fdf474..fb0a851f7 100644 --- a/lib/src/phy/ue/ue_dl_nr.c +++ b/lib/src/phy/ue/ue_dl_nr.c @@ -375,7 +375,7 @@ static int ue_dl_nr_find_dci_ss(srsran_ue_dl_nr_t* q, // Calculate possible PDCCH DCI candidates uint32_t candidates[SRSRAN_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR] = {}; int nof_candidates = srsran_pdcch_nr_locations_coreset( - coreset, search_space, rnti, L, SRSRAN_SLOT_NR_MOD(q->carrier.scs, slot_cfg->idx), candidates); + coreset, search_space, rnti, L, SRSRAN_SLOT_NR_MOD(q->carrier.scs, slot_cfg->idx), candidates); if (nof_candidates < SRSRAN_SUCCESS) { ERROR("Error calculating DCI candidate location"); return SRSRAN_ERROR; @@ -576,19 +576,19 @@ int srsran_ue_dl_nr_decode_pdsch(srsran_ue_dl_nr_t* q, return SRSRAN_SUCCESS; } -int srsran_ue_dl_nr_pdsch_info(const srsran_ue_dl_nr_t* q, - const srsran_sch_cfg_nr_t* cfg, - const srsran_pdsch_res_nr_t res[SRSRAN_MAX_CODEWORDS], - char* str, - uint32_t str_len) +uint32_t srsran_ue_dl_nr_pdsch_info(const srsran_ue_dl_nr_t* q, + const srsran_sch_cfg_nr_t* cfg, + const srsran_pdsch_res_nr_t res[SRSRAN_MAX_CODEWORDS], + char* str, + uint32_t str_len) { - int len = 0; + uint32_t len = 0; // Append PDSCH info len += srsran_pdsch_nr_rx_info(&q->pdsch, cfg, &cfg->grant, res, &str[len], str_len - len); // Append channel estimator info - len = srsran_print_check(str, str_len, len, "SNR=%+.1f", q->chest.snr_db); + len += srsran_csi_meas_info_short(&q->dmrs_pdsch.csi, &str[len], str_len - len); return len; } diff --git a/srsenb/src/phy/nr/slot_worker.cc b/srsenb/src/phy/nr/slot_worker.cc index 2ff2880c1..dbdf5d5f7 100644 --- a/srsenb/src/phy/nr/slot_worker.cc +++ b/srsenb/src/phy/nr/slot_worker.cc @@ -239,7 +239,7 @@ bool slot_worker::work_ul() srsran_gnb_ul_pusch_info(&gnb_ul, &pusch.sch, &pusch_info.pusch_data, str.data(), (uint32_t)str.size()); if (logger.debug.enabled()) { - std::array str_extra; + std::array str_extra = {}; srsran_sch_cfg_nr_info(&pusch.sch, str_extra.data(), (uint32_t)str_extra.size()); logger.info("PUSCH: %s\n%s", str.data(), str_extra.data()); } else { From 51ff429bc78ed83c7162392721b7a1d4fbf76a6e Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 13 Oct 2021 12:55:24 +0200 Subject: [PATCH 160/208] Added SS type to PDSCH context info --- lib/src/phy/phch/dci_nr.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/src/phy/phch/dci_nr.c b/lib/src/phy/phch/dci_nr.c index f18656c0e..f52ec4fe9 100644 --- a/lib/src/phy/phch/dci_nr.c +++ b/lib/src/phy/phch/dci_nr.c @@ -2072,10 +2072,11 @@ uint32_t srsran_dci_ctx_to_str(const srsran_dci_ctx_t* ctx, char* str, uint32_t len = srsran_print_check(str, str_len, len, - "%s-rnti=%04x dci=%s ", + "%s-rnti=%04x dci=%s ss=%s", srsran_rnti_type_str_short(ctx->rnti_type), ctx->rnti, - srsran_dci_format_nr_string(ctx->format)); + srsran_dci_format_nr_string(ctx->format), + srsran_ss_type_str(ctx->ss_type)); if (ctx->format != srsran_dci_format_nr_rar) { len = srsran_print_check(str, str_len, len, "L=%d cce=%d ", ctx->location.L, ctx->location.ncce); From e6bd6462b19df8c678a9de16cb35156fed107a8a Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 13 Oct 2021 17:04:46 +0200 Subject: [PATCH 161/208] Estimate CFO for NR PUCCH formats 0 and 1 --- lib/src/phy/ch_estimation/dmrs_pucch.c | 58 +++++++++++++++++++++----- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/lib/src/phy/ch_estimation/dmrs_pucch.c b/lib/src/phy/ch_estimation/dmrs_pucch.c index cae4cac58..bbe046519 100644 --- a/lib/src/phy/ch_estimation/dmrs_pucch.c +++ b/lib/src/phy/ch_estimation/dmrs_pucch.c @@ -14,6 +14,7 @@ #include "srsran/phy/common/sequence.h" #include "srsran/phy/utils/debug.h" #include "srsran/phy/utils/vector.h" +#include // Implements TS 38.211 table 6.4.1.3.1.1-1: Number of DM-RS symbols and the corresponding N_PUCCH... static uint32_t dmrs_pucch_format1_n_pucch(const srsran_pucch_nr_resource_t* resource, uint32_t m_prime) @@ -217,12 +218,13 @@ int srsran_dmrs_pucch_format1_estimate(const srsran_pucch_nr_t* q, } // Perform measurements - float rsrp = 0.0f; - float epre = 0.0f; - float ta_err = 0.0f; + float rsrp = 0.0f; + float epre = 0.0f; + float ta_err = 0.0f; + cf_t corr[SRSRAN_PUCCH_NR_FORMAT1_N_MAX] = {}; for (uint32_t m = 0; m < n_pucch; m++) { - cf_t corr = srsran_vec_acc_cc(ce[m], SRSRAN_NRE) / SRSRAN_NRE; - rsrp += __real__ corr * __real__ corr + __imag__ corr * __imag__ corr; + corr[m] = srsran_vec_acc_cc(ce[m], SRSRAN_NRE) / SRSRAN_NRE; + rsrp += SRSRAN_CSQABS(corr[m]); epre += srsran_vec_avg_power_cf(ce[m], SRSRAN_NRE); ta_err += srsran_vec_estimate_frequency(ce[m], SRSRAN_NRE); } @@ -254,7 +256,22 @@ int srsran_dmrs_pucch_format1_estimate(const srsran_pucch_nr_t* q, } // Measure CFO - res->cfo_hz = NAN; // Not implemented + if (n_pucch > 1) { + float cfo_avg_hz = 0.0f; + for (uint32_t m = 0; m < n_pucch - 1; m++) { + uint32_t l0 = resource->start_symbol_idx + m * 2; + uint32_t l1 = resource->start_symbol_idx + (m + 1) * 2; + float time_diff = srsran_symbol_distance_s(l0, l1, q->carrier.scs); + float phase_diff = cargf(corr[m + 1] * conjf(corr[m])); + + if (isnormal(time_diff)) { + cfo_avg_hz += phase_diff / (2.0f * M_PI * time_diff * (n_pucch - 1)); + } + } + res->cfo_hz = cfo_avg_hz; + } else { + res->cfo_hz = NAN; // Not implemented + } // Do averaging here // ... Not implemented @@ -379,12 +396,13 @@ int srsran_dmrs_pucch_format2_estimate(const srsran_pucch_nr_t* q, } // Perform measurements - float epre = 0.0f; - float rsrp = 0.0f; - float ta_err = 0.0f; + float epre = 0.0f; + float rsrp = 0.0f; + float ta_err = 0.0f; + cf_t corr[SRSRAN_PUCCH_NR_FORMAT2_MAX_NSYMB] = {}; for (uint32_t i = 0; i < resource->nof_symbols; i++) { - cf_t corr = srsran_vec_acc_cc(ce[i], nof_ref) / nof_ref; - rsrp += __real__ corr * __real__ corr + __imag__ corr * __imag__ corr; + corr[i] = srsran_vec_acc_cc(ce[i], nof_ref) / nof_ref; + rsrp += SRSRAN_CSQABS(corr[i]); epre += srsran_vec_avg_power_cf(ce[i], nof_ref); ta_err += srsran_vec_estimate_frequency(ce[i], nof_ref); } @@ -413,6 +431,24 @@ int srsran_dmrs_pucch_format2_estimate(const srsran_pucch_nr_t* q, res->ta_us = 0.0f; } + // Measure CFO + if (resource->nof_symbols > 1) { + float cfo_avg_hz = 0.0f; + for (uint32_t l = 0; l < resource->nof_symbols - 1; l++) { + uint32_t l0 = resource->start_symbol_idx + l; + uint32_t l1 = resource->start_symbol_idx + l + 1; + float time_diff = srsran_symbol_distance_s(l0, l1, q->carrier.scs); + float phase_diff = cargf(corr[l + 1] * conjf(corr[l])); + + if (isnormal(time_diff)) { + cfo_avg_hz += phase_diff / (2.0f * M_PI * time_diff * (resource->nof_symbols - 1)); + } + } + res->cfo_hz = cfo_avg_hz; + } else { + res->cfo_hz = NAN; // Not implemented + } + // Perform averaging // ... From addd687d7ea9a72f2c12a3f5a033af8f6abb760d Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 13 Oct 2021 17:06:01 +0200 Subject: [PATCH 162/208] Fix NR PUCCH format 1 normalised correlation --- lib/src/phy/phch/pucch_nr.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/src/phy/phch/pucch_nr.c b/lib/src/phy/phch/pucch_nr.c index 926db626a..931fbf27a 100644 --- a/lib/src/phy/phch/pucch_nr.c +++ b/lib/src/phy/phch/pucch_nr.c @@ -472,8 +472,9 @@ int srsran_pucch_nr_format1_decode(srsran_pucch_nr_t* q, return SRSRAN_ERROR; } - // Received symbol d - cf_t d = 0; + // Accumulates received symbol d and average power + cf_t d = 0; + float pwr_acc = 0.0f; // Get group sequence uint32_t u = 0; @@ -517,7 +518,10 @@ int srsran_pucch_nr_format1_decode(srsran_pucch_nr_t* q, srsran_vec_sc_prod_ccc(r_uv, w_i_m, z, SRSRAN_NRE); // Compute d = sum(x * conj(w(i) * r_uv(n))) = sum(w(i) * d' * r_uv(n) * conj(w(i) * r_uv(n))) = d' - d += srsran_vec_dot_prod_conj_ccc(x, z, SRSRAN_NRE); + d += srsran_vec_dot_prod_conj_ccc(x, z, SRSRAN_NRE) / SRSRAN_NRE; + + // Compute and accumulate average symbol power + pwr_acc += srsran_vec_avg_power_cf(x, SRSRAN_NRE); } // Demodulate d @@ -525,14 +529,18 @@ int srsran_pucch_nr_format1_decode(srsran_pucch_nr_t* q, srsran_demod_soft_demodulate((nof_bits == 1) ? SRSRAN_MOD_BPSK : SRSRAN_MOD_QPSK, &d, llr, 1); // Hard decision - float corr = 0.0f; for (uint32_t i = 0; i < nof_bits; i++) { b[i] = llr[i] > 0.0f ? 1 : 0; - corr += fabsf(llr[i]); } - if (norm_corr != NULL && nof_bits > 0) { - *norm_corr = corr / nof_bits; + // Calculate normalised correlation, it uses the absolute value of d and accumulated average power + if (norm_corr != NULL) { + float nsymb = (float)SRSRAN_CEIL(resource->nof_symbols, 2); + if (isnormal(pwr_acc) && isnormal(nsymb)) { + *norm_corr = cabsf(d) / sqrtf(pwr_acc * nsymb); + } else { + *norm_corr = 0.0f; + } } return SRSRAN_SUCCESS; From b3a844c53395c898a0bddda693177d34425b1566 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 13 Oct 2021 17:08:41 +0200 Subject: [PATCH 163/208] Removed redundant metric trace and add PUCCH SNR assertion --- test/phy/nr_phy_test.cc | 48 ++++++----------------------------------- 1 file changed, 6 insertions(+), 42 deletions(-) diff --git a/test/phy/nr_phy_test.cc b/test/phy/nr_phy_test.cc index 9a7122313..5dde6052c 100644 --- a/test/phy/nr_phy_test.cc +++ b/test/phy/nr_phy_test.cc @@ -28,6 +28,7 @@ static double assert_pdsch_bler_max = 0.000; static double assert_prach_detection_min = 1.000; static double assert_prach_ta_min = 0.000; static double assert_prach_ta_max = 0.000; +static double assert_pucch_snr_min = 0.000; test_bench::args_t::args_t(int argc, char** argv) { @@ -101,6 +102,7 @@ test_bench::args_t::args_t(int argc, char** argv) ("assert.pdsch.bler.max", bpo::value(&assert_pdsch_bler_max)->default_value(assert_pdsch_bler_max), "PDSCH maximum BLER threshold") ("assert.prach.ta.min", bpo::value(&assert_prach_ta_min)->default_value(assert_prach_ta_min), "PRACH estimated TA minimum value threshold") ("assert.prach.ta.max", bpo::value(&assert_prach_ta_max)->default_value(assert_prach_ta_max), "PRACH estimated TA maximum value threshold") + ("assert.pucch.snr.min", bpo::value(&assert_pucch_snr_min)->default_value(assert_pucch_snr_min), "PUCCH DMRS minimum SNR allowed threshold") ; options.add(options_gnb_stack).add(options_gnb_phy).add(options_ue_stack).add(options_ue_phy).add_options() @@ -197,48 +199,6 @@ int main(int argc, char** argv) // Retrieve MAC metrics test_bench::metrics_t metrics = tb.get_metrics(); - // Print PDSCH metrics if scheduled - if (metrics.gnb_stack.mac.tx_pkts > 0) { - float pdsch_bler = 0.0f; - pdsch_bler = (float)metrics.gnb_stack.mac.tx_errors / (float)metrics.gnb_stack.mac.tx_pkts; - - float pdsch_shed_rate = 0.0f; - pdsch_shed_rate = (float)metrics.gnb_stack.mac.tx_brate / (float)metrics.gnb_stack.mac.tx_pkts / 1000.0f; - float decode_iterations = metrics.ue_phy.dl[0].fec_iters; - float ue_snr = metrics.ue_phy.ch[0].sinr; - - srsran::console("PDSCH:\n"); - srsran::console(" Count: %d\n", metrics.gnb_stack.mac.tx_pkts); - srsran::console(" BLER: %f\n", pdsch_bler); - srsran::console(" Sched Rate: %f Mbps\n", pdsch_shed_rate); - srsran::console(" Net Rate: %f Mbps\n", (1.0f - pdsch_bler) * pdsch_shed_rate); - srsran::console(" Retx Rate: %f Mbps\n", pdsch_bler * pdsch_shed_rate); - srsran::console(" Measured SNR: %f dB\n", ue_snr); - srsran::console(" Dec Iterations: %f\n", decode_iterations); - srsran::console("\n"); - } - - // Print PUSCH metrics if scheduled - if (metrics.gnb_stack.mac.rx_pkts > 0) { - float pusch_bler = 0.0f; - if (metrics.gnb_stack.mac.rx_pkts != 0) { - pusch_bler = (float)metrics.gnb_stack.mac.rx_errors / (float)metrics.gnb_stack.mac.rx_pkts; - } - - float pusch_shed_rate = 0.0f; - if (metrics.gnb_stack.mac.rx_pkts != 0) { - pusch_shed_rate = (float)metrics.gnb_stack.mac.rx_brate / (float)metrics.gnb_stack.mac.rx_pkts / 1000.0f; - } - - srsran::console("PUSCH:\n"); - srsran::console(" Count: %d\n", metrics.gnb_stack.mac.rx_pkts); - srsran::console(" BLER: %f\n", pusch_bler); - srsran::console(" Sched Rate: %f Mbps\n", pusch_shed_rate); - srsran::console(" Net Rate: %f Mbps\n", (1.0f - pusch_bler) * pusch_shed_rate); - srsran::console(" Retx Rate: %f Mbps\n", pusch_bler * pusch_shed_rate); - srsran::console("\n"); - } - // Print PRACH double prach_detection = 0.0; double prach_ta = 0.0; @@ -448,6 +408,10 @@ int main(int argc, char** argv) prach_ta, assert_prach_ta_min, assert_prach_ta_max); + srsran_assert(metrics.gnb_stack.pucch.count == 0 or (metrics.gnb_stack.pucch.snr_db_min >= assert_pucch_snr_min), + "Minimum PUCCH DMRS SNR %f is below the minimum (%d)", + metrics.gnb_stack.pucch.snr_db_min, + assert_pucch_snr_min); // If reached here, the test is successful return SRSRAN_SUCCESS; From 3c40cd2840bc9815b4fa1482c27354eed6fa9eef Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 13 Oct 2021 17:10:15 +0200 Subject: [PATCH 164/208] Improved NR PHY logging info --- lib/include/srsran/phy/gnb/gnb_ul.h | 11 ++++++----- lib/src/phy/gnb/gnb_ul.c | 18 ++++++++++-------- lib/src/phy/phch/dci_nr.c | 2 +- srsenb/src/phy/nr/slot_worker.cc | 1 + srsue/src/phy/nr/cc_worker.cc | 25 +++++++++---------------- 5 files changed, 27 insertions(+), 30 deletions(-) diff --git a/lib/include/srsran/phy/gnb/gnb_ul.h b/lib/include/srsran/phy/gnb/gnb_ul.h index 95c37116e..424d068dd 100644 --- a/lib/include/srsran/phy/gnb/gnb_ul.h +++ b/lib/include/srsran/phy/gnb/gnb_ul.h @@ -60,11 +60,12 @@ SRSRAN_API int srsran_gnb_ul_get_pucch(srsran_gnb_ul_t* q, srsran_uci_value_nr_t* uci_value, srsran_csi_trs_measurements_t* meas); -SRSRAN_API uint32_t srsran_gnb_ul_pucch_info(srsran_gnb_ul_t* q, - const srsran_pucch_nr_resource_t* resource, - const srsran_uci_data_nr_t* uci_data, - char* str, - uint32_t str_len); +SRSRAN_API uint32_t srsran_gnb_ul_pucch_info(srsran_gnb_ul_t* q, + const srsran_pucch_nr_resource_t* resource, + const srsran_uci_data_nr_t* uci_data, + const srsran_csi_trs_measurements_t* csi, + char* str, + uint32_t str_len); SRSRAN_API uint32_t srsran_gnb_ul_pusch_info(srsran_gnb_ul_t* q, const srsran_sch_cfg_nr_t* cfg, diff --git a/lib/src/phy/gnb/gnb_ul.c b/lib/src/phy/gnb/gnb_ul.c index bf09799d5..7e2c48847 100644 --- a/lib/src/phy/gnb/gnb_ul.c +++ b/lib/src/phy/gnb/gnb_ul.c @@ -299,11 +299,12 @@ int srsran_gnb_ul_get_pucch(srsran_gnb_ul_t* q, return SRSRAN_SUCCESS; } -uint32_t srsran_gnb_ul_pucch_info(srsran_gnb_ul_t* q, - const srsran_pucch_nr_resource_t* resource, - const srsran_uci_data_nr_t* uci_data, - char* str, - uint32_t str_len) +uint32_t srsran_gnb_ul_pucch_info(srsran_gnb_ul_t* q, + const srsran_pucch_nr_resource_t* resource, + const srsran_uci_data_nr_t* uci_data, + const srsran_csi_trs_measurements_t* csi, + char* str, + uint32_t str_len) { if (q == NULL || uci_data == NULL) { return 0; @@ -311,10 +312,11 @@ uint32_t srsran_gnb_ul_pucch_info(srsran_gnb_ul_t* q, uint32_t len = 0; - len += srsran_pucch_nr_info(resource, uci_data, str, str_len - len); + len += srsran_pucch_nr_info(resource, uci_data, &str[len], str_len - len); - len = srsran_print_check( - str, str_len, len, "snr=%+.1f valid=%c", q->chest_pucch.snr_db, uci_data->value.valid ? 'y' : 'n'); + len += srsran_csi_meas_info_short(csi, &str[len], str_len - len); + + len = srsran_print_check(str, str_len, len, "valid=%c ", uci_data->value.valid ? 'y' : 'n'); return len; } diff --git a/lib/src/phy/phch/dci_nr.c b/lib/src/phy/phch/dci_nr.c index f52ec4fe9..33ebbbcf4 100644 --- a/lib/src/phy/phch/dci_nr.c +++ b/lib/src/phy/phch/dci_nr.c @@ -2072,7 +2072,7 @@ uint32_t srsran_dci_ctx_to_str(const srsran_dci_ctx_t* ctx, char* str, uint32_t len = srsran_print_check(str, str_len, len, - "%s-rnti=%04x dci=%s ss=%s", + "%s-rnti=%04x dci=%s ss=%s ", srsran_rnti_type_str_short(ctx->rnti_type), ctx->rnti, srsran_dci_format_nr_string(ctx->format), diff --git a/srsenb/src/phy/nr/slot_worker.cc b/srsenb/src/phy/nr/slot_worker.cc index dbdf5d5f7..efad85c8b 100644 --- a/srsenb/src/phy/nr/slot_worker.cc +++ b/srsenb/src/phy/nr/slot_worker.cc @@ -195,6 +195,7 @@ bool slot_worker::work_ul() srsran_gnb_ul_pucch_info(&gnb_ul, &pucch.candidates[0].resource, &pucch_info[best_candidate].uci_data, + &pucch_info[best_candidate].csi, str.data(), (uint32_t)str.size()); diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index ec887cceb..46c26c11c 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -161,22 +161,15 @@ void cc_worker::decode_pdcch_dl() if (logger.debug.enabled()) { for (uint32_t i = 0; i < ue_dl.pdcch_info_count; i++) { const srsran_ue_dl_nr_pdcch_info_t* info = &ue_dl.pdcch_info[i]; - logger.debug( - "PDCCH: dci=%s, %s-rnti=%x, crst_id=%d, ss_type=%s, ncce=%d, al=%d, EPRE=%+.2f, RSRP=%+.2f, corr=%.3f; " - "evm=%f; nof_bits=%d; crc=%s;", - srsran_dci_format_nr_string(info->dci_ctx.format), - srsran_rnti_type_str_short(info->dci_ctx.rnti_type), - info->dci_ctx.rnti, - info->dci_ctx.coreset_id, - srsran_ss_type_str(info->dci_ctx.ss_type), - info->dci_ctx.location.ncce, - info->dci_ctx.location.L, - info->measure.epre_dBfs, - info->measure.rsrp_dBfs, - info->measure.norm_corr, - info->result.evm, - info->nof_bits, - info->result.crc ? "OK" : "KO"); + std::array dci_ctx; + srsran_dci_ctx_to_str(&info->dci_ctx, dci_ctx.data(), (uint32_t)dci_ctx.size()); + logger.debug("PDCCH: %sEPRE=%+.2f, RSRP=%+.2f, corr=%.3f nof_bits=%d crc=%s", + dci_ctx.data(), + info->measure.epre_dBfs, + info->measure.rsrp_dBfs, + info->measure.norm_corr, + info->nof_bits, + info->result.crc ? "OK" : "KO"); } } } From bdcf90d99008e6edb050c23fff43aca9839a8297 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 13 Oct 2021 17:11:14 +0200 Subject: [PATCH 165/208] Enable NR PUSCH EVM estimation in srsenb --- srsenb/src/phy/nr/slot_worker.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsenb/src/phy/nr/slot_worker.cc b/srsenb/src/phy/nr/slot_worker.cc index efad85c8b..fc835c0b7 100644 --- a/srsenb/src/phy/nr/slot_worker.cc +++ b/srsenb/src/phy/nr/slot_worker.cc @@ -74,6 +74,7 @@ bool slot_worker::init(const args_t& args) // Prepare UL arguments srsran_gnb_ul_args_t ul_args = {}; ul_args.pusch.measure_time = true; + ul_args.pusch.measure_evm = true; ul_args.pusch.max_layers = args.nof_rx_ports; ul_args.pusch.max_prb = args.nof_max_prb; ul_args.nof_max_prb = args.nof_max_prb; From 537f1654823b92e7054fa701c15833908851692b Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Fri, 15 Oct 2021 10:48:20 +0200 Subject: [PATCH 166/208] Added comments --- lib/src/phy/phch/pucch_nr.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/src/phy/phch/pucch_nr.c b/lib/src/phy/phch/pucch_nr.c index 931fbf27a..b8c2005b2 100644 --- a/lib/src/phy/phch/pucch_nr.c +++ b/lib/src/phy/phch/pucch_nr.c @@ -528,14 +528,18 @@ int srsran_pucch_nr_format1_decode(srsran_pucch_nr_t* q, float llr[SRSRAN_PUCCH_NR_FORMAT1_MAX_NOF_BITS]; srsran_demod_soft_demodulate((nof_bits == 1) ? SRSRAN_MOD_BPSK : SRSRAN_MOD_QPSK, &d, llr, 1); - // Hard decision + // Hard decision based on the LLRs sign for (uint32_t i = 0; i < nof_bits; i++) { b[i] = llr[i] > 0.0f ? 1 : 0; } // Calculate normalised correlation, it uses the absolute value of d and accumulated average power if (norm_corr != NULL) { - float nsymb = (float)SRSRAN_CEIL(resource->nof_symbols, 2); + // Get the number of payload symbols. As the one of every 2 symbols carry DMRS, the payload symbols is half of the + // total symbols rounding down + float nsymb = (float)SRSRAN_FLOOR(resource->nof_symbols, 2); + + // Avoid zero, INF or NAN division, set correlation to 0 in this case if (isnormal(pwr_acc) && isnormal(nsymb)) { *norm_corr = cabsf(d) / sqrtf(pwr_acc * nsymb); } else { From e93503bae35fd7c112b2b437e1c9a1950137bf72 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Fri, 15 Oct 2021 10:51:37 +0200 Subject: [PATCH 167/208] Minor changes --- srsue/src/phy/nr/cc_worker.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index 46c26c11c..c169d21ba 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -160,8 +160,8 @@ void cc_worker::decode_pdcch_dl() if (logger.debug.enabled()) { for (uint32_t i = 0; i < ue_dl.pdcch_info_count; i++) { - const srsran_ue_dl_nr_pdcch_info_t* info = &ue_dl.pdcch_info[i]; - std::array dci_ctx; + const srsran_ue_dl_nr_pdcch_info_t* info = &ue_dl.pdcch_info[i]; + std::array dci_ctx = {}; srsran_dci_ctx_to_str(&info->dci_ctx, dci_ctx.data(), (uint32_t)dci_ctx.size()); logger.debug("PDCCH: %sEPRE=%+.2f, RSRP=%+.2f, corr=%.3f nof_bits=%d crc=%s", dci_ctx.data(), From 81174bda6444efbf8f6f784807b740f8e04bc7c6 Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 14 Oct 2021 22:45:11 +0100 Subject: [PATCH 168/208] nr,ue,rrc: release NR logical channels during RRC release --- lib/include/srsran/interfaces/ue_nr_interfaces.h | 1 + lib/include/srsran/interfaces/ue_rrc_interfaces.h | 1 + srsue/hdr/stack/mac_nr/mac_nr.h | 2 +- srsue/hdr/stack/rrc/rrc_nr.h | 1 + srsue/src/stack/mac_nr/mac_nr.cc | 5 +++++ srsue/src/stack/mac_nr/mux_nr.cc | 6 ++++++ srsue/src/stack/mac_nr/proc_bsr_nr.cc | 2 ++ srsue/src/stack/rrc/rrc.cc | 4 ++++ srsue/src/stack/rrc/rrc_nr.cc | 7 +++++++ srsue/src/stack/rrc/test/rrc_meas_test.cc | 3 ++- srsue/src/stack/rrc/test/ue_rrc_nr_test.cc | 3 ++- 11 files changed, 32 insertions(+), 3 deletions(-) diff --git a/lib/include/srsran/interfaces/ue_nr_interfaces.h b/lib/include/srsran/interfaces/ue_nr_interfaces.h index b67fe3372..f43a6f354 100644 --- a/lib/include/srsran/interfaces/ue_nr_interfaces.h +++ b/lib/include/srsran/interfaces/ue_nr_interfaces.h @@ -146,6 +146,7 @@ public: class mac_interface_rrc_nr { public: + virtual void reset() = 0; // Config calls that return SRSRAN_SUCCESS or SRSRAN_ERROR virtual int setup_lcid(const srsran::logical_channel_config_t& config) = 0; virtual int set_config(const srsran::bsr_cfg_nr_t& bsr_cfg) = 0; diff --git a/lib/include/srsran/interfaces/ue_rrc_interfaces.h b/lib/include/srsran/interfaces/ue_rrc_interfaces.h index f3796fa35..01e8d26b9 100644 --- a/lib/include/srsran/interfaces/ue_rrc_interfaces.h +++ b/lib/include/srsran/interfaces/ue_rrc_interfaces.h @@ -110,6 +110,7 @@ public: uint32_t sk_counter_r15, bool nr_radio_bearer_cfg1_r15_present, asn1::dyn_octstring nr_radio_bearer_cfg1_r15) = 0; + virtual void rrc_release() = 0; virtual bool is_config_pending() = 0; }; diff --git a/srsue/hdr/stack/mac_nr/mac_nr.h b/srsue/hdr/stack/mac_nr/mac_nr.h index ee32663d5..9eb944b1a 100644 --- a/srsue/hdr/stack/mac_nr/mac_nr.h +++ b/srsue/hdr/stack/mac_nr/mac_nr.h @@ -48,7 +48,6 @@ public: int init(const mac_nr_args_t& args_, phy_interface_mac_nr* phy_, rlc_interface_mac* rlc_, rrc_interface_mac* rrc_); void stop(); - void reset(); void run_tti(const uint32_t tti); void start_pcap(srsran::mac_pcap* pcap_); @@ -75,6 +74,7 @@ public: void get_metrics(mac_metrics_t* metrics); /// Interface for RRC (RRC -> MAC) + void reset(); int setup_lcid(const srsran::logical_channel_config_t& config); int set_config(const srsran::bsr_cfg_nr_t& bsr_cfg); int set_config(const srsran::sr_cfg_nr_t& sr_cfg); diff --git a/srsue/hdr/stack/rrc/rrc_nr.h b/srsue/hdr/stack/rrc/rrc_nr.h index 011922934..177cf8fc0 100644 --- a/srsue/hdr/stack/rrc/rrc_nr.h +++ b/srsue/hdr/stack/rrc/rrc_nr.h @@ -113,6 +113,7 @@ public: uint32_t sk_counter_r15, bool nr_radio_bearer_cfg1_r15_present, asn1::dyn_octstring nr_radio_bearer_cfg1_r15); + void rrc_release(); bool configure_sk_counter(uint16_t sk_counter); bool is_config_pending(); // STACK interface diff --git a/srsue/src/stack/mac_nr/mac_nr.cc b/srsue/src/stack/mac_nr/mac_nr.cc index a5d0fd09b..9a20de119 100644 --- a/srsue/src/stack/mac_nr/mac_nr.cc +++ b/srsue/src/stack/mac_nr/mac_nr.cc @@ -97,6 +97,11 @@ void mac_nr::stop() void mac_nr::reset() { logger.info("Resetting MAC-NR"); + + proc_bsr.reset(); + proc_sr.reset(); + proc_ra.reset(); + mux.reset(); } void mac_nr::run_tti(const uint32_t tti) diff --git a/srsue/src/stack/mac_nr/mux_nr.cc b/srsue/src/stack/mac_nr/mux_nr.cc index 0c7da9923..001dea03f 100644 --- a/srsue/src/stack/mac_nr/mux_nr.cc +++ b/srsue/src/stack/mac_nr/mux_nr.cc @@ -35,6 +35,12 @@ int32_t mux_nr::init(rlc_interface_mac* rlc_) return SRSRAN_SUCCESS; } +void mux_nr::reset() +{ + std::lock_guard lock(mutex); + this->logical_channels.clear(); +} + int mux_nr::setup_lcid(const srsran::logical_channel_config_t& config) { std::lock_guard lock(mutex); diff --git a/srsue/src/stack/mac_nr/proc_bsr_nr.cc b/srsue/src/stack/mac_nr/proc_bsr_nr.cc index b292476a9..b06e0ca44 100644 --- a/srsue/src/stack/mac_nr/proc_bsr_nr.cc +++ b/srsue/src/stack/mac_nr/proc_bsr_nr.cc @@ -63,6 +63,8 @@ void proc_bsr_nr::reset() timer_periodic.stop(); timer_retx.stop(); + lcg_priorities.clear(); + triggered_bsr_type = NONE; } diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index 6a6e3b6c6..c9fefe1e8 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -1134,6 +1134,10 @@ void rrc::rrc_connection_release(const std::string& cause) // Save idleModeMobilityControlInfo, etc. srsran::console("Received RRC Connection Release (releaseCause: %s)\n", cause.c_str()); + if (has_nr_dc()) { + rrc_nr->rrc_release(); + } + // delay actions by 60ms as per 5.3.8.3 task_sched.defer_callback(60, [this]() { start_go_idle(); }); } diff --git a/srsue/src/stack/rrc/rrc_nr.cc b/srsue/src/stack/rrc/rrc_nr.cc index 39a7db192..f1be64467 100644 --- a/srsue/src/stack/rrc/rrc_nr.cc +++ b/srsue/src/stack/rrc/rrc_nr.cc @@ -362,6 +362,13 @@ bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15, return true; } +void rrc_nr::rrc_release() +{ + rlc->reset(); + pdcp->reset(); + mac->reset(); +} + int rrc_nr::get_nr_capabilities(srsran::byte_buffer_t* nr_caps_pdu) { struct ue_nr_cap_s nr_cap; diff --git a/srsue/src/stack/rrc/test/rrc_meas_test.cc b/srsue/src/stack/rrc/test/rrc_meas_test.cc index e84022896..bf610fd65 100644 --- a/srsue/src/stack/rrc/test/rrc_meas_test.cc +++ b/srsue/src/stack/rrc/test/rrc_meas_test.cc @@ -180,7 +180,8 @@ public: asn1::dyn_octstring nr_radio_bearer_cfg1_r15) override { return false; - }; + } + void rrc_release() override {} bool is_config_pending() override { return false; }; }; diff --git a/srsue/src/stack/rrc/test/ue_rrc_nr_test.cc b/srsue/src/stack/rrc/test/ue_rrc_nr_test.cc index c58dc050e..87a1c4345 100644 --- a/srsue/src/stack/rrc/test/ue_rrc_nr_test.cc +++ b/srsue/src/stack/rrc/test/ue_rrc_nr_test.cc @@ -27,6 +27,7 @@ class dummy_phy : public phy_interface_rrc_nr class dummy_mac : public mac_interface_rrc_nr { + void reset() {} int setup_lcid(const srsran::logical_channel_config_t& config) { return SRSRAN_SUCCESS; } int set_config(const srsran::bsr_cfg_nr_t& bsr_cfg) { return SRSRAN_SUCCESS; } int set_config(const srsran::sr_cfg_nr_t& sr_cfg) { return SRSRAN_SUCCESS; } @@ -62,7 +63,7 @@ class dummy_rlc : public rlc_interface_rrc class dummy_pdcp : public pdcp_interface_rrc { - void set_enabled(uint32_t lcid, bool enabled) {}; + void set_enabled(uint32_t lcid, bool enabled){}; void reestablish(){}; void reestablish(uint32_t lcid){}; void reset(){}; From 08c96b0e351c63d3c2479cd838844efc725b6bbc Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 15 Oct 2021 18:00:46 +0100 Subject: [PATCH 169/208] nr,ue,mac: added TODO comment warning about missing functionality in srsue::mac_nr::reset method --- srsue/src/stack/mac_nr/mac_nr.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsue/src/stack/mac_nr/mac_nr.cc b/srsue/src/stack/mac_nr/mac_nr.cc index 9a20de119..7cf4c3ea7 100644 --- a/srsue/src/stack/mac_nr/mac_nr.cc +++ b/srsue/src/stack/mac_nr/mac_nr.cc @@ -98,6 +98,7 @@ void mac_nr::reset() { logger.info("Resetting MAC-NR"); + // TODO: Implement all the steps in 5.9 proc_bsr.reset(); proc_sr.reset(); proc_ra.reset(); From 9cbd2727f54e966569d7d1690973214dd74d2da3 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Fri, 15 Oct 2021 13:16:20 +0200 Subject: [PATCH 170/208] Disable measGapConfig in first reconfig. Remove all measurement reports for nr in the 2nd reconfig. --- srsenb/hdr/stack/rrc/rrc_endc.h | 13 +++++++--- srsenb/src/stack/rrc/rrc_endc.cc | 42 ++++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_endc.h b/srsenb/hdr/stack/rrc/rrc_endc.h index 9d41171ab..a580750a9 100644 --- a/srsenb/hdr/stack/rrc/rrc_endc.h +++ b/srsenb/hdr/stack/rrc/rrc_endc.h @@ -85,6 +85,11 @@ private: rrc* rrc_enb = nullptr; srslog::basic_logger& logger; + // nr ids to deactivate in second reconfig + uint32_t nr_meas_obj_id = 0; + uint32_t nr_report_cfg_id = 0; + uint32_t nr_meas_id = 0; + // vars bool endc_supported = false; rrc_endc_cfg_t endc_cfg = {}; @@ -111,8 +116,8 @@ private: private: srslog::basic_logger& logger; }; - struct wait_add_complete_st {}; // user needs to complete RA procedure and send C-RNTI CE - struct endc_activated_st {}; // user has enabled EN-DC successfully and is currently served + struct wait_add_complete_st {}; // user needs to complete RA procedure and send C-RNTI CE + struct endc_activated_st {}; // user has enabled EN-DC successfully and is currently served struct wait_sgnb_rel_req_resp_st {}; // release EN-DC // FSM guards @@ -141,7 +146,7 @@ protected: // transitions using fsm = rrc_endc; // clang-format off - using transitions = transition_table< + using transitions = transition_table< // Start Target Event Action Guard // +---------------------------+--------------------------+------------------------+------------------------------+-------------------------+ row< endc_deactivated_st, wait_sgnb_add_req_resp_st, sgnb_add_req_sent_ev, nullptr >, @@ -154,7 +159,7 @@ protected: // +---------------------------+--------------------------+------------------------+------------------------------+-------------------------+ row< endc_activated_st, wait_sgnb_rel_req_resp_st, sgnb_rel_req_ev, &fsm::handle_sgnb_rel_req >, row< wait_sgnb_rel_req_resp_st, endc_deactivated_st, sgnb_rel_req_ack_ev > - + >; // clang-format on }; diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index a0b16707a..ac2bc5d5e 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -62,8 +62,11 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn meas_cfg.meas_obj_to_add_mod_list_present = true; + // store id of nr meas object to remove it in second reconfiguration message + nr_meas_obj_id = meas_cfg.meas_obj_to_add_mod_list.size() + 1; + meas_obj_to_add_mod_s meas_obj = {}; - meas_obj.meas_obj_id = meas_cfg.meas_obj_to_add_mod_list.size() + 1; + meas_obj.meas_obj_id = nr_meas_obj_id; meas_obj.meas_obj.set_meas_obj_nr_r15(); auto& meas_obj_nr = meas_obj.meas_obj.meas_obj_nr_r15(); meas_obj_nr.carrier_freq_r15 = endc_cfg.abs_frequency_ssb; @@ -77,9 +80,12 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn // report config meas_cfg.report_cfg_to_add_mod_list_present = true; - report_cfg_to_add_mod_s report_cfg = {}; - report_cfg.report_cfg_id = meas_cfg.report_cfg_to_add_mod_list.size() + 1; + // store id of nr report config to remove it in second reconfiguration message + nr_report_cfg_id = meas_cfg.report_cfg_to_add_mod_list.size() + 1; + + report_cfg_to_add_mod_s report_cfg = {}; + report_cfg.report_cfg_id = nr_report_cfg_id; report_cfg.report_cfg.set_report_cfg_inter_rat(); report_cfg.report_cfg.report_cfg_inter_rat().trigger_type.set_event(); report_cfg.report_cfg.report_cfg_inter_rat().trigger_type.event().event_id.set_event_b1_nr_r15(); @@ -108,10 +114,14 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn // measIdToAddModList meas_cfg.meas_id_to_add_mod_list_present = true; - meas_id_to_add_mod_s meas_id = {}; - meas_id.meas_id = meas_cfg.meas_id_to_add_mod_list.size() + 1; - meas_id.meas_obj_id = meas_obj.meas_obj_id; - meas_id.report_cfg_id = report_cfg.report_cfg_id; + + // store id of nr meas to remove it in second reconfiguration message + nr_meas_id = meas_cfg.meas_id_to_add_mod_list.size() + 1; + + meas_id_to_add_mod_s meas_id = {}; + meas_id.meas_id = nr_meas_id; + meas_id.meas_obj_id = meas_obj.meas_obj_id; + meas_id.report_cfg_id = report_cfg.report_cfg_id; meas_cfg.meas_id_to_add_mod_list.push_back(meas_id); // quantityConfig @@ -125,10 +135,26 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn meas_quant[0].meas_quant_cell_nr_r15.filt_coeff_rsrp_r15 = filt_coef_opts::fc3; // measGapConfig - meas_cfg.meas_gap_cfg_present = true; + meas_cfg.meas_gap_cfg_present = false; // No LTE measGaps allowed while in NSA mode meas_cfg.meas_gap_cfg.set_setup(); meas_cfg.meas_gap_cfg.setup().gap_offset.set_gp0() = 16; } else if (is_in_state()) { + // Deactivate measurement reports, as we do not support measurements after NR activation + conn_recfg->meas_cfg_present = true; + meas_cfg_s& meas_cfg = conn_recfg->meas_cfg; + // Remove meas config + meas_cfg.meas_obj_to_rem_list_present = true; + meas_cfg.meas_obj_to_rem_list.resize(1); + meas_cfg.meas_obj_to_rem_list[0] = nr_meas_obj_id; + // remove report config + meas_cfg.report_cfg_to_rem_list_present = true; + meas_cfg.report_cfg_to_rem_list.resize(1); + meas_cfg.report_cfg_to_rem_list[0] = nr_report_cfg_id; + // remove meas id + meas_cfg.meas_id_to_rem_list_present = true; + meas_cfg.meas_id_to_rem_list.resize(1); + meas_cfg.meas_id_to_rem_list[0] = nr_meas_id; + // FIXME: use bearer manager to remove EUTRA DRB conn_recfg->rr_cfg_ded.drb_to_release_list_present = true; conn_recfg->rr_cfg_ded.drb_to_release_list.resize(1); From cc87af2986e83f5007ccfa9cfe0a3630676ed2d8 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 15 Oct 2021 16:46:15 +0200 Subject: [PATCH 171/208] ue,rrc: simplify code --- srsue/src/stack/rrc/rrc.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index c9fefe1e8..02479d266 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -2837,10 +2837,7 @@ uint32_t rrc::get_drb_id_for_eps_bearer(const uint32_t& eps_bearer_id) bool rrc::has_nr_dc() { - bool has_nr_dc = false; - if (args.release >= 15) - has_nr_dc = true; - return has_nr_dc; + return (args.release >= 15); } void rrc::add_mrb(uint32_t lcid, uint32_t port) From af69551c8d74941c2817313bf0cb54f0dfd8a027 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 15 Oct 2021 16:46:59 +0200 Subject: [PATCH 172/208] mac_sch_pdu_nr: add LBSR unpacking * add LBSR unpacking * add pretty printer * also simplify and unify general unpacking code --- lib/include/srsran/mac/mac_sch_pdu_nr.h | 15 +++-- lib/src/mac/mac_sch_pdu_nr.cc | 76 ++++++++++++++++++++++--- 2 files changed, 78 insertions(+), 13 deletions(-) diff --git a/lib/include/srsran/mac/mac_sch_pdu_nr.h b/lib/include/srsran/mac/mac_sch_pdu_nr.h index fb15b1768..7b3114d5f 100644 --- a/lib/include/srsran/mac/mac_sch_pdu_nr.h +++ b/lib/include/srsran/mac/mac_sch_pdu_nr.h @@ -59,7 +59,7 @@ public: nr_lcid_sch_t get_type(); bool is_sdu(); bool is_valid_lcid(); - bool is_var_len_ce(); + bool is_var_len_ce(uint32_t lcid); bool is_ul_ccch(); int32_t read_subheader(const uint8_t* ptr); @@ -78,9 +78,13 @@ public: uint8_t lcg_id; uint8_t buffer_size; }; - lcg_bsr_t get_sbsr(); - static const uint8_t max_num_lcg_lbsr = 8; - std::array get_lbsr(); + lcg_bsr_t get_sbsr(); + static const uint8_t max_num_lcg_lbsr = 8; + struct lbsr_t { + uint8_t bitmap; // the first octet of LBSR and Long Trunc BSR + std::vector list; // one entry for each reported LCG + }; + lbsr_t get_lbsr(); // TA struct ta_t { @@ -107,6 +111,9 @@ public: private: srslog::basic_logger* logger; + // internal helpers + bool has_length_field(); + uint32_t lcid = 0; int header_length = 0; int sdu_length = 0; diff --git a/lib/src/mac/mac_sch_pdu_nr.cc b/lib/src/mac/mac_sch_pdu_nr.cc index 28645ff0b..e9f6b4f3a 100644 --- a/lib/src/mac/mac_sch_pdu_nr.cc +++ b/lib/src/mac/mac_sch_pdu_nr.cc @@ -25,8 +25,18 @@ mac_sch_subpdu_nr::nr_lcid_sch_t mac_sch_subpdu_nr::get_type() bool mac_sch_subpdu_nr::is_sdu() { - // for UL-SCH LCID 52 is also valid for carrying SDUs - return (lcid <= 32 || (parent->is_ulsch() && lcid == 52)); + return (lcid <= 32); +} + +bool mac_sch_subpdu_nr::has_length_field() +{ + // CCCH (both versions) don't have a length field in the UL + if (parent->is_ulsch()) { + if (lcid == CCCH_SIZE_48 || lcid == CCCH_SIZE_64) { + return false; + } + } + return (is_sdu() || is_var_len_ce(lcid)); } // returns false for all reserved values in Table 6.2.1-1 and 6.2.1-2 @@ -35,9 +45,15 @@ bool mac_sch_subpdu_nr::is_valid_lcid() return (lcid <= 63 && ((parent->is_ulsch() && (lcid <= 32 || lcid >= 52)) || (lcid <= 32 || lcid >= 47))); } -bool mac_sch_subpdu_nr::is_var_len_ce() +bool mac_sch_subpdu_nr::is_var_len_ce(uint32_t lcid) { - return false; + switch (lcid) { + case LONG_TRUNC_BSR: + case LONG_BSR: + return true; + default: + return false; + } } // return length of PDU (or SRSRAN_ERROR otherwise) @@ -50,7 +66,7 @@ int32_t mac_sch_subpdu_nr::read_subheader(const uint8_t* ptr) header_length = 1; if (is_valid_lcid()) { - if ((is_sdu() || is_var_len_ce()) && not is_ul_ccch()) { + if (has_length_field()) { // Read first length byte sdu_length = (uint32_t)*ptr; ptr++; @@ -236,7 +252,7 @@ mac_sch_subpdu_nr::ta_t mac_sch_subpdu_nr::get_ta() mac_sch_subpdu_nr::lcg_bsr_t mac_sch_subpdu_nr::get_sbsr() { lcg_bsr_t sbsr = {}; - if (parent->is_ulsch() && lcid == SHORT_BSR) { + if (parent->is_ulsch() && (lcid == SHORT_BSR || lcid == SHORT_TRUNC_BSR)) { uint8_t* ptr = sdu.ptr(); sbsr.lcg_id = (ptr[0] & 0xe0) >> 5; sbsr.buffer_size = ptr[0] & 0x1f; @@ -244,6 +260,44 @@ mac_sch_subpdu_nr::lcg_bsr_t mac_sch_subpdu_nr::get_sbsr() return sbsr; } +mac_sch_subpdu_nr::lbsr_t mac_sch_subpdu_nr::get_lbsr() +{ + lbsr_t lbsr = {}; + lbsr.list.reserve(mac_sch_subpdu_nr::max_num_lcg_lbsr); + + if (parent->is_ulsch() && (lcid == LONG_BSR || lcid == LONG_TRUNC_BSR)) { + uint8_t* ptr = sdu.ptr(); + lbsr.bitmap = *ptr; // read LCG bitmap + ptr++; // skip LCG bitmap + + // early stop if LBSR is empty + if (lbsr.bitmap == 0) { + return lbsr; + } + + int bsr_cnt = 0; + for (int i = 0; i < mac_sch_subpdu_nr::max_num_lcg_lbsr; i++) { + // If LCGi bit is enabled, it means the next 8-bit BSR value corresponds to it + if (lbsr.bitmap & (0x1 << i)) { + lcg_bsr_t bsr = {}; + bsr.lcg_id = i; + // For the Long truncated, some BSR words can be not present, assume BSR > 0 in that case + if (1 + bsr_cnt < sdu_length) { + bsr.buffer_size = ptr[bsr_cnt]; + bsr_cnt++; + } else if (lcid == LONG_TRUNC_BSR) { + bsr.buffer_size = 63; // just assume it has 526 bytes to transmit + } else { + fprintf(stderr, "Error parsing LongBSR CE: sdu_length=%d but there are %d active bsr\n", sdu_length, bsr_cnt); + } + lbsr.list.push_back(bsr); + } + } + } + + return lbsr; +} + uint32_t mac_sch_subpdu_nr::sizeof_ce(uint32_t lcid, bool is_ul) { if (is_ul) { @@ -307,9 +361,13 @@ void mac_sch_subpdu_nr::to_string(fmt::memory_buffer& buffer) lcg_bsr_t sbsr = get_sbsr(); fmt::format_to(buffer, " SBSR: lcg={} bs={}", sbsr.lcg_id, sbsr.buffer_size); } break; - case mac_sch_subpdu_nr::LONG_BSR: - fmt::format_to(buffer, " LBSR: len={}", get_total_length()); - break; + case mac_sch_subpdu_nr::LONG_BSR: { + mac_sch_subpdu_nr::lbsr_t lbsr = get_lbsr(); + fmt::format_to(buffer, " LBSR: bitmap={:#02x}", lbsr.bitmap); + for (const auto& lcg : lbsr.list) { + fmt::format_to(buffer, " lcg={} bs={}", lcg.lcg_id, lcg.buffer_size); + } + } break; case mac_sch_subpdu_nr::SE_PHR: fmt::format_to(buffer, " SE_PHR: ph={} pc={}", get_phr(), get_pcmax()); break; From e5556fcc326ce6dcd9695aa267953ca212c8507b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 15 Oct 2021 16:47:47 +0200 Subject: [PATCH 173/208] mac_pdu_nr_test: add LBSR unpacking tests --- lib/test/mac/mac_pdu_nr_test.cc | 89 +++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/lib/test/mac/mac_pdu_nr_test.cc b/lib/test/mac/mac_pdu_nr_test.cc index 8752fcf09..bf1636170 100644 --- a/lib/test/mac/mac_pdu_nr_test.cc +++ b/lib/test/mac/mac_pdu_nr_test.cc @@ -516,6 +516,90 @@ int mac_ul_sch_pdu_unpack_and_pack_test3() return SRSRAN_SUCCESS; } +int mac_ul_sch_pdu_unpack_and_pack_test4() +{ + // MAC PDU with UL-SCH with C-RNTI, Long BSR (all zeros) and padding + uint8_t mac_ul_sch_pdu_1[] = {0x3a, 0x46, 0x01, 0x3e, 0x01, 0x00, 0x3f, 0x21, 0x21, 0x21, 0x21}; + const uint16_t TV_CRNTI = 0x4601; + + // only LBSR with only one LCG (LCG7 leftmost bit) reporting buffer state + uint8_t mac_ul_sch_pdu_2[] = {0x3e, 0x02, 0x80, 0xab}; + + // only LBSR with only two LCG (LCG7 leftmost bit. LCG0) reporting buffer state + uint8_t mac_ul_sch_pdu_3[] = {0x3e, 0x03, 0x81, 0xab, 0xcd}; + + if (pcap_handle) { + pcap_handle->write_ul_crnti_nr(mac_ul_sch_pdu_1, sizeof(mac_ul_sch_pdu_1), PCAP_CRNTI, true, PCAP_TTI); + pcap_handle->write_ul_crnti_nr(mac_ul_sch_pdu_2, sizeof(mac_ul_sch_pdu_2), PCAP_CRNTI, true, PCAP_TTI); + pcap_handle->write_ul_crnti_nr(mac_ul_sch_pdu_3, sizeof(mac_ul_sch_pdu_3), PCAP_CRNTI, true, PCAP_TTI); + } + + // pretty print PDU + fmt::memory_buffer buff; + auto& mac_logger = srslog::fetch_basic_logger("MAC"); + + // first TV + srsran::mac_sch_pdu_nr pdu(true); + pdu.unpack(mac_ul_sch_pdu_1, sizeof(mac_ul_sch_pdu_1)); + pdu.to_string(buff); + mac_logger.info("Rx PDU: %s", srsran::to_c_str(buff)); + + TESTASSERT(pdu.get_num_subpdus() == 3); + + // 1st subPDU is C-RNTI CE + mac_sch_subpdu_nr subpdu = pdu.get_subpdu(0); + TESTASSERT(subpdu.get_total_length() == 3); + TESTASSERT(subpdu.get_sdu_length() == 2); + TESTASSERT(subpdu.get_lcid() == mac_sch_subpdu_nr::CRNTI); + TESTASSERT(subpdu.get_c_rnti() == TV_CRNTI); + + // 2nd subPDU is LBSR + subpdu = pdu.get_subpdu(1); + TESTASSERT(subpdu.get_lcid() == mac_sch_subpdu_nr::LONG_BSR); + mac_sch_subpdu_nr::lbsr_t lbsr = subpdu.get_lbsr(); + TESTASSERT(lbsr.list.size() == 0); + + // 3rd is padding + subpdu = pdu.get_subpdu(2); + TESTASSERT(subpdu.get_lcid() == mac_sch_subpdu_nr::PADDING); + + // TODO: pack again and test + + // 2nd TV + pdu.init_rx(true); + pdu.unpack(mac_ul_sch_pdu_2, sizeof(mac_ul_sch_pdu_2)); + buff.clear(); + pdu.to_string(buff); + mac_logger.info("Rx PDU: %s", srsran::to_c_str(buff)); + + TESTASSERT(pdu.get_num_subpdus() == 1); + subpdu = pdu.get_subpdu(0); + TESTASSERT(subpdu.get_lcid() == mac_sch_subpdu_nr::LONG_BSR); + lbsr = subpdu.get_lbsr(); + TESTASSERT(lbsr.list.size() == 1); + TESTASSERT(lbsr.list.at(0).lcg_id == 7); + TESTASSERT(lbsr.list.at(0).buffer_size == 0xab); + + // 3nd TV + pdu.init_rx(true); + pdu.unpack(mac_ul_sch_pdu_3, sizeof(mac_ul_sch_pdu_3)); + buff.clear(); + pdu.to_string(buff); + mac_logger.info("Rx PDU: %s", srsran::to_c_str(buff)); + + TESTASSERT(pdu.get_num_subpdus() == 1); + subpdu = pdu.get_subpdu(0); + TESTASSERT(subpdu.get_lcid() == mac_sch_subpdu_nr::LONG_BSR); + lbsr = subpdu.get_lbsr(); + TESTASSERT(lbsr.list.size() == 2); + TESTASSERT(lbsr.list.at(0).lcg_id == 0); + TESTASSERT(lbsr.list.at(0).buffer_size == 0xab); + TESTASSERT(lbsr.list.at(1).lcg_id == 7); + TESTASSERT(lbsr.list.at(1).buffer_size == 0xcd); + + return SRSRAN_SUCCESS; +} + int mac_ul_sch_pdu_pack_test4() { // MAC PDU with UL-SCH (with normal LCID) subheader for long SDU @@ -771,6 +855,11 @@ int main(int argc, char** argv) return SRSRAN_ERROR; } + if (mac_ul_sch_pdu_unpack_and_pack_test4()) { + fprintf(stderr, "mac_ul_sch_pdu_unpack_and_pack_test4() failed.\n"); + return SRSRAN_ERROR; + } + if (mac_ul_sch_pdu_pack_test4()) { fprintf(stderr, "mac_ul_sch_pdu_pack_test4() failed.\n"); return SRSRAN_ERROR; From f96b315f81414197a3755a7b57461401df2f0056 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 15 Oct 2021 16:52:26 +0200 Subject: [PATCH 174/208] enb,ue_nr: unpack LBSR and pass content to sched --- srsenb/src/stack/mac/nr/ue_nr.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc index 4e79a257d..6c0bcbbfc 100644 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ b/srsenb/src/stack/mac/nr/ue_nr.cc @@ -115,11 +115,12 @@ int ue_nr::process_pdu(srsran::unique_byte_buffer_t pdu) } } break; case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::LONG_BSR: - logger.info("LONG_BSR CE not implemented."); - break; - case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::LONG_TRUNC_BSR: - logger.info("LONG_TRUNC_BSR CE not implemented."); - break; + case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::LONG_TRUNC_BSR: { + srsran::mac_sch_subpdu_nr::lbsr_t lbsr = subpdu.get_lbsr(); + for (auto& lb : lbsr.list) { + sched->ul_bsr(rnti, lb.lcg_id, buff_size_field_to_bytes(lb.buffer_size, srsran::LONG_BSR)); + } + } break; default: if (subpdu.is_sdu()) { rrc->set_activity_user(rnti); From 7a16be969244db3fdb862df43dd13ca02c4f3fd3 Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 14 Oct 2021 21:43:18 +0100 Subject: [PATCH 175/208] rrc,nr: ensure coresets and search spaces are passed to scheduler cell_cfg and ue_cfg --- lib/include/srsran/asn1/rrc_nr_utils.h | 4 + lib/src/asn1/rrc_nr_utils.cc | 33 ++++++ srsenb/hdr/stack/rrc/rrc_nr.h | 3 - srsenb/src/stack/rrc/nr/cell_asn1_config.cc | 94 ++++++++++++++++ srsenb/src/stack/rrc/rrc_nr.cc | 113 ++------------------ 5 files changed, 142 insertions(+), 105 deletions(-) diff --git a/lib/include/srsran/asn1/rrc_nr_utils.h b/lib/include/srsran/asn1/rrc_nr_utils.h index d732aa57a..3cf8385e2 100644 --- a/lib/include/srsran/asn1/rrc_nr_utils.h +++ b/lib/include/srsran/asn1/rrc_nr_utils.h @@ -57,6 +57,8 @@ struct pdsch_serving_cell_cfg_s; struct freq_info_dl_s; struct serving_cell_cfg_common_s; struct serving_cell_cfg_s; +struct pdcch_cfg_common_s; +struct pdcch_cfg_s; } // namespace rrc_nr } // namespace asn1 @@ -118,6 +120,8 @@ bool make_pdsch_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_s& serv_ bool make_csi_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_csi_hl_cfg_t* csi_hl); bool make_duplex_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_common_s& serv_cell, srsran_duplex_config_nr_t* duplex_cfg); +bool fill_phy_pdcch_cfg_common(const asn1::rrc_nr::pdcch_cfg_common_s& pdcch_cfg, srsran_pdcch_cfg_nr_t* pdcch); +bool fill_phy_pdcch_cfg(const asn1::rrc_nr::pdcch_cfg_s& pdcch_cfg, srsran_pdcch_cfg_nr_t* pdcch); /*************************** * MAC Config diff --git a/lib/src/asn1/rrc_nr_utils.cc b/lib/src/asn1/rrc_nr_utils.cc index 12964a225..51db1b5ed 100644 --- a/lib/src/asn1/rrc_nr_utils.cc +++ b/lib/src/asn1/rrc_nr_utils.cc @@ -1551,6 +1551,39 @@ bool make_duplex_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_common_ return true; } +bool fill_phy_pdcch_cfg(const asn1::rrc_nr::pdcch_cfg_s& pdcch_cfg, srsran_pdcch_cfg_nr_t* pdcch) +{ + if (pdcch_cfg.ctrl_res_set_to_add_mod_list_present) { + for (const ctrl_res_set_s& coreset : pdcch_cfg.ctrl_res_set_to_add_mod_list) { + pdcch->coreset_present[coreset.ctrl_res_set_id] = true; + make_phy_coreset_cfg(coreset, &pdcch->coreset[coreset.ctrl_res_set_id]); + } + } + + if (pdcch_cfg.search_spaces_to_add_mod_list_present) { + for (const search_space_s& ss : pdcch_cfg.search_spaces_to_add_mod_list) { + pdcch->search_space_present[ss.search_space_id] = true; + make_phy_search_space_cfg(ss, &pdcch->search_space[ss.search_space_id]); + } + } + return true; +} + +bool fill_phy_pdcch_cfg_common(const asn1::rrc_nr::pdcch_cfg_common_s& pdcch_cfg, srsran_pdcch_cfg_nr_t* pdcch) +{ + if (pdcch_cfg.common_ctrl_res_set_present) { + pdcch->coreset_present[pdcch_cfg.common_ctrl_res_set.ctrl_res_set_id] = true; + make_phy_coreset_cfg(pdcch_cfg.common_ctrl_res_set, &pdcch->coreset[pdcch_cfg.common_ctrl_res_set.ctrl_res_set_id]); + } + if (pdcch_cfg.common_search_space_list_present) { + for (const search_space_s& ss : pdcch_cfg.common_search_space_list) { + pdcch->search_space_present[ss.search_space_id] = true; + make_phy_search_space_cfg(ss, &pdcch->search_space[ss.search_space_id]); + } + } + return true; +} + } // namespace srsran namespace srsenb { diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 03bf34376..94d40fa9f 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -139,7 +139,6 @@ public: int pack_sp_cell_cfg_ded(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); int pack_sp_cell_cfg_ded_init_dl_bwp(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_sp_cell_cfg_ded_init_dl_bwp_pdcch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); int pack_sp_cell_cfg_ded_init_dl_bwp_pdsch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); int pack_sp_cell_cfg_ded_init_dl_bwp_radio_link_monitoring(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); @@ -159,8 +158,6 @@ public: asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); int pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp_pdcch_cfg_common( - asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); int pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp_pdsch_cfg_common( asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); diff --git a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc index 0fd1fbd82..cc6555bdd 100644 --- a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc +++ b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc @@ -221,17 +221,108 @@ int fill_csi_meas_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas return SRSRAN_SUCCESS; } +void fill_init_dl_bwp(const rrc_nr_cfg_t& cfg, bwp_dl_ded_s& bwp) +{ + bwp.pdcch_cfg_present = true; + auto& pdcch_ded_setup = bwp.pdcch_cfg.set_setup(); + pdcch_ded_setup.ctrl_res_set_to_add_mod_list_present = true; + pdcch_ded_setup.ctrl_res_set_to_add_mod_list.resize(1); + pdcch_ded_setup.ctrl_res_set_to_add_mod_list[0].ctrl_res_set_id = 2; + pdcch_ded_setup.ctrl_res_set_to_add_mod_list[0].freq_domain_res.from_number( + 0b111111110000000000000000000000000000000000000); + pdcch_ded_setup.ctrl_res_set_to_add_mod_list[0].dur = 1; + pdcch_ded_setup.ctrl_res_set_to_add_mod_list[0].cce_reg_map_type.set_non_interleaved(); + pdcch_ded_setup.ctrl_res_set_to_add_mod_list[0].precoder_granularity = + asn1::rrc_nr::ctrl_res_set_s::precoder_granularity_opts::same_as_reg_bundle; + + // search spaces + pdcch_ded_setup.search_spaces_to_add_mod_list_present = true; + pdcch_ded_setup.search_spaces_to_add_mod_list.resize(1); + pdcch_ded_setup.search_spaces_to_add_mod_list[0].search_space_id = 2; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].ctrl_res_set_id_present = true; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].ctrl_res_set_id = 2; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].monitoring_slot_periodicity_and_offset_present = true; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].monitoring_slot_periodicity_and_offset.set_sl1(); + pdcch_ded_setup.search_spaces_to_add_mod_list[0].monitoring_symbols_within_slot_present = true; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].monitoring_symbols_within_slot.from_number(0b10000000000000); + pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates_present = true; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level1 = + asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level1_opts::n0; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level2 = + asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level2_opts::n2; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level4 = + asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level4_opts::n2; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level8 = + asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level8_opts::n0; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level16 = + asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level16_opts::n0; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].search_space_type_present = true; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].search_space_type.set_ue_specific(); + pdcch_ded_setup.search_spaces_to_add_mod_list[0].search_space_type.ue_specific().dci_formats = asn1::rrc_nr:: + search_space_s::search_space_type_c_::ue_specific_s_::dci_formats_opts::formats0_minus0_and_minus1_minus0; +} + /// Fill ServingCellConfig with gNB config int fill_serv_cell_from_enb_cfg(const rrc_nr_cfg_t& cfg, serving_cell_cfg_s& serv_cell) { serv_cell.csi_meas_cfg_present = true; HANDLE_ERROR(fill_csi_meas_from_enb_cfg(cfg, serv_cell.csi_meas_cfg.set_setup())); + serv_cell.init_dl_bwp_present = true; + fill_init_dl_bwp(cfg, serv_cell.init_dl_bwp); + // TODO: remaining fields return SRSRAN_SUCCESS; } +void fill_dl_cfg_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, dl_cfg_common_s& dl_cfg_common) +{ + dl_cfg_common.init_dl_bwp_present = true; + dl_cfg_common.init_dl_bwp.pdcch_cfg_common_present = true; + + auto& pdcch_cfg_setup = dl_cfg_common.init_dl_bwp.pdcch_cfg_common.set_setup(); + pdcch_cfg_setup.common_ctrl_res_set_present = true; + pdcch_cfg_setup.common_ctrl_res_set.ctrl_res_set_id = 1; + pdcch_cfg_setup.common_ctrl_res_set.freq_domain_res.from_number(0b111111110000000000000000000000000000000000000); + pdcch_cfg_setup.common_ctrl_res_set.dur = 1; + pdcch_cfg_setup.common_ctrl_res_set.cce_reg_map_type.set_non_interleaved(); + pdcch_cfg_setup.common_ctrl_res_set.precoder_granularity = + asn1::rrc_nr::ctrl_res_set_s::precoder_granularity_opts::same_as_reg_bundle; + + // common search space list + pdcch_cfg_setup.common_search_space_list_present = true; + pdcch_cfg_setup.common_search_space_list.resize(1); + pdcch_cfg_setup.common_search_space_list[0].search_space_id = 1; + pdcch_cfg_setup.common_search_space_list[0].ctrl_res_set_id_present = true; + pdcch_cfg_setup.common_search_space_list[0].ctrl_res_set_id = 1; + pdcch_cfg_setup.common_search_space_list[0].search_space_type_present = true; + pdcch_cfg_setup.common_search_space_list[0].search_space_type.set_common(); + pdcch_cfg_setup.common_search_space_list[0].search_space_type.common().dci_format0_minus0_and_format1_minus0_present = + true; + pdcch_cfg_setup.common_search_space_list[0].nrof_candidates_present = true; + pdcch_cfg_setup.common_search_space_list[0].nrof_candidates.aggregation_level1 = + asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level1_opts::n1; + pdcch_cfg_setup.common_search_space_list[0].nrof_candidates.aggregation_level2 = + asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level2_opts::n1; + pdcch_cfg_setup.common_search_space_list[0].nrof_candidates.aggregation_level4 = + asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level4_opts::n1; + pdcch_cfg_setup.common_search_space_list[0].nrof_candidates.aggregation_level8 = + asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level8_opts::n0; + pdcch_cfg_setup.common_search_space_list[0].nrof_candidates.aggregation_level16 = + asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level16_opts::n0; + pdcch_cfg_setup.common_search_space_list[0].monitoring_slot_periodicity_and_offset_present = true; + pdcch_cfg_setup.common_search_space_list[0].monitoring_slot_periodicity_and_offset.set_sl1(); + pdcch_cfg_setup.common_search_space_list[0].monitoring_symbols_within_slot_present = true; + pdcch_cfg_setup.common_search_space_list[0].monitoring_symbols_within_slot.from_number(0b10000000000000); + pdcch_cfg_setup.ra_search_space_present = true; + pdcch_cfg_setup.ra_search_space = 1; + + if (cfg.cell_list[cc].duplex_mode == SRSRAN_DUPLEX_MODE_TDD) { + pdcch_cfg_setup.ext = false; + } +} + /// Fill ServingCellConfigCommon with gNB config int fill_serv_cell_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, serving_cell_cfg_common_s& serv_common) { @@ -280,6 +371,9 @@ int fill_serv_cell_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, ser tdd_config.pattern1.nrof_ul_symbols = 0; } + serv_common.dl_cfg_common_present = true; + fill_dl_cfg_common_from_enb_cfg(cfg, cc, serv_common.dl_cfg_common); + return SRSRAN_SUCCESS; } diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 35f9b183d..cc23b5bfc 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -252,6 +252,12 @@ void rrc_nr::config_mac() // Derive cell config from ASN1 bool ret2 = srsran::make_pdsch_cfg_from_serv_cell(sp_cell.sp_cell_cfg_ded, &cell.bwps[0].pdsch); srsran_assert(ret2, "Invalid NR cell configuration."); + ret2 = srsran::fill_phy_pdcch_cfg_common( + sp_cell.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdcch_cfg_common.setup(), + &cell.bwps[0].pdcch); + srsran_assert(ret2, "Invalid NR cell configuration."); + ret2 = srsran::fill_phy_pdcch_cfg(sp_cell.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg.setup(), &cell.bwps[0].pdcch); + srsran_assert(ret2, "Invalid NR cell configuration."); ret2 = srsran::make_phy_ssb_cfg( cfg.cell_list[0].phy_cell.carrier, sp_cell.recfg_with_sync.sp_cell_cfg_common, &cell.ssb); srsran_assert(ret2, "Invalid NR cell configuration."); @@ -659,7 +665,6 @@ int rrc_nr::ue::pack_sp_cell_cfg_ded_init_dl_bwp(asn1::rrc_nr::cell_group_cfg_s& { cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp_present = true; - pack_sp_cell_cfg_ded_init_dl_bwp_pdcch_cfg(cell_group_cfg_pack); pack_sp_cell_cfg_ded_init_dl_bwp_pdsch_cfg(cell_group_cfg_pack); pack_sp_cell_cfg_ded_init_dl_bwp_radio_link_monitoring(cell_group_cfg_pack); @@ -683,51 +688,6 @@ int rrc_nr::ue::pack_sp_cell_cfg_ded_init_dl_bwp_radio_link_monitoring( return SRSRAN_SUCCESS; } -int rrc_nr::ue::pack_sp_cell_cfg_ded_init_dl_bwp_pdcch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - // PDCCH config - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg_present = true; - auto& pdcch_cfg_dedicated = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg; - auto& pdcch_ded_setup = pdcch_cfg_dedicated.set_setup(); - pdcch_ded_setup.ctrl_res_set_to_add_mod_list_present = true; - pdcch_ded_setup.ctrl_res_set_to_add_mod_list.resize(1); - pdcch_ded_setup.ctrl_res_set_to_add_mod_list[0].ctrl_res_set_id = 2; - pdcch_ded_setup.ctrl_res_set_to_add_mod_list[0].freq_domain_res.from_number( - 0b111111110000000000000000000000000000000000000); - pdcch_ded_setup.ctrl_res_set_to_add_mod_list[0].dur = 1; - pdcch_ded_setup.ctrl_res_set_to_add_mod_list[0].cce_reg_map_type.set_non_interleaved(); - pdcch_ded_setup.ctrl_res_set_to_add_mod_list[0].precoder_granularity = - asn1::rrc_nr::ctrl_res_set_s::precoder_granularity_opts::same_as_reg_bundle; - - // search spaces - pdcch_ded_setup.search_spaces_to_add_mod_list_present = true; - pdcch_ded_setup.search_spaces_to_add_mod_list.resize(1); - pdcch_ded_setup.search_spaces_to_add_mod_list[0].search_space_id = 2; - pdcch_ded_setup.search_spaces_to_add_mod_list[0].ctrl_res_set_id_present = true; - pdcch_ded_setup.search_spaces_to_add_mod_list[0].ctrl_res_set_id = 2; - pdcch_ded_setup.search_spaces_to_add_mod_list[0].monitoring_slot_periodicity_and_offset_present = true; - pdcch_ded_setup.search_spaces_to_add_mod_list[0].monitoring_slot_periodicity_and_offset.set_sl1(); - pdcch_ded_setup.search_spaces_to_add_mod_list[0].monitoring_symbols_within_slot_present = true; - pdcch_ded_setup.search_spaces_to_add_mod_list[0].monitoring_symbols_within_slot.from_number(0b10000000000000); - pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates_present = true; - pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level1 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level1_opts::n0; - pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level2 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level2_opts::n2; - pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level4 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level4_opts::n2; - pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level8 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level8_opts::n0; - pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level16 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level16_opts::n0; - pdcch_ded_setup.search_spaces_to_add_mod_list[0].search_space_type_present = true; - pdcch_ded_setup.search_spaces_to_add_mod_list[0].search_space_type.set_ue_specific(); - pdcch_ded_setup.search_spaces_to_add_mod_list[0].search_space_type.ue_specific().dci_formats = asn1::rrc_nr:: - search_space_s::search_space_type_c_::ue_specific_s_::dci_formats_opts::formats0_minus0_and_minus1_minus0; - - return SRSRAN_SUCCESS; -} - int rrc_nr::ue::pack_sp_cell_cfg_ded_init_dl_bwp_pdsch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) { cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdsch_cfg_present = true; @@ -1011,61 +971,6 @@ int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_common_phy_cell_g return SRSRAN_SUCCESS; } -int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp_pdcch_cfg_common( - asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp - .pdcch_cfg_common_present = true; - auto& pdcch_cfg_common = - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdcch_cfg_common; - - pdcch_cfg_common.set_setup(); - pdcch_cfg_common.setup().common_ctrl_res_set_present = true; - pdcch_cfg_common.setup().common_ctrl_res_set.ctrl_res_set_id = 1; - pdcch_cfg_common.setup().common_ctrl_res_set.freq_domain_res.from_number( - 0b111111110000000000000000000000000000000000000); - pdcch_cfg_common.setup().common_ctrl_res_set.dur = 1; - pdcch_cfg_common.setup().common_ctrl_res_set.cce_reg_map_type.set_non_interleaved(); - pdcch_cfg_common.setup().common_ctrl_res_set.precoder_granularity = - asn1::rrc_nr::ctrl_res_set_s::precoder_granularity_opts::same_as_reg_bundle; - - // common search space list - pdcch_cfg_common.setup().common_search_space_list_present = true; - pdcch_cfg_common.setup().common_search_space_list.resize(1); - pdcch_cfg_common.setup().common_search_space_list[0].search_space_id = 1; - pdcch_cfg_common.setup().common_search_space_list[0].ctrl_res_set_id_present = true; - pdcch_cfg_common.setup().common_search_space_list[0].ctrl_res_set_id = 1; - pdcch_cfg_common.setup().common_search_space_list[0].search_space_type_present = true; - pdcch_cfg_common.setup().common_search_space_list[0].search_space_type.set_common(); - pdcch_cfg_common.setup() - .common_search_space_list[0] - .search_space_type.common() - .dci_format0_minus0_and_format1_minus0_present = true; - pdcch_cfg_common.setup().common_search_space_list[0].nrof_candidates_present = true; - pdcch_cfg_common.setup().common_search_space_list[0].nrof_candidates.aggregation_level1 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level1_opts::n1; - pdcch_cfg_common.setup().common_search_space_list[0].nrof_candidates.aggregation_level2 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level2_opts::n1; - pdcch_cfg_common.setup().common_search_space_list[0].nrof_candidates.aggregation_level4 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level4_opts::n1; - pdcch_cfg_common.setup().common_search_space_list[0].nrof_candidates.aggregation_level8 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level8_opts::n0; - pdcch_cfg_common.setup().common_search_space_list[0].nrof_candidates.aggregation_level16 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level16_opts::n0; - pdcch_cfg_common.setup().common_search_space_list[0].monitoring_slot_periodicity_and_offset_present = true; - pdcch_cfg_common.setup().common_search_space_list[0].monitoring_slot_periodicity_and_offset.set_sl1(); - pdcch_cfg_common.setup().common_search_space_list[0].monitoring_symbols_within_slot_present = true; - pdcch_cfg_common.setup().common_search_space_list[0].monitoring_symbols_within_slot.from_number(0b10000000000000); - pdcch_cfg_common.setup().ra_search_space_present = true; - pdcch_cfg_common.setup().ra_search_space = 1; - - if (parent->cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_TDD) { - pdcch_cfg_common.setup().ext = false; - } - - return SRSRAN_SUCCESS; -} - int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp_pdsch_cfg_common( asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) { @@ -1094,7 +999,6 @@ int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp( init_dl_bwp.generic_params.location_and_bw = 14025; init_dl_bwp.generic_params.subcarrier_spacing = subcarrier_spacing_opts::khz15; - pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp_pdcch_cfg_common(cell_group_cfg_pack); pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp_pdsch_cfg_common(cell_group_cfg_pack); return SRSRAN_SUCCESS; @@ -1411,6 +1315,11 @@ void rrc_nr::ue::crnti_ce_received() &uecfg.phy_cfg.ssb); srsran::make_duplex_cfg_from_serv_cell(cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common, &uecfg.phy_cfg.duplex); + srsran::fill_phy_pdcch_cfg_common(cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common + .init_dl_bwp.pdcch_cfg_common.setup(), + &uecfg.phy_cfg.pdcch); + srsran::fill_phy_pdcch_cfg(cell_group_cfg.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg.setup(), + &uecfg.phy_cfg.pdcch); parent->mac->ue_cfg(rnti, uecfg); } From 5b2afb1739708a2e353fa7b2427df0df7d4b9f80 Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 15 Oct 2021 16:58:40 +0100 Subject: [PATCH 176/208] rrc,nr,gnb: ensure same PDCCH config is sent to PHY, scheduler cell config, and sched ue cfg --- lib/src/asn1/rrc_nr_utils.cc | 20 +++++++++--- srsenb/hdr/stack/rrc/rrc_nr.h | 7 +++-- srsenb/src/stack/mac/nr/sched_nr_cfg.cc | 10 +++--- srsenb/src/stack/rrc/rrc_nr.cc | 42 +++++++++++++------------ 4 files changed, 46 insertions(+), 33 deletions(-) diff --git a/lib/src/asn1/rrc_nr_utils.cc b/lib/src/asn1/rrc_nr_utils.cc index 51db1b5ed..7321f0490 100644 --- a/lib/src/asn1/rrc_nr_utils.cc +++ b/lib/src/asn1/rrc_nr_utils.cc @@ -378,15 +378,20 @@ bool make_phy_search_space_cfg(const search_space_s& search_space, srsran_search } srsran_search_space.coreset_id = search_space.ctrl_res_set_id; + srsran_search_space.duration = 1; + if (search_space.dur_present) { + srsran_search_space.duration = search_space.dur; + } + if (not search_space.nrof_candidates_present) { asn1::log_warning("nrof_candidates_present option not present"); return false; } - srsran_search_space.nof_candidates[0] = search_space.nrof_candidates.aggregation_level1.value; - srsran_search_space.nof_candidates[1] = search_space.nrof_candidates.aggregation_level2.value; - srsran_search_space.nof_candidates[2] = search_space.nrof_candidates.aggregation_level4.value; - srsran_search_space.nof_candidates[3] = search_space.nrof_candidates.aggregation_level8.value; - srsran_search_space.nof_candidates[4] = search_space.nrof_candidates.aggregation_level16.value; + srsran_search_space.nof_candidates[0] = search_space.nrof_candidates.aggregation_level1.to_number(); + srsran_search_space.nof_candidates[1] = search_space.nrof_candidates.aggregation_level2.to_number(); + srsran_search_space.nof_candidates[2] = search_space.nrof_candidates.aggregation_level4.to_number(); + srsran_search_space.nof_candidates[3] = search_space.nrof_candidates.aggregation_level8.to_number(); + srsran_search_space.nof_candidates[4] = search_space.nrof_candidates.aggregation_level16.to_number(); if (not search_space.search_space_type_present) { asn1::log_warning("nrof_candidates option not present"); @@ -1579,8 +1584,13 @@ bool fill_phy_pdcch_cfg_common(const asn1::rrc_nr::pdcch_cfg_common_s& pdcch_cfg for (const search_space_s& ss : pdcch_cfg.common_search_space_list) { pdcch->search_space_present[ss.search_space_id] = true; make_phy_search_space_cfg(ss, &pdcch->search_space[ss.search_space_id]); + if (pdcch_cfg.ra_search_space_present and pdcch_cfg.ra_search_space == ss.search_space_id) { + pdcch->ra_search_space_present = true; + pdcch->ra_search_space = pdcch->search_space[ss.search_space_id]; + } } } + return true; } diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 94d40fa9f..6ab39d282 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -121,7 +121,7 @@ public: void get_metrics(rrc_ue_metrics_t& ue_metrics) { ue_metrics = {}; /*TODO fill RRC metrics*/ }; // setters - int pack_rrc_reconfiguration(); + int pack_rrc_reconfiguration(); void deactivate_bearers(); private: @@ -210,8 +210,9 @@ private: srsran::task_sched_handle task_sched; // derived - uint32_t slot_dur_ms = 0; - srslog::basic_logger& logger; + uint32_t slot_dur_ms = 0; + srslog::basic_logger& logger; + asn1::rrc_nr::sp_cell_cfg_s base_sp_cell_cfg; // vars std::map > users; diff --git a/srsenb/src/stack/mac/nr/sched_nr_cfg.cc b/srsenb/src/stack/mac/nr/sched_nr_cfg.cc index f077d8edd..0a924b099 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_cfg.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_cfg.cc @@ -46,7 +46,8 @@ bwp_params_t::bwp_params_t(const cell_cfg_t& cell, const sched_args_t& sched_cfg cfg(cell.bwps[bwp_id_]), logger(srslog::fetch_basic_logger(sched_cfg_.logger_name)) { - srsran_assert(bwp_id != 0 or cfg.pdcch.coreset_present[0], "CORESET#0 has to be active for initial BWP"); + srsran_assert(cfg.pdcch.ra_search_space_present, "BWPs without RA search space not supported"); + const uint32_t ra_coreset_id = cfg.pdcch.ra_search_space.coreset_id; P = get_P(cfg.rb_width, cfg.pdsch.rbg_size_cfg_1); N_rbg = get_nof_rbgs(cfg.rb_width, cfg.start_rb, cfg.pdsch.rbg_size_cfg_1); @@ -61,14 +62,13 @@ bwp_params_t::bwp_params_t(const cell_cfg_t& cell, const sched_args_t& sched_cfg } pusch_ra_list.resize(cfg.pusch.nof_common_time_ra); - const uint32_t coreset_id = 0; srsran_sch_grant_nr_t grant; for (uint32_t m = 0; m < cfg.pusch.nof_common_time_ra; ++m) { int ret = - srsran_ra_ul_nr_time(&cfg.pusch, srsran_rnti_type_ra, srsran_search_space_type_rar, coreset_id, m, &grant); + srsran_ra_ul_nr_time(&cfg.pusch, srsran_rnti_type_ra, srsran_search_space_type_rar, ra_coreset_id, m, &grant); srsran_assert(ret == SRSRAN_SUCCESS, "Failed to obtain RA config"); pusch_ra_list[m].msg3_delay = grant.k; - ret = srsran_ra_ul_nr_time(&cfg.pusch, srsran_rnti_type_c, srsran_search_space_type_ue, coreset_id, m, &grant); + ret = srsran_ra_ul_nr_time(&cfg.pusch, srsran_rnti_type_c, srsran_search_space_type_ue, ra_coreset_id, m, &grant); pusch_ra_list[m].K = grant.k; pusch_ra_list[m].S = grant.S; pusch_ra_list[m].L = grant.L; @@ -79,7 +79,7 @@ bwp_params_t::bwp_params_t(const cell_cfg_t& cell, const sched_args_t& sched_cfg for (uint32_t sl = 0; sl < SRSRAN_NOF_SF_X_FRAME; ++sl) { for (uint32_t agg_idx = 0; agg_idx < MAX_NOF_AGGR_LEVELS; ++agg_idx) { rar_cce_list[sl][agg_idx].resize(SRSRAN_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR); - int n = srsran_pdcch_nr_locations_coreset(&cell_cfg.bwps[0].pdcch.coreset[0], + int n = srsran_pdcch_nr_locations_coreset(&cell_cfg.bwps[0].pdcch.coreset[ra_coreset_id], &cell_cfg.bwps[0].pdcch.ra_search_space, 0, agg_idx, diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index cc23b5bfc..7dc973cc2 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -55,6 +55,19 @@ int rrc_nr::init(const rrc_nr_cfg_t& cfg_, return SRSRAN_ERROR; } + // Fill base ASN1 cell config. + int ret = fill_sp_cell_cfg_from_enb_cfg(cfg, UE_PSCELL_CC_IDX, base_sp_cell_cfg); + srsran_assert(ret == SRSRAN_SUCCESS, "Failed to configure cell"); + + // Fill rrc_nr_cfg with UE-specific search spaces and coresets + bool ret2 = srsran::fill_phy_pdcch_cfg_common( + base_sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdcch_cfg_common.setup(), + &cfg.cell_list[0].phy_cell.pdcch); + srsran_assert(ret2, "Invalid NR cell configuration."); + ret2 = srsran::fill_phy_pdcch_cfg(base_sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg.setup(), + &cfg.cell_list[0].phy_cell.pdcch); + srsran_assert(ret2, "Invalid NR cell configuration."); + config_phy(); // if PHY is not yet initialized, config will be stored and applied on initialization config_mac(); @@ -244,24 +257,15 @@ void rrc_nr::config_mac() std::vector sched_cells_cfg = {srsenb::get_default_cells_cfg(1)}; sched_nr_interface::cell_cfg_t& cell = sched_cells_cfg[0]; - // Derive ASN1 from config - asn1::rrc_nr::sp_cell_cfg_s sp_cell; - int ret = fill_sp_cell_cfg_from_enb_cfg(cfg, UE_PSCELL_CC_IDX, sp_cell); - srsran_assert(ret == SRSRAN_SUCCESS, "Failed to configure cell"); - + // Derive cell config from rrc_nr_cfg_t + cell.bwps[0].pdcch = cfg.cell_list[0].phy_cell.pdcch; // Derive cell config from ASN1 - bool ret2 = srsran::make_pdsch_cfg_from_serv_cell(sp_cell.sp_cell_cfg_ded, &cell.bwps[0].pdsch); - srsran_assert(ret2, "Invalid NR cell configuration."); - ret2 = srsran::fill_phy_pdcch_cfg_common( - sp_cell.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdcch_cfg_common.setup(), - &cell.bwps[0].pdcch); - srsran_assert(ret2, "Invalid NR cell configuration."); - ret2 = srsran::fill_phy_pdcch_cfg(sp_cell.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg.setup(), &cell.bwps[0].pdcch); + bool ret2 = srsran::make_pdsch_cfg_from_serv_cell(base_sp_cell_cfg.sp_cell_cfg_ded, &cell.bwps[0].pdsch); srsran_assert(ret2, "Invalid NR cell configuration."); ret2 = srsran::make_phy_ssb_cfg( - cfg.cell_list[0].phy_cell.carrier, sp_cell.recfg_with_sync.sp_cell_cfg_common, &cell.ssb); + cfg.cell_list[0].phy_cell.carrier, base_sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common, &cell.ssb); srsran_assert(ret2, "Invalid NR cell configuration."); - ret2 = srsran::make_duplex_cfg_from_serv_cell(sp_cell.recfg_with_sync.sp_cell_cfg_common, &cell.duplex); + ret2 = srsran::make_duplex_cfg_from_serv_cell(base_sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common, &cell.duplex); srsran_assert(ret2, "Invalid NR cell configuration."); // FIXME: entire SI configuration, etc needs to be ported to NR @@ -548,7 +552,10 @@ int rrc_nr::sgnb_release_request(uint16_t nr_rnti) *******************************************************************************/ rrc_nr::ue::ue(rrc_nr* parent_, uint16_t rnti_, const sched_nr_ue_cfg_t& uecfg_) : parent(parent_), rnti(rnti_), uecfg(uecfg_) -{} +{ + // Derive UE cfg from rrc_cfg_nr_t + uecfg.phy_cfg.pdcch = parent->cfg.cell_list[0].phy_cell.pdcch; +} void rrc_nr::ue::send_connection_setup() { @@ -1315,11 +1322,6 @@ void rrc_nr::ue::crnti_ce_received() &uecfg.phy_cfg.ssb); srsran::make_duplex_cfg_from_serv_cell(cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common, &uecfg.phy_cfg.duplex); - srsran::fill_phy_pdcch_cfg_common(cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common - .init_dl_bwp.pdcch_cfg_common.setup(), - &uecfg.phy_cfg.pdcch); - srsran::fill_phy_pdcch_cfg(cell_group_cfg.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg.setup(), - &uecfg.phy_cfg.pdcch); parent->mac->ue_cfg(rnti, uecfg); } From b6e890cc1261bc0b9b23e5331b26a25d2270574a Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 15 Oct 2021 21:53:33 +0100 Subject: [PATCH 177/208] nr,gnb,sched: use search space id=2 for 5G NR NSA --- srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc index 768ffb82a..4054d3ec8 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc @@ -223,7 +223,7 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr // TODO // Find space and allocate PDCCH - const uint32_t aggr_idx = 2, ss_id = 1; + const uint32_t aggr_idx = 2, ss_id = 2; uint32_t coreset_id = ue.cfg->phy().pdcch.search_space[ss_id].coreset_id; if (not bwp_pdcch_slot.coresets[coreset_id]->alloc_dci(pdcch_grant_type_t::dl_data, aggr_idx, ss_id, &ue)) { // Could not find space in PDCCH @@ -312,7 +312,7 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_pr if (bwp_pusch_slot.ul_prbs.collides(ul_prbs)) { return alloc_result::sch_collision; } - const uint32_t aggr_idx = 2, ss_id = 1; + const uint32_t aggr_idx = 2, ss_id = 2; uint32_t coreset_id = ue.cfg->phy().pdcch.search_space[ss_id].coreset_id; if (not bwp_pdcch_slot.coresets[coreset_id].value().alloc_dci(pdcch_grant_type_t::ul_data, aggr_idx, ss_id, &ue)) { // Could not find space in PDCCH From 9ace7017884971bf13bf5d12ee018eb04f24d476 Mon Sep 17 00:00:00 2001 From: Francisco Date: Sat, 16 Oct 2021 16:07:15 +0100 Subject: [PATCH 178/208] nr,gnb,sched: prioritize the search space with the highest number of position candidates --- .../stack/mac/nr/sched_nr_grant_allocator.cc | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc index 4054d3ec8..f2b544761 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc @@ -223,8 +223,17 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr // TODO // Find space and allocate PDCCH - const uint32_t aggr_idx = 2, ss_id = 2; - uint32_t coreset_id = ue.cfg->phy().pdcch.search_space[ss_id].coreset_id; + const uint32_t aggr_idx = 2; + // Choose the ss_id the highest number of candidates + uint32_t ss_id = 0, max_nof_candidates = 0; + for (uint32_t i = 0; i < 3; ++i) { + uint32_t nof_candidates = ue.cfg->cce_pos_list(i, pdcch_slot.slot_idx(), aggr_idx).size(); + if (nof_candidates > max_nof_candidates) { + ss_id = i; + max_nof_candidates = nof_candidates; + } + } + uint32_t coreset_id = ue.cfg->phy().pdcch.search_space[ss_id].coreset_id; if (not bwp_pdcch_slot.coresets[coreset_id]->alloc_dci(pdcch_grant_type_t::dl_data, aggr_idx, ss_id, &ue)) { // Could not find space in PDCCH return alloc_result::no_cch_space; @@ -312,8 +321,17 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_pr if (bwp_pusch_slot.ul_prbs.collides(ul_prbs)) { return alloc_result::sch_collision; } - const uint32_t aggr_idx = 2, ss_id = 2; - uint32_t coreset_id = ue.cfg->phy().pdcch.search_space[ss_id].coreset_id; + const uint32_t aggr_idx = 2; + // Choose the ss_id the highest number of candidates + uint32_t ss_id = 0, max_nof_candidates = 0; + for (uint32_t i = 0; i < 3; ++i) { + uint32_t nof_candidates = ue.cfg->cce_pos_list(i, pdcch_slot.slot_idx(), aggr_idx).size(); + if (nof_candidates > max_nof_candidates) { + ss_id = i; + max_nof_candidates = nof_candidates; + } + } + uint32_t coreset_id = ue.cfg->phy().pdcch.search_space[ss_id].coreset_id; if (not bwp_pdcch_slot.coresets[coreset_id].value().alloc_dci(pdcch_grant_type_t::ul_data, aggr_idx, ss_id, &ue)) { // Could not find space in PDCCH return alloc_result::no_cch_space; From 1d37c5b476b8e4a6468ffc946a4bc1223773bffa Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 15 Oct 2021 12:42:32 +0200 Subject: [PATCH 179/208] nr: increase nominal p0 pusch --- srsenb/src/stack/rrc/nr/cell_asn1_config.cc | 2 +- srsenb/src/stack/rrc/rrc_nr.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc index cc6555bdd..f40428945 100644 --- a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc +++ b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc @@ -328,7 +328,7 @@ int fill_serv_cell_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, ser { auto& cell_cfg = cfg.cell_list.at(cc); - serv_common.ss_pbch_block_pwr = 0; + serv_common.ss_pbch_block_pwr = 20; serv_common.n_timing_advance_offset_present = true; serv_common.n_timing_advance_offset = asn1::rrc_nr::serving_cell_cfg_common_s::n_timing_advance_offset_opts::n0; serv_common.n_timing_advance_offset_present = true; diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 7dc973cc2..f2d70e741 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -1106,7 +1106,7 @@ int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bw asn1::rrc_nr::pusch_time_domain_res_alloc_s::map_type_opts::type_a; pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[1].start_symbol_and_len = 27; pusch_cfg_common_pack.setup().p0_nominal_with_grant_present = true; - pusch_cfg_common_pack.setup().p0_nominal_with_grant = -90; + pusch_cfg_common_pack.setup().p0_nominal_with_grant = -60; // PUCCH config common cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp @@ -1116,7 +1116,7 @@ int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bw pucch_cfg_common_pack.set_setup(); pucch_cfg_common_pack.setup().pucch_group_hop = asn1::rrc_nr::pucch_cfg_common_s::pucch_group_hop_opts::neither; pucch_cfg_common_pack.setup().p0_nominal_present = true; - pucch_cfg_common_pack.setup().p0_nominal = -90; + pucch_cfg_common_pack.setup().p0_nominal = -60; return SRSRAN_SUCCESS; } From abe2c8cba4ed2e26e03ea5b09aacc195bee37866 Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 15 Oct 2021 20:11:38 +0100 Subject: [PATCH 180/208] nr,gnb,rrc: Allow NR EN-DC to be re-activated in case of Reestablishment with cause other than ReconfFailure --- srsenb/hdr/stack/rrc/rrc_endc.h | 26 +++++++++++++++++--------- srsenb/src/stack/rrc/rrc_endc.cc | 18 +++++++++++++----- srsenb/src/stack/rrc/rrc_ue.cc | 7 +++++++ 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_endc.h b/srsenb/hdr/stack/rrc/rrc_endc.h index a580750a9..5975199f4 100644 --- a/srsenb/hdr/stack/rrc/rrc_endc.h +++ b/srsenb/hdr/stack/rrc/rrc_endc.h @@ -64,6 +64,11 @@ public: */ struct sgnb_rel_req_ack_ev {}; + /** + * @brief in case of non supported NR carrier in UE capabilities or the NR reconfiguration failed + */ + struct disable_endc_ev {}; + rrc_endc(srsenb::rrc::ue* outer_ue, const rrc_endc_cfg_t& endc_cfg_); ~rrc_endc(); @@ -91,9 +96,8 @@ private: uint32_t nr_meas_id = 0; // vars - bool endc_supported = false; - rrc_endc_cfg_t endc_cfg = {}; - uint16_t nr_rnti = SRSRAN_INVALID_RNTI; // C-RNTI assigned to UE on NR side + rrc_endc_cfg_t endc_cfg = {}; + uint16_t nr_rnti = SRSRAN_INVALID_RNTI; // C-RNTI assigned to UE on NR side asn1::rrc::rrc_conn_recfg_complete_s pending_recfg_complete; // fixed ENDC variables @@ -119,13 +123,15 @@ private: struct wait_add_complete_st {}; // user needs to complete RA procedure and send C-RNTI CE struct endc_activated_st {}; // user has enabled EN-DC successfully and is currently served struct wait_sgnb_rel_req_resp_st {}; // release EN-DC + struct endc_disabled_st {}; // EN-DC disabled // FSM guards // FSM transition handlers void handle_sgnb_add_req_ack(wait_sgnb_add_req_resp_st& s, const sgnb_add_req_ack_ev& ev); void handle_sgnb_rel_req(endc_activated_st& s, const sgnb_rel_req_ev& ev); - void handle_rrc_reest(wait_add_complete_st& s, const rrc_reest_rx_ev& ev); + void handle_rrc_reest(const rrc_reest_rx_ev& ev); + void handle_endc_disabled(const disable_endc_ev& ev); protected: // states @@ -134,14 +140,16 @@ protected: prepare_recfg_st, wait_add_complete_st, endc_activated_st, - wait_sgnb_rel_req_resp_st> + wait_sgnb_rel_req_resp_st, + endc_disabled_st> states{this, endc_deactivated_st{}, wait_sgnb_add_req_resp_st{}, prepare_recfg_st{this}, wait_add_complete_st{}, endc_activated_st{}, - wait_sgnb_rel_req_resp_st{}}; + wait_sgnb_rel_req_resp_st{}, + endc_disabled_st{}}; // transitions using fsm = rrc_endc; @@ -155,11 +163,11 @@ protected: row< wait_sgnb_add_req_resp_st, endc_deactivated_st, sgnb_add_req_reject_ev >, row< prepare_recfg_st, wait_add_complete_st, rrc_recfg_sent_ev >, row< wait_add_complete_st, endc_activated_st, sgnb_add_complete_ev >, - row< wait_add_complete_st, endc_deactivated_st, rrc_reest_rx_ev, &fsm::handle_rrc_reest >, // +---------------------------+--------------------------+------------------------+------------------------------+-------------------------+ row< endc_activated_st, wait_sgnb_rel_req_resp_st, sgnb_rel_req_ev, &fsm::handle_sgnb_rel_req >, - row< wait_sgnb_rel_req_resp_st, endc_deactivated_st, sgnb_rel_req_ack_ev > - + to_state< endc_deactivated_st, rrc_reest_rx_ev, &fsm::handle_rrc_reest >, + row< wait_sgnb_rel_req_resp_st, endc_deactivated_st, sgnb_rel_req_ack_ev >, + to_state< endc_disabled_st, disable_endc_ev, &fsm::handle_endc_disabled > >; // clang-format on }; diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index ac2bc5d5e..8baeb1ac7 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -50,7 +50,7 @@ rrc::ue::rrc_endc::~rrc_endc() //! Method to add NR fields to a RRC Connection Reconfiguration Message bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_recfg) { - if (not endc_supported) { + if (not is_endc_supported()) { // skipping ENDC-related field return false; } @@ -228,6 +228,7 @@ void rrc::ue::rrc_endc::handle_eutra_capabilities(const asn1::rrc::ue_eutra_cap_ // skip any further checks if eNB runs without NR cells if (rrc_enb->cfg.num_nr_cells == 0) { Debug("Skipping UE capabilities. No NR cell configured."); + trigger(disable_endc_ev{}); return; } @@ -257,7 +258,7 @@ void rrc::ue::rrc_endc::handle_eutra_capabilities(const asn1::rrc::ue_eutra_cap_ if (ue_cap_v1510.irat_params_nr_r15_present) { if (ue_cap_v1510.irat_params_nr_r15.en_dc_r15_present) { logger.info("Enabling ENDC support for rnti=%d", rrc_ue->rnti); - endc_supported = true; + return; } } } @@ -273,13 +274,15 @@ void rrc::ue::rrc_endc::handle_eutra_capabilities(const asn1::rrc::ue_eutra_cap_ } } } + + trigger(disable_endc_ev{}); } //! Method called whenever the eNB receives a MeasReport from the UE void rrc::ue::rrc_endc::handle_ue_meas_report(const meas_report_s& msg) { // Ignore event if ENDC isn't supported - if (not endc_supported) { + if (not is_endc_supported()) { return; } @@ -363,10 +366,10 @@ void rrc::ue::rrc_endc::handle_sgnb_rel_req(endc_activated_st& s, const sgnb_rel bool rrc::ue::rrc_endc::is_endc_supported() { - return endc_supported; + return not is_in_state(); } -void rrc::ue::rrc_endc::handle_rrc_reest(wait_add_complete_st& s, const rrc_reest_rx_ev& ev) +void rrc::ue::rrc_endc::handle_rrc_reest(const rrc_reest_rx_ev& ev) { auto& sgnb_config = get_state()->sgnb_config; @@ -376,4 +379,9 @@ void rrc::ue::rrc_endc::handle_rrc_reest(wait_add_complete_st& s, const rrc_rees rrc_enb->bearer_manager.rem_user(sgnb_config.nr_rnti); } +void rrc::ue::rrc_endc::handle_endc_disabled(const disable_endc_ev& ev) +{ + logger.info("Disabling NR EN-DC support for rnti=0x%x", nr_rnti); +} + } // namespace srsenb diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index cc5648914..46741e5d2 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -694,6 +694,13 @@ void rrc::ue::handle_rrc_con_reest_req(rrc_conn_reest_request_s* msg) eutra_capabilities.to_json(js); parent->logger.debug("rnti=0x%x EUTRA capabilities: %s", rnti, js.to_string().c_str()); } + if (endc_handler) { + if (req_r8.reest_cause.value == reest_cause_opts::recfg_fail) { + endc_handler->trigger(rrc_endc::disable_endc_ev{}); + } else { + endc_handler->handle_eutra_capabilities(eutra_capabilities); + } + } // Recover GTP-U tunnels and S1AP context parent->gtpu->mod_bearer_rnti(old_rnti, rnti); From 277e6f2998f7e012a07b2e8ff6fcbfe17d8ffa95 Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 15 Oct 2021 20:50:08 +0100 Subject: [PATCH 181/208] nr,gnb,rrc: Ignore measurementReports from UE while RRC Reconfiguration procedure is not yet complete. --- srsenb/src/stack/rrc/rrc_ue.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 46741e5d2..4c7ee845a 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -397,13 +397,16 @@ void rrc::ue::parse_ul_dcch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) } break; case ul_dcch_msg_type_c::c1_c_::types::meas_report: - if (mobility_handler != nullptr) { - mobility_handler->handle_ue_meas_report(ul_dcch_msg.msg.c1().meas_report(), std::move(original_pdu)); + if (state == RRC_STATE_REGISTERED) { + if (mobility_handler != nullptr) { + mobility_handler->handle_ue_meas_report(ul_dcch_msg.msg.c1().meas_report(), std::move(original_pdu)); + } + if (endc_handler != nullptr) { + endc_handler->handle_ue_meas_report(ul_dcch_msg.msg.c1().meas_report()); + } } else { - parent->logger.warning("Received MeasReport but no mobility configuration is available"); - } - if (endc_handler != nullptr) { - endc_handler->handle_ue_meas_report(ul_dcch_msg.msg.c1().meas_report()); + parent->logger.warning( + "measurementReport for rnti=0x%x ignored. Cause: RRC Reconfiguration is not yet complete", rnti); } break; case ul_dcch_msg_type_c::c1_c_::types::ue_info_resp_r9: From 643b5a188583827266a7f79f43470ec6469d9ffc Mon Sep 17 00:00:00 2001 From: Francisco Date: Sun, 17 Oct 2021 23:41:39 +0100 Subject: [PATCH 182/208] nr,gnb,rrc: Add comment explaining how the UE rrc_endc is updated in case of reestablishment --- srsenb/src/stack/rrc/rrc_ue.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 4c7ee845a..56c1a686d 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -699,8 +699,12 @@ void rrc::ue::handle_rrc_con_reest_req(rrc_conn_reest_request_s* msg) } if (endc_handler) { if (req_r8.reest_cause.value == reest_cause_opts::recfg_fail) { + // In case of Reestablishment due to ReconfFailure, avoid re-enabling NR EN-DC, otherwise + // the eNB and UE may enter in a reconfiguration + reestablishment loop. endc_handler->trigger(rrc_endc::disable_endc_ev{}); } else { + // In case of Reestablishment with cause other than ReconfFailure, recompute whether + // the new RNTI supports NR EN-DC. endc_handler->handle_eutra_capabilities(eutra_capabilities); } } From 061385cf720c6b96a2d7807394de374ebb390d43 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 8 Jun 2021 17:20:27 +0100 Subject: [PATCH 183/208] Fix short MAC integrity check at MME --- srsepc/src/mme/nas.cc | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/srsepc/src/mme/nas.cc b/srsepc/src/mme/nas.cc index 2e64b926d..c43324390 100644 --- a/srsepc/src/mme/nas.cc +++ b/srsepc/src/mme/nas.cc @@ -967,7 +967,7 @@ bool nas::handle_attach_request(srsran::byte_buffer_t* nas_rx) bool nas::handle_authentication_response(srsran::byte_buffer_t* nas_rx) { LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT auth_resp = {}; - bool ue_valid = true; + bool ue_valid = true; // Get NAS authentication response LIBLTE_ERROR_ENUM err = liblte_mme_unpack_authentication_response_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx, &auth_resp); @@ -1701,12 +1701,14 @@ bool nas::short_integrity_check(srsran::byte_buffer_t* pdu) return false; } + uint32_t estimated_count = (m_sec_ctx.ul_nas_count & 0xffffffe0) | (pdu->msg[1] & 0x1f); + switch (m_sec_ctx.integ_algo) { case srsran::INTEGRITY_ALGORITHM_ID_EIA0: break; case srsran::INTEGRITY_ALGORITHM_ID_128_EIA1: srsran::security_128_eia1(&m_sec_ctx.k_nas_int[16], - m_sec_ctx.ul_nas_count, + estimated_count, 0, srsran::SECURITY_DIRECTION_UPLINK, &pdu->msg[0], @@ -1715,7 +1717,7 @@ bool nas::short_integrity_check(srsran::byte_buffer_t* pdu) break; case srsran::INTEGRITY_ALGORITHM_ID_128_EIA2: srsran::security_128_eia2(&m_sec_ctx.k_nas_int[16], - m_sec_ctx.ul_nas_count, + estimated_count, 0, srsran::SECURITY_DIRECTION_UPLINK, &pdu->msg[0], @@ -1724,7 +1726,7 @@ bool nas::short_integrity_check(srsran::byte_buffer_t* pdu) break; case srsran::INTEGRITY_ALGORITHM_ID_128_EIA3: srsran::security_128_eia3(&m_sec_ctx.k_nas_int[16], - m_sec_ctx.ul_nas_count, + estimated_count, 0, srsran::SECURITY_DIRECTION_UPLINK, &pdu->msg[0], @@ -1734,12 +1736,13 @@ bool nas::short_integrity_check(srsran::byte_buffer_t* pdu) default: break; } + // Check if expected mac equals the sent mac for (i = 0; i < 2; i++) { if (exp_mac[i + 2] != mac[i]) { m_logger.warning("Short integrity check failure. Local: count=%d, [%02x %02x %02x %02x], " "Received: count=%d, [%02x %02x]", - m_sec_ctx.ul_nas_count, + estimated_count, exp_mac[0], exp_mac[1], exp_mac[2], @@ -1750,7 +1753,9 @@ bool nas::short_integrity_check(srsran::byte_buffer_t* pdu) return false; } } + m_logger.info("Integrity check ok. Local: count=%d, Received: count=%d", m_sec_ctx.ul_nas_count, pdu->msg[1] & 0x1F); + m_sec_ctx.ul_nas_count = estimated_count; return true; } From 3bf09021f96064bb5243ad5ac849ce962802da2a Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 18 Oct 2021 14:17:53 +0200 Subject: [PATCH 184/208] enb: remove unused parameter --- lib/include/srsran/interfaces/enb_mac_interfaces.h | 1 - srsenb/src/main.cc | 1 - 2 files changed, 2 deletions(-) diff --git a/lib/include/srsran/interfaces/enb_mac_interfaces.h b/lib/include/srsran/interfaces/enb_mac_interfaces.h index b3e2ef2fc..17ef85fac 100644 --- a/lib/include/srsran/interfaces/enb_mac_interfaces.h +++ b/lib/include/srsran/interfaces/enb_mac_interfaces.h @@ -22,7 +22,6 @@ struct mac_args_t { uint32_t nof_prb; ///< Needed to dimension MAC softbuffers for all cells sched_interface::sched_args_t sched; int lcid_padding; - int nr_tb_size = -1; uint32_t nof_prealloc_ues; ///< Number of UE resources to pre-allocate at eNB startup uint32_t max_nof_kos; int rlf_min_ul_snr_estim; diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 118444b1d..b0670f7af 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -255,7 +255,6 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("embms.mcs", bpo::value(&args->stack.embms.mcs)->default_value(20), "Modulation and Coding scheme of MBMS traffic.") // NR section - ("scheduler.tb_len", bpo::value(&args->stack.mac.nr_tb_size)->default_value(1520), "Default TB size") ("scheduler.nr_pdsch_mcs", bpo::value(&args->nr_stack.mac.sched_cfg.fixed_dl_mcs)->default_value(28), "Fixed NR DL MCS (-1 for dynamic)") ("scheduler.nr_pusch_mcs", bpo::value(&args->nr_stack.mac.sched_cfg.fixed_ul_mcs)->default_value(28), "Fixed NR UL MCS (-1 for dynamic)") From d5acf73c46df03dbfe8149bc7370d06e9a8748a9 Mon Sep 17 00:00:00 2001 From: Francisco Date: Mon, 18 Oct 2021 13:26:14 +0100 Subject: [PATCH 185/208] nr,gnb,sched: fix logging of tbs. check if sched args are supported at sched startup. change the tti logging to be equal to tti_rx --- srsenb/hdr/stack/mac/nr/sched_nr_harq.h | 19 ++++---------- srsenb/src/stack/mac/nr/mac_nr.cc | 2 +- srsenb/src/stack/mac/nr/sched_nr_cfg.cc | 6 ++++- .../stack/mac/nr/sched_nr_grant_allocator.cc | 25 ++++++++----------- srsenb/src/stack/mac/nr/sched_nr_harq.cc | 18 +++++++------ srsenb/src/stack/mac/nr/sched_nr_helpers.cc | 4 +-- 6 files changed, 35 insertions(+), 39 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_harq.h b/srsenb/hdr/stack/mac/nr/sched_nr_harq.h index dcf2c587e..8af07e9b7 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_harq.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_harq.h @@ -48,17 +48,13 @@ public: void new_slot(slot_point slot_rx); void reset(); - bool new_tx(slot_point slot_tx, - slot_point slot_ack, - const prb_grant& grant, - uint32_t mcs, - uint32_t tbs, - uint32_t max_retx); + bool new_tx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant, uint32_t mcs, uint32_t max_retx); bool new_retx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant); bool new_retx(slot_point slot_tx, slot_point slot_ack); // NOTE: Has to be used before first tx is dispatched - bool set_tbs(uint32_t tbs, int mcs = -1); + bool set_tbs(uint32_t tbs); + bool set_mcs(uint32_t mcs); const uint32_t pid; @@ -87,12 +83,7 @@ public: tx_harq_softbuffer& get_softbuffer() { return *softbuffer; } srsran::unique_byte_buffer_t* get_tx_pdu() { return &pdu; } - bool new_tx(slot_point slot_tx, - slot_point slot_ack, - const prb_grant& grant, - uint32_t mcs, - uint32_t tbs, - uint32_t max_retx); + bool new_tx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant, uint32_t mcs, uint32_t max_retx); private: srsran::unique_pool_ptr softbuffer; @@ -110,7 +101,7 @@ public: bool set_tbs(uint32_t tbs) { - softbuffer->reset(tbs * 8u); + softbuffer->reset(tbs); return harq_proc::set_tbs(tbs); } diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 23c59c594..bd418cf53 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -291,7 +291,7 @@ int mac_nr::slot_indication(const srsran_slot_cfg_t& slot_cfg) int mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) { - logger.set_context(slot_cfg.idx); + logger.set_context(slot_cfg.idx - TX_ENB_DELAY); slot_point pdsch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx}; sched_nr_interface::dl_sched_res_t dl_res; diff --git a/srsenb/src/stack/mac/nr/sched_nr_cfg.cc b/srsenb/src/stack/mac/nr/sched_nr_cfg.cc index 0a924b099..ecbb30e4c 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_cfg.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_cfg.cc @@ -101,7 +101,11 @@ cell_params_t::cell_params_t(uint32_t cc_, const cell_cfg_t& cell, const sched_a srsran_assert(not bwps.empty(), "No BWPs were configured"); } -sched_params::sched_params(const sched_args_t& sched_cfg_) : sched_cfg(sched_cfg_) {} +sched_params::sched_params(const sched_args_t& sched_cfg_) : sched_cfg(sched_cfg_) +{ + srsran_assert(sched_cfg.fixed_dl_mcs >= 0, "Dynamic DL MCS not supported"); + srsran_assert(sched_cfg.fixed_ul_mcs >= 0, "Dynamic DL MCS not supported"); +} /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc index f2b544761..6982a5726 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc @@ -172,7 +172,7 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t prb_interval msg3_interv{last_msg3, last_msg3 + msg3_nof_prbs}; last_msg3 += msg3_nof_prbs; ue.h_ul = ue.harq_ent->find_empty_ul_harq(); - success = ue.h_ul->new_tx(msg3_slot, msg3_slot, msg3_interv, mcs, 100, max_harq_msg3_retx); + success = ue.h_ul->new_tx(msg3_slot, msg3_slot, msg3_interv, mcs, max_harq_msg3_retx); srsran_assert(success, "Failed to allocate Msg3"); fill_dci_msg3(ue, *bwp_grid.cfg, rar_grant.msg3_dci); @@ -240,22 +240,20 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr } // Allocate HARQ + int mcs = ue.cfg->fixed_pdsch_mcs(); if (ue.h_dl->empty()) { - int mcs = ue.cfg->fixed_pdsch_mcs(); - srsran_assert(mcs >= 0, "Dynamic MCS not yet supported"); - int tbs = 100; - bool ret = ue.h_dl->new_tx(ue.pdsch_slot, ue.uci_slot, dl_grant, mcs, tbs, 4); + bool ret = ue.h_dl->new_tx(ue.pdsch_slot, ue.uci_slot, dl_grant, mcs, 4); srsran_assert(ret, "Failed to allocate DL HARQ"); } else { bool ret = ue.h_dl->new_retx(ue.pdsch_slot, ue.uci_slot, dl_grant); + mcs = ue.h_dl->mcs(); srsran_assert(ret, "Failed to allocate DL HARQ retx"); } // Allocation Successful - int mcs = ue.h_dl->mcs(); const static float max_R = 0.93; - do { + while (true) { // Generate PDCCH pdcch_dl_t& pdcch = bwp_pdcch_slot.dl_pdcchs.back(); fill_dl_dci_ue_fields(ue, *bwp_grid.cfg, ss_id, pdcch.dci.ctx.location, pdcch.dci); @@ -288,15 +286,15 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr } else { srsran_assert(pdsch.sch.grant.tb[0].tbs == (int)ue.h_dl->tbs(), "The TBS did not remain constant in retx"); } - if (bwp_pdsch_slot.pdschs.back().sch.grant.tb[0].R_prime < max_R or mcs == 0) { + if (ue.h_dl->nof_retx() > 0 or bwp_pdsch_slot.pdschs.back().sch.grant.tb[0].R_prime < max_R or mcs <= 0) { break; } - // Decrease MCS if rate is too high + // Decrease MCS if first tx and rate is too high mcs--; - ue.h_dl->set_tbs(100, mcs); + ue.h_dl->set_mcs(mcs); bwp_pdsch_slot.pdschs.pop_back(); bwp_uci_slot.pending_acks.pop_back(); - } while (true); + } if (mcs == 0) { logger.warning("Couldn't find mcs that leads to R<0.9"); } @@ -338,10 +336,9 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_pr } if (ue.h_ul->empty()) { - int mcs = ue.cfg->fixed_pusch_mcs(); - srsran_assert(mcs >= 0, "Dynamic MCS not yet supported"); + int mcs = ue.cfg->fixed_pusch_mcs(); int tbs = 100; - bool success = ue.h_ul->new_tx(ue.pusch_slot, ue.pusch_slot, ul_prbs, mcs, tbs, ue.cfg->ue_cfg()->maxharq_tx); + bool success = ue.h_ul->new_tx(ue.pusch_slot, ue.pusch_slot, ul_prbs, mcs, ue.cfg->ue_cfg()->maxharq_tx); srsran_assert(success, "Failed to allocate UL HARQ"); } else { bool success = ue.h_ul->new_retx(ue.pusch_slot, ue.pusch_slot, ul_prbs); diff --git a/srsenb/src/stack/mac/nr/sched_nr_harq.cc b/srsenb/src/stack/mac/nr/sched_nr_harq.cc index 003925a3a..6019190fa 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_harq.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_harq.cc @@ -48,7 +48,6 @@ bool harq_proc::new_tx(slot_point slot_tx_, slot_point slot_ack_, const prb_grant& grant, uint32_t mcs, - uint32_t tbs, uint32_t max_retx_) { if (not empty()) { @@ -61,20 +60,26 @@ bool harq_proc::new_tx(slot_point slot_tx_, prbs_ = grant; tb[0].ndi = !tb[0].ndi; tb[0].mcs = mcs; - tb[0].tbs = tbs; + tb[0].tbs = 0; tb[0].active = true; return true; } -bool harq_proc::set_tbs(uint32_t tbs, int mcs) +bool harq_proc::set_tbs(uint32_t tbs) { if (empty() or nof_retx() > 0) { return false; } tb[0].tbs = tbs; - if (mcs >= 0) { - tb[0].mcs = mcs; + return true; +} + +bool harq_proc::set_mcs(uint32_t mcs) +{ + if (empty() or nof_retx() > 0) { + return false; } + tb[0].mcs = mcs; return true; } @@ -112,10 +117,9 @@ bool dl_harq_proc::new_tx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant, uint32_t mcs, - uint32_t tbs, uint32_t max_retx) { - if (harq_proc::new_tx(slot_tx, slot_ack, grant, mcs, tbs, max_retx)) { + if (harq_proc::new_tx(slot_tx, slot_ack, grant, mcs, max_retx)) { softbuffer->reset(); pdu->clear(); return true; diff --git a/srsenb/src/stack/mac/nr/sched_nr_helpers.cc b/srsenb/src/stack/mac/nr/sched_nr_helpers.cc index 015059778..e1ed7032b 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_helpers.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_helpers.cc @@ -156,7 +156,7 @@ void log_sched_bwp_result(srslog::basic_logger& logger, ue.h_dl->prbs(), ue.h_dl->nof_retx(), pdcch.dci.dai, - ue.h_dl->tbs(), + ue.h_dl->tbs() / 8u, ue.dl_pending_bytes, ue.pdsch_slot, ue.uci_slot); @@ -193,7 +193,7 @@ void log_sched_bwp_result(srslog::basic_logger& logger, pdcch.dci.ctx.coreset_id, srsran_dci_format_nr_string(pdcch.dci.ctx.format), ue.h_ul->nof_retx(), - ue.h_ul->tbs(), + ue.h_ul->tbs() / 8u, ue.ul_pending_bytes, ue.pusch_slot); } else if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_tc) { From 1db683053f73a217a4582420456807190f05d123 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 15 Oct 2021 17:33:11 +0200 Subject: [PATCH 186/208] enb,mac: fix buffer setting when receiving SBSR the MAX_LCG is 7 so the loop needs to be inclusive to set all 8 LCGs to 0 --- srsenb/src/stack/mac/nr/ue_nr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc index 6c0bcbbfc..57cc02dbb 100644 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ b/srsenb/src/stack/mac/nr/ue_nr.cc @@ -107,7 +107,7 @@ int ue_nr::process_pdu(srsran::unique_byte_buffer_t pdu) uint32_t buffer_size_bytes = buff_size_field_to_bytes(sbsr.buffer_size, srsran::SHORT_BSR); // Assume all LCGs are 0 if reported SBSR is 0 if (buffer_size_bytes == 0) { - for (uint32_t j = 0; j < SCHED_NR_MAX_LC_GROUP; j++) { + for (uint32_t j = 0; j <= SCHED_NR_MAX_LC_GROUP; j++) { sched->ul_bsr(rnti, j, 0); } } else { From d7e2f442f7081818e781b94b1a72edae8b24bb33 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 15 Sep 2021 18:16:47 +0100 Subject: [PATCH 187/208] Adding option to remove UE contexts if SCTP error occors. This was done as after an SCTP error, the MME would try to page the UE, but the UE was already RRC Connected. --- srsenb/src/stack/s1ap/s1ap.cc | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/srsenb/src/stack/s1ap/s1ap.cc b/srsenb/src/stack/s1ap/s1ap.cc index 75657a0c0..16fd551a2 100644 --- a/srsenb/src/stack/s1ap/s1ap.cc +++ b/srsenb/src/stack/s1ap/s1ap.cc @@ -553,17 +553,29 @@ bool s1ap::handle_mme_rx_msg(srsran::unique_byte_buffer_t pdu, // Received notification union sctp_notification* notification = (union sctp_notification*)pdu->msg; logger.info("SCTP Notification %04x", notification->sn_header.sn_type); + bool restart_s1 = false; if (notification->sn_header.sn_type == SCTP_SHUTDOWN_EVENT) { logger.info("SCTP Association Shutdown. Association: %d", sri.sinfo_assoc_id); srsran::console("SCTP Association Shutdown. Association: %d\n", sri.sinfo_assoc_id); - rx_socket_handler->remove_socket(mme_socket.get_socket()); - mme_socket.close(); + restart_s1 = true; } else if (notification->sn_header.sn_type == SCTP_PEER_ADDR_CHANGE && notification->sn_paddr_change.spc_state == SCTP_ADDR_UNREACHABLE) { logger.info("SCTP peer addres unreachable. Association: %d", sri.sinfo_assoc_id); srsran::console("SCTP peer address unreachable. Association: %d\n", sri.sinfo_assoc_id); + restart_s1 = true; + } + if (restart_s1) { + logger.info("Restarting S1 connection"); + srsran::console("Restarting S1 connection\n"); rx_socket_handler->remove_socket(mme_socket.get_socket()); mme_socket.close(); + while (users.size() != 0) { + std::unordered_map >::iterator it = users.begin(); + uint16_t rnti = it->second->ctxt.rnti; + rrc->release_erabs(rnti); + rrc->release_ue(rnti); + users.erase(it->second.get()); + } } } else if (pdu->N_bytes == 0) { logger.error("SCTP return 0 bytes. Closing socket"); From 59df04547e609316ea2d3cf0278012b91874cf66 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Mon, 18 Oct 2021 16:46:00 +0200 Subject: [PATCH 188/208] Increase buffer size for NR. --- lib/include/srsran/asn1/asn1_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/include/srsran/asn1/asn1_utils.h b/lib/include/srsran/asn1/asn1_utils.h index af8c3770e..2441ae15a 100644 --- a/lib/include/srsran/asn1/asn1_utils.h +++ b/lib/include/srsran/asn1/asn1_utils.h @@ -1311,7 +1311,7 @@ private: bit_ref brefstart; // bit_ref bref0; bit_ref* bref_tracker; - uint8_t buffer[2048]; + uint8_t buffer[4096]; bool align; }; From 51806982f73c174ea23b0238847fb82a971f4e27 Mon Sep 17 00:00:00 2001 From: Francisco Date: Mon, 18 Oct 2021 22:11:46 +0100 Subject: [PATCH 189/208] nr,gnb,rrc: correctly release NR RNTI user after Reestablishment --- srsenb/hdr/stack/rrc/rrc_endc.h | 25 ++++++++++++++----------- srsenb/src/stack/rrc/rrc.cc | 2 +- srsenb/src/stack/rrc/rrc_endc.cc | 25 ++++++++++++++++--------- srsenb/src/stack/rrc/rrc_nr.cc | 6 +++++- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_endc.h b/srsenb/hdr/stack/rrc/rrc_endc.h index 5975199f4..a1f81433a 100644 --- a/srsenb/hdr/stack/rrc/rrc_endc.h +++ b/srsenb/hdr/stack/rrc/rrc_endc.h @@ -126,11 +126,13 @@ private: struct endc_disabled_st {}; // EN-DC disabled // FSM guards + bool requires_rel_req(const sgnb_rel_req_ev& ev); + bool skip_rel_req(const sgnb_rel_req_ev& ev); // FSM transition handlers void handle_sgnb_add_req_ack(wait_sgnb_add_req_resp_st& s, const sgnb_add_req_ack_ev& ev); - void handle_sgnb_rel_req(endc_activated_st& s, const sgnb_rel_req_ev& ev); - void handle_rrc_reest(const rrc_reest_rx_ev& ev); + void handle_sgnb_rel_req(const sgnb_rel_req_ev& ev); + void handle_rrc_reest(endc_activated_st& s, const rrc_reest_rx_ev& ev); void handle_endc_disabled(const disable_endc_ev& ev); protected: @@ -157,17 +159,18 @@ protected: using transitions = transition_table< // Start Target Event Action Guard // +---------------------------+--------------------------+------------------------+------------------------------+-------------------------+ - row< endc_deactivated_st, wait_sgnb_add_req_resp_st, sgnb_add_req_sent_ev, nullptr >, + row< endc_deactivated_st, wait_sgnb_add_req_resp_st, sgnb_add_req_sent_ev, nullptr >, // +---------------------------+--------------------------+------------------------+------------------------------+-------------------------+ - row< wait_sgnb_add_req_resp_st, prepare_recfg_st, sgnb_add_req_ack_ev, &fsm::handle_sgnb_add_req_ack >, - row< wait_sgnb_add_req_resp_st, endc_deactivated_st, sgnb_add_req_reject_ev >, - row< prepare_recfg_st, wait_add_complete_st, rrc_recfg_sent_ev >, - row< wait_add_complete_st, endc_activated_st, sgnb_add_complete_ev >, + row< wait_sgnb_add_req_resp_st, prepare_recfg_st, sgnb_add_req_ack_ev, &fsm::handle_sgnb_add_req_ack >, + row< wait_sgnb_add_req_resp_st, endc_deactivated_st, sgnb_add_req_reject_ev >, + row< prepare_recfg_st, wait_add_complete_st, rrc_recfg_sent_ev >, + row< wait_add_complete_st, endc_activated_st, sgnb_add_complete_ev >, + upd< endc_activated_st, rrc_reest_rx_ev, &fsm::handle_rrc_reest >, // +---------------------------+--------------------------+------------------------+------------------------------+-------------------------+ - row< endc_activated_st, wait_sgnb_rel_req_resp_st, sgnb_rel_req_ev, &fsm::handle_sgnb_rel_req >, - to_state< endc_deactivated_st, rrc_reest_rx_ev, &fsm::handle_rrc_reest >, - row< wait_sgnb_rel_req_resp_st, endc_deactivated_st, sgnb_rel_req_ack_ev >, - to_state< endc_disabled_st, disable_endc_ev, &fsm::handle_endc_disabled > + to_state< wait_sgnb_rel_req_resp_st, sgnb_rel_req_ev, &fsm::handle_sgnb_rel_req, &fsm::requires_rel_req >, + to_state< endc_deactivated_st, sgnb_rel_req_ev, &fsm::handle_sgnb_rel_req, &fsm::skip_rel_req >, + row< wait_sgnb_rel_req_resp_st, endc_deactivated_st, sgnb_rel_req_ack_ev >, + to_state< endc_disabled_st, disable_endc_ev, &fsm::handle_endc_disabled > >; // clang-format on }; diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index f4fbd6245..31cbae59e 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -569,7 +569,7 @@ void rrc::set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_st void rrc::sgnb_addition_ack(uint16_t eutra_rnti, sgnb_addition_ack_params_t params) { - logger.info("Received SgNB addition acknowledgement for rnti=%d", eutra_rnti); + logger.info("Received SgNB addition 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_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index 8baeb1ac7..119464d2f 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -312,7 +312,7 @@ void rrc::ue::rrc_endc::start_sgnb_addition() rrc_nr_interface_rrc::sgnb_addition_req_params_t params = {}; params.eps_bearer_id = rrc_enb->bearer_manager.get_lcid_bearer(rrc_ue->rnti, drb_to_lcid((lte_drb)eutra_drb_id)).eps_bearer_id; - logger.info("Triggering SgNB addition"); + logger.info("Triggering SgNB addition for E-UTRA rnti=0x%x", rrc_ue->rnti); rrc_enb->rrc_nr->sgnb_addition_request(rrc_ue->rnti, params); sgnb_add_req_sent_ev sgnb_add_req{}; @@ -358,9 +358,10 @@ void rrc::ue::rrc_endc::handle_sgnb_add_req_ack(wait_sgnb_add_req_resp_st& s, co nr_rnti = ev.params.nr_rnti; } -void rrc::ue::rrc_endc::handle_sgnb_rel_req(endc_activated_st& s, const sgnb_rel_req_ev& ev) +void rrc::ue::rrc_endc::handle_sgnb_rel_req(const sgnb_rel_req_ev& ev) { - logger.info("Triggering SgNB release"); + logger.info("Triggering SgNB release for E-UTRA rnti=0x%x", rrc_ue->rnti); + rrc_enb->bearer_manager.rem_user(nr_rnti); rrc_enb->rrc_nr->sgnb_release_request(nr_rnti); } @@ -369,14 +370,10 @@ bool rrc::ue::rrc_endc::is_endc_supported() return not is_in_state(); } -void rrc::ue::rrc_endc::handle_rrc_reest(const rrc_reest_rx_ev& ev) +void rrc::ue::rrc_endc::handle_rrc_reest(endc_activated_st& s, const rrc_reest_rx_ev& ev) { - auto& sgnb_config = get_state()->sgnb_config; - // Transition GTPU tunnel rnti back from NR RNTI to LTE RNTI, given that the reconfiguration failed - rrc_enb->gtpu->mod_bearer_rnti(sgnb_config.nr_rnti, rrc_ue->rnti); - - rrc_enb->bearer_manager.rem_user(sgnb_config.nr_rnti); + rrc_enb->gtpu->mod_bearer_rnti(nr_rnti, rrc_ue->rnti); } void rrc::ue::rrc_endc::handle_endc_disabled(const disable_endc_ev& ev) @@ -384,4 +381,14 @@ void rrc::ue::rrc_endc::handle_endc_disabled(const disable_endc_ev& ev) logger.info("Disabling NR EN-DC support for rnti=0x%x", nr_rnti); } +bool rrc::ue::rrc_endc::requires_rel_req(const sgnb_rel_req_ev& ev) +{ + return not is_in_state() and not is_in_state(); +} + +bool rrc::ue::rrc_endc::skip_rel_req(const sgnb_rel_req_ev& ev) +{ + return not requires_rel_req(ev) and not is_in_state(); +} + } // namespace srsenb diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index f2d70e741..d03968ee1 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -538,8 +538,12 @@ int 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); - rrc_eutra->sgnb_release_ack(nr_rnti); + if (eutra_rnti != SRSRAN_INVALID_RNTI) { + rrc_eutra->sgnb_release_ack(eutra_rnti); + } }); return SRSRAN_SUCCESS; } From d4a4da7eccf790369c1b97d3c220e62fa0712bb9 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 18 Oct 2021 20:51:56 +0200 Subject: [PATCH 190/208] mux_nr: fix tiny issue in mux unit when adding SDUs of different logical channels this issue has a tiny affect when adding new SDUs from different logical channels to an UL MAC PDU. Since the MAC subPDU header is accounted for twice, less SDU payload may be packed. The patch calculates the required header space and accounts for it in the scheduling. Howerver, it is only substracted from the available space when an SDU was actually added. --- srsue/src/stack/mac_nr/mux_nr.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/srsue/src/stack/mac_nr/mux_nr.cc b/srsue/src/stack/mac_nr/mux_nr.cc index 001dea03f..3fd79f01f 100644 --- a/srsue/src/stack/mac_nr/mux_nr.cc +++ b/srsue/src/stack/mac_nr/mux_nr.cc @@ -94,10 +94,10 @@ srsran::unique_byte_buffer_t mux_nr::get_pdu(uint32_t max_pdu_len) uint8_t* rd = rlc_buff->msg; // Determine space for RLC - remaining_len -= remaining_len >= srsran::mac_sch_subpdu_nr::MAC_SUBHEADER_LEN_THRESHOLD ? 3 : 2; + int32_t subpdu_header_len = (remaining_len >= srsran::mac_sch_subpdu_nr::MAC_SUBHEADER_LEN_THRESHOLD ? 3 : 2); - // Read PDU from RLC - int pdu_len = rlc->read_pdu(lc.lcid, rd, remaining_len); + // Read PDU from RLC (account for subPDU header) + int pdu_len = rlc->read_pdu(lc.lcid, rd, remaining_len - subpdu_header_len); if (pdu_len > remaining_len) { logger.error("Can't add SDU of %d B. Available space %d B", pdu_len, remaining_len); @@ -114,10 +114,11 @@ srsran::unique_byte_buffer_t mux_nr::get_pdu(uint32_t max_pdu_len) break; } } else { + // couldn't read PDU from RLC break; } - remaining_len -= pdu_len; + remaining_len -= (pdu_len + subpdu_header_len); logger.debug("%d B remaining PDU", remaining_len); } } From 97d43eb0443fb041d11cc0ed63cbba8c4751f8b5 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 18 Oct 2021 20:55:19 +0200 Subject: [PATCH 191/208] mac_nr_test: add PDU packing test for two SDUs from different LCs --- srsue/src/stack/mac_nr/test/mac_nr_test.cc | 88 ++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/srsue/src/stack/mac_nr/test/mac_nr_test.cc b/srsue/src/stack/mac_nr/test/mac_nr_test.cc index f6bbc28ba..460e813ca 100644 --- a/srsue/src/stack/mac_nr/test/mac_nr_test.cc +++ b/srsue/src/stack/mac_nr/test/mac_nr_test.cc @@ -514,6 +514,92 @@ int mac_nr_ul_logical_channel_prioritization_test3() return SRSRAN_SUCCESS; } +// Correct packing of MAC PDU with two SDUs for different LCIDs +int mac_nr_ul_logical_channel_prioritization_test4() +{ + // PDU layout (24 B in total) + const uint8_t tv[] = {0x04, 0x0a, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x05, 0x0a, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05}; + + // dummy layers + dummy_phy phy; + rlc_dummy rlc; + rrc_dummy rrc; + stack_dummy stack; + + // the actual MAC + mac_nr mac(&stack.task_sched); + + const uint16_t crnti = 0x1001; + mac_nr_args_t args = {}; + mac.init(args, &phy, &rlc, &rrc); + mac.set_crnti(crnti); + + stack.init(&mac, &phy); + + // generate config for two DRBs + std::vector lcids; + srsran::logical_channel_config_t config = {}; + config.lcid = 4; + config.lcg = 6; + config.PBR = 0; + config.BSD = 1000; // 1000ms + config.priority = 11; + lcids.push_back(config); + + config.lcid = 5; + config.lcg = 7; + config.PBR = 0; + config.BSD = 1000; // 1000ms + config.priority = 12; + lcids.push_back(config); + + // setup LCIDs in MAC + for (auto& channel : lcids) { + mac.setup_lcid(channel); + } + + // write one SDU to each DRB + const uint32_t sdu_len = 10; + rlc.write_sdu(4, sdu_len); + rlc.write_sdu(5, sdu_len); + + // run TTI to setup Bj, BSR should be generated + stack.run_tti(0); + usleep(100); + + // create UL action and grant and read MAC PDU + { + mac_interface_phy_nr::tb_action_ul_t ul_action = {}; + mac_interface_phy_nr::mac_nr_grant_ul_t mac_grant = {}; + + mac_grant.rnti = crnti; // make sure MAC picks it up as valid UL grant + mac_grant.pid = 0; + mac_grant.tti = 0; + mac_grant.tbs = 24; + int cc_idx = 0; + + // Send grant to MAC and get action for this TB, 0x + mac.new_grant_ul(cc_idx, mac_grant, &ul_action); + + // print generated PDU + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload->msg, mac_grant.tbs, "Generated PDU (%d B)", mac_grant.tbs); +#if HAVE_PCAP + pcap_handle->write_ul_crnti_nr( + ul_action.tb.payload->msg, mac_grant.tbs, mac_grant.rnti, UE_ID, mac_grant.pid, mac_grant.tti); +#endif + + TESTASSERT(memcmp(ul_action.tb.payload->msg, tv, sizeof(tv)) == 0); + } + + // make sure MAC PDU thread picks up before stopping + stack.run_tti(0); + mac.stop(); + + return SRSRAN_SUCCESS; +} + // Basic test for periodic BSR transmission int mac_nr_ul_periodic_bsr_test() { @@ -800,6 +886,8 @@ int main() TESTASSERT(mac_nr_ul_logical_channel_prioritization_test1() == SRSRAN_SUCCESS); TESTASSERT(mac_nr_ul_logical_channel_prioritization_test2() == SRSRAN_SUCCESS); TESTASSERT(mac_nr_ul_logical_channel_prioritization_test3() == SRSRAN_SUCCESS); + TESTASSERT(mac_nr_ul_logical_channel_prioritization_test4() == SRSRAN_SUCCESS); + TESTASSERT(mac_nr_ul_periodic_bsr_test() == SRSRAN_SUCCESS); TESTASSERT(mac_nr_dl_retx_test() == SRSRAN_SUCCESS); From 146f12f0c0365107b16f16ce68aa4ca73123065e Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 18 Oct 2021 20:56:07 +0200 Subject: [PATCH 192/208] enb,mac_nr: fix MAC PDU packing by tyring to pack multiple SDUs when possible the patch adds support to fully use the available space in a MAC PDU by adding multiple SDUs. --- srsenb/hdr/stack/mac/nr/ue_nr.h | 3 ++ srsenb/src/stack/mac/nr/ue_nr.cc | 63 +++++++++++++++++++++++--------- 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/ue_nr.h b/srsenb/hdr/stack/mac/nr/ue_nr.h index b5d1cf6a2..59ef98a15 100644 --- a/srsenb/hdr/stack/mac/nr/ue_nr.h +++ b/srsenb/hdr/stack/mac/nr/ue_nr.h @@ -96,6 +96,9 @@ private: ue_rx_pdu_queue; ///< currently only DCH PDUs supported (add BCH, PCH, etc) srsran::unique_byte_buffer_t ue_rlc_buffer; + static constexpr int32_t MIN_RLC_PDU_LEN = + 5; ///< minimum bytes that need to be available in a MAC PDU for attempting to add another RLC SDU + // Mutexes std::mutex mutex; }; diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc index 57cc02dbb..0e7a3779b 100644 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ b/srsenb/src/stack/mac/nr/ue_nr.cc @@ -76,8 +76,7 @@ int ue_nr::process_pdu(srsran::unique_byte_buffer_t pdu) // Reverse the order in which MAC subPDUs get processed. // First, process MAC CEs, then MAC MAC subPDUs with MAC SDUs - for (uint32_t n = mac_pdu_ul.get_num_subpdus(), i = mac_pdu_ul.get_num_subpdus() - 1; n > 0; - --n, i = n - 1) { + for (uint32_t n = mac_pdu_ul.get_num_subpdus(), i = mac_pdu_ul.get_num_subpdus() - 1; n > 0; --n, i = n - 1) { srsran::mac_sch_subpdu_nr subpdu = mac_pdu_ul.get_subpdu(i); logger.debug("Handling subPDU %d/%d: lcid=%d, sdu_len=%d", i, @@ -145,30 +144,58 @@ int ue_nr::generate_pdu(srsran::byte_buffer_t* pdu, uint32_t grant_size) return SRSRAN_ERROR; } - // read RLC PDU - ue_rlc_buffer->clear(); - int lcid = 4; - int pdu_len = - rlc->read_pdu(rnti, lcid, ue_rlc_buffer->msg, grant_size - mac_pdu_dl.size_header_sdu(lcid, grant_size)); + bool drb_activity = false; // inform RRC about user activity if true + int lcid = 4; // only supporting single DRB right now - // Only create PDU if RLC has something to tx - if (pdu_len > 0) { - logger.debug("Adding MAC PDU for RNTI=%d", rnti); - ue_rlc_buffer->N_bytes = pdu_len; - logger.debug(ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes, "Read %d B from RLC", ue_rlc_buffer->N_bytes); + int32_t remaining_len = mac_pdu_dl.get_remaing_len(); - // add to MAC PDU and pack - mac_pdu_dl.add_sdu(lcid, ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes); + logger.debug("Adding MAC PDU for RNTI=%d (max %d B)", rnti, remaining_len); + while (remaining_len >= MIN_RLC_PDU_LEN) { + // clear read buffer + ue_rlc_buffer->clear(); - // Indicate DRB activity in DL to RRC - if (lcid > 3) { - rrc->set_activity_user(rnti); - logger.debug("DL activity rnti=0x%x, n_bytes=%d", rnti, ue_rlc_buffer->N_bytes); + // Determine space for RLC + remaining_len -= remaining_len >= srsran::mac_sch_subpdu_nr::MAC_SUBHEADER_LEN_THRESHOLD ? 3 : 2; + + // read RLC PDU + int pdu_len = rlc->read_pdu(rnti, lcid, ue_rlc_buffer->msg, remaining_len); + + if (pdu_len > remaining_len) { + logger.error("Can't add SDU of %d B. Available space %d B", pdu_len, remaining_len); + break; + } else { + // Add SDU if RLC has something to tx + if (pdu_len > 0) { + ue_rlc_buffer->N_bytes = pdu_len; + logger.debug(ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes, "Read %d B from RLC", ue_rlc_buffer->N_bytes); + + // add to MAC PDU and pack + if (mac_pdu_dl.add_sdu(lcid, ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes) != SRSRAN_SUCCESS) { + logger.error("Error packing MAC PDU"); + break; + } + + // set DRB activity flag but only notify RRC once + if (lcid > 3) { + drb_activity = true; + } + } else { + break; + } + + remaining_len -= pdu_len; + logger.debug("%d B remaining PDU", remaining_len); } } mac_pdu_dl.pack(); + if (drb_activity) { + // Indicate DRB activity in DL to RRC + rrc->set_activity_user(rnti); + logger.debug("DL activity rnti=0x%x", rnti); + } + if (logger.info.enabled()) { fmt::memory_buffer str_buffer; mac_pdu_dl.to_string(str_buffer); From d32bfa3756cb62c6909cdda6c2a62be47e907eb0 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 19 Oct 2021 11:59:38 +0200 Subject: [PATCH 193/208] remove warning when UE is already in camping --- srsue/hdr/phy/sync.h | 10 +++------- srsue/src/phy/sync.cc | 11 ++++------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/srsue/hdr/phy/sync.h b/srsue/hdr/phy/sync.h index 677ac6a1f..73c2fd48d 100644 --- a/srsue/hdr/phy/sync.h +++ b/srsue/hdr/phy/sync.h @@ -279,15 +279,11 @@ private: std::lock_guard lock(mutex); return std::isnormal(current_srate) and current_srate > 0.0f; } - bool set_camp(float new_srate) + void set_camp(float new_srate) { std::lock_guard lock(mutex); - if (srate_mode != SRATE_CAMP) { - current_srate = new_srate; - srate_mode = SRATE_CAMP; - return true; - } - return false; + current_srate = new_srate; + srate_mode = SRATE_CAMP; } bool set_find() { diff --git a/srsue/src/phy/sync.cc b/srsue/src/phy/sync.cc index 4d0f0cfe5..e799fb96f 100644 --- a/srsue/src/phy/sync.cc +++ b/srsue/src/phy/sync.cc @@ -927,13 +927,10 @@ void sync::set_sampling_rate() return; } - if (srate.set_camp(new_srate)) { - Info("SYNC: Setting sampling rate %.2f MHz", new_srate / 1000000); - radio_h->set_rx_srate(new_srate); - radio_h->set_tx_srate(new_srate); - } else { - Error("Error setting sampling rate for cell with %d PRBs", cell.get().nof_prb); - } + srate.set_camp(new_srate); + Info("SYNC: Setting sampling rate %.2f MHz", new_srate / 1000000); + radio_h->set_rx_srate(new_srate); + radio_h->set_tx_srate(new_srate); } uint32_t sync::get_current_tti() From 0b51848ddab6391a113ed1004890f4df9b21d2ec Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 19 Oct 2021 11:36:25 +0100 Subject: [PATCH 194/208] 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); + } } /******************************************************************************* From b3e974db9bb3f6337d1922bd68cca8e7fe0a2e03 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 19 Oct 2021 12:42:41 +0100 Subject: [PATCH 195/208] nr,gnb,rrc: avoid warning when eutra requests sgnb release and destroys the UE before acknowledgement --- srsenb/hdr/stack/rrc/rrc_endc.h | 2 -- srsenb/src/stack/rrc/rrc.cc | 11 ++++++----- srsenb/src/stack/rrc/rrc_endc.cc | 8 ++------ 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_endc.h b/srsenb/hdr/stack/rrc/rrc_endc.h index a1f81433a..d835a4842 100644 --- a/srsenb/hdr/stack/rrc/rrc_endc.h +++ b/srsenb/hdr/stack/rrc/rrc_endc.h @@ -127,7 +127,6 @@ private: // FSM guards bool requires_rel_req(const sgnb_rel_req_ev& ev); - bool skip_rel_req(const sgnb_rel_req_ev& ev); // FSM transition handlers void handle_sgnb_add_req_ack(wait_sgnb_add_req_resp_st& s, const sgnb_add_req_ack_ev& ev); @@ -168,7 +167,6 @@ protected: upd< endc_activated_st, rrc_reest_rx_ev, &fsm::handle_rrc_reest >, // +---------------------------+--------------------------+------------------------+------------------------------+-------------------------+ to_state< wait_sgnb_rel_req_resp_st, sgnb_rel_req_ev, &fsm::handle_sgnb_rel_req, &fsm::requires_rel_req >, - to_state< endc_deactivated_st, sgnb_rel_req_ev, &fsm::handle_sgnb_rel_req, &fsm::skip_rel_req >, row< wait_sgnb_rel_req_resp_st, endc_deactivated_st, sgnb_rel_req_ack_ev >, to_state< endc_disabled_st, disable_endc_ev, &fsm::handle_endc_disabled > >; diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index 4213f8d1a..a8e523301 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -605,13 +605,14 @@ 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=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); - return; + if (ue_it != users.end()) { + logger.info("Received SgNB release acknowledgement for rnti=0x%x", eutra_rnti); + ue_it->second->endc_handler->trigger(ue::rrc_endc::sgnb_rel_req_ack_ev{}); + } else { + // The EUTRA does not need to wait for Release Ack in case it wants to destroy the EUTRA UE + logger.info("Received SgNB release acknowledgement for already released rnti=0x%x", eutra_rnti); } - ue_it->second->endc_handler->trigger(ue::rrc_endc::sgnb_rel_req_ack_ev{}); } /******************************************************************************* diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index 119464d2f..49f3676b2 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -383,12 +383,8 @@ void rrc::ue::rrc_endc::handle_endc_disabled(const disable_endc_ev& ev) bool rrc::ue::rrc_endc::requires_rel_req(const sgnb_rel_req_ev& ev) { - return not is_in_state() and not is_in_state(); -} - -bool rrc::ue::rrc_endc::skip_rel_req(const sgnb_rel_req_ev& ev) -{ - return not requires_rel_req(ev) and not is_in_state(); + return not is_in_state() and not is_in_state() and + not is_in_state(); } } // namespace srsenb From 859f4d2185ee50f4bfc64c7ff33cf3f19eff4c94 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 19 Oct 2021 15:02:38 +0100 Subject: [PATCH 196/208] nr,gnb,sched: avoid logging warning for pending feedback of UEs that were just removed --- srsenb/src/stack/mac/nr/sched_nr.cc | 9 ++++++++- srsenb/src/stack/mac/nr/sched_nr_worker.cc | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/srsenb/src/stack/mac/nr/sched_nr.cc b/srsenb/src/stack/mac/nr/sched_nr.cc index b0acfabf4..89cbff2b0 100644 --- a/srsenb/src/stack/mac/nr/sched_nr.cc +++ b/srsenb/src/stack/mac/nr/sched_nr.cc @@ -101,7 +101,14 @@ void sched_nr::ue_cfg(uint16_t rnti, const ue_cfg_t& uecfg) void sched_nr::ue_rem(uint16_t rnti) { - sched_workers->enqueue_event(rnti, [this, rnti]() { ue_db.erase(rnti); }); + sched_workers->enqueue_event(rnti, [this, rnti]() { + auto ue_it = ue_db.find(rnti); + if (ue_it == ue_db.end()) { + logger->warning("SCHED: ue_rem(rnti) called for inexistent rnti=0x%x", rnti); + return; + } + ue_db.erase(rnti); + }); } bool sched_nr::ue_exists(uint16_t rnti) diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc index ce992962c..97be29928 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_worker.cc @@ -57,7 +57,7 @@ void slot_cc_worker::run_feedback(ue_map_t& ue_db) if (ue_db.contains(f.rnti) and ue_db[f.rnti]->carriers[cfg.cc] != nullptr) { f.fdbk(*ue_db[f.rnti]->carriers[cfg.cc]); } else { - logger.warning("SCHED: feedback received for invalid rnti=0x%x, cc=%d", f.rnti, cfg.cc); + logger.info("SCHED: feedback received for rnti=0x%x, cc=%d that has been removed.", f.rnti, cfg.cc); } } tmp_feedback_to_run.clear(); From 9ecea014bd6624c16d335f9e637cf3b3ee6cc38c Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 19 Oct 2021 17:13:56 +0200 Subject: [PATCH 197/208] Added PUSCH DMRS minimum SNR --- lib/include/srsran/phy/gnb/gnb_ul.h | 2 ++ lib/src/phy/gnb/gnb_ul.c | 20 ++++++++++++++++++++ srsenb/hdr/phy/nr/slot_worker.h | 1 + srsenb/hdr/phy/nr/worker_pool.h | 1 + srsenb/src/phy/nr/slot_worker.cc | 1 + srsenb/src/phy/nr/worker_pool.cc | 1 + 6 files changed, 26 insertions(+) diff --git a/lib/include/srsran/phy/gnb/gnb_ul.h b/lib/include/srsran/phy/gnb/gnb_ul.h index 424d068dd..c13f50103 100644 --- a/lib/include/srsran/phy/gnb/gnb_ul.h +++ b/lib/include/srsran/phy/gnb/gnb_ul.h @@ -21,6 +21,7 @@ typedef struct SRSRAN_API { srsran_pusch_nr_args_t pusch; srsran_pucch_nr_args_t pucch; + float pusch_min_snr_dB; ///< Minimum SNR threshold to decode PUSCH, set to 0 for default value uint32_t nof_max_prb; } srsran_gnb_ul_args_t; @@ -36,6 +37,7 @@ typedef struct SRSRAN_API { srsran_dmrs_sch_t dmrs; srsran_chest_dl_res_t chest_pusch; srsran_chest_ul_res_t chest_pucch; + float pusch_min_snr_dB; ///< Minimum measured DMRS SNR, below this threshold PUSCH is not decoded } srsran_gnb_ul_t; SRSRAN_API int srsran_gnb_ul_init(srsran_gnb_ul_t* q, cf_t* input, const srsran_gnb_ul_args_t* args); diff --git a/lib/src/phy/gnb/gnb_ul.c b/lib/src/phy/gnb/gnb_ul.c index 7e2c48847..13fd7a0cc 100644 --- a/lib/src/phy/gnb/gnb_ul.c +++ b/lib/src/phy/gnb/gnb_ul.c @@ -20,6 +20,11 @@ */ #define GNB_UL_NR_FFT_WINDOW_OFFSET 0.5f +/** + * @brief Minimum PUSCH DMRS measured SINR default value + */ +#define GNB_UL_PUSCH_MIN_SNR_DEFAULT -10.0f + static int gnb_ul_alloc_prb(srsran_gnb_ul_t* q, uint32_t new_nof_prb) { if (q->max_prb < new_nof_prb) { @@ -83,6 +88,12 @@ int srsran_gnb_ul_init(srsran_gnb_ul_t* q, cf_t* input, const srsran_gnb_ul_args return SRSRAN_ERROR; } + // Set PUSCH minimum SNR, use default value if the given is NAN, INF or zero + q->pusch_min_snr_dB = GNB_UL_PUSCH_MIN_SNR_DEFAULT; + if (isnormal(args->pusch_min_snr_dB)) { + q->pusch_min_snr_dB = args->pusch_min_snr_dB; + } + return SRSRAN_SUCCESS; } @@ -169,6 +180,15 @@ int srsran_gnb_ul_get_pusch(srsran_gnb_ul_t* q, return SRSRAN_ERROR; } + // Check PUSCH DMRS minimum SNR and abort PUSCH decoding if it is below the threshold + if (q->dmrs.csi.snr_dB < q->pusch_min_snr_dB) { + // Set PUSCH data as not decoded + data->tb[0].crc = false; + data->tb[0].avg_iter = NAN; + data->uci.valid = false; + return SRSRAN_SUCCESS; + } + if (srsran_pusch_nr_decode(&q->pusch, cfg, grant, &q->chest_pusch, q->sf_symbols, data) < SRSRAN_SUCCESS) { return SRSRAN_ERROR; } diff --git a/srsenb/hdr/phy/nr/slot_worker.h b/srsenb/hdr/phy/nr/slot_worker.h index 3bb515dbe..355f10d26 100644 --- a/srsenb/hdr/phy/nr/slot_worker.h +++ b/srsenb/hdr/phy/nr/slot_worker.h @@ -57,6 +57,7 @@ public: uint32_t rf_port = 0; srsran_subcarrier_spacing_t scs = srsran_subcarrier_spacing_15kHz; uint32_t pusch_max_nof_iter = 10; + float pusch_min_snr_dB = -10.0f; double srate_hz = 0.0; }; diff --git a/srsenb/hdr/phy/nr/worker_pool.h b/srsenb/hdr/phy/nr/worker_pool.h index 300c43fc4..f61afbfda 100644 --- a/srsenb/hdr/phy/nr/worker_pool.h +++ b/srsenb/hdr/phy/nr/worker_pool.h @@ -103,6 +103,7 @@ public: uint32_t nof_prach_workers = 0; uint32_t prio = 52; uint32_t pusch_max_nof_iter = 10; + float pusch_min_snr_dB = -10; srsran::phy_log_args_t log = {}; }; slot_worker* operator[](std::size_t pos) { return workers.at(pos).get(); } diff --git a/srsenb/src/phy/nr/slot_worker.cc b/srsenb/src/phy/nr/slot_worker.cc index fc835c0b7..bbe96fca7 100644 --- a/srsenb/src/phy/nr/slot_worker.cc +++ b/srsenb/src/phy/nr/slot_worker.cc @@ -78,6 +78,7 @@ bool slot_worker::init(const args_t& args) ul_args.pusch.max_layers = args.nof_rx_ports; ul_args.pusch.max_prb = args.nof_max_prb; ul_args.nof_max_prb = args.nof_max_prb; + ul_args.pusch_min_snr_dB = args.pusch_min_snr_dB; // Initialise UL if (srsran_gnb_ul_init(&gnb_ul, rx_buffer[0], &ul_args) < SRSRAN_SUCCESS) { diff --git a/srsenb/src/phy/nr/worker_pool.cc b/srsenb/src/phy/nr/worker_pool.cc index 0563c6e1c..e60caca40 100644 --- a/srsenb/src/phy/nr/worker_pool.cc +++ b/srsenb/src/phy/nr/worker_pool.cc @@ -63,6 +63,7 @@ bool worker_pool::init(const args_t& args, const phy_cell_cfg_list_nr_t& cell_li w_args.rf_port = cell_list[cell_index].rf_port; w_args.srate_hz = srate_hz; w_args.pusch_max_nof_iter = args.pusch_max_nof_iter; + w_args.pusch_min_snr_dB = args.pusch_min_snr_dB; if (not w->init(w_args)) { return false; From 2aa59a55d51adf981406a1eff4cdf75972740c36 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Tue, 19 Oct 2021 14:33:49 +0200 Subject: [PATCH 198/208] Read max turbo decoder iterations from conf. --- srsenb/enb.conf.example | 40 +++++++++--------- srsenb/hdr/phy/nr/slot_worker.h | 18 ++++---- srsenb/hdr/phy/nr/worker_pool.h | 14 +++---- srsenb/hdr/phy/phy_interfaces.h | 3 +- srsenb/src/main.cc | 71 ++++++++++++++++---------------- srsenb/src/phy/nr/worker_pool.cc | 2 +- srsenb/src/phy/phy.cc | 1 + test/phy/nr_phy_test.cc | 2 +- 8 files changed, 78 insertions(+), 73 deletions(-) diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index b7bf3dafa..f54c038ef 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -31,12 +31,12 @@ n_prb = 50 #nof_ports = 2 ##################################################################### -# eNB configuration files +# eNB configuration files # -# sib_config: SIB1, SIB2 and SIB3 configuration file +# sib_config: SIB1, SIB2 and SIB3 configuration file # note: when enabling mbms, use the sib.conf.mbsfn configuration file which includes SIB13 -# rr_config: Radio Resources configuration file -# rb_config: SRB/DRB configuration file +# rr_config: Radio Resources configuration file +# rb_config: SRB/DRB configuration file ##################################################################### [enb_files] sib_config = sib.conf @@ -47,7 +47,7 @@ rb_config = rb.conf # RF configuration # # dl_earfcn: EARFCN code for DL (only valid if a single cell is configured in rr.conf) -# tx_gain: Transmit gain (dB). +# tx_gain: Transmit gain (dB). # rx_gain: Optional receive gain (dB). If disabled, AGC if enabled # # Optional parameters: @@ -86,24 +86,24 @@ rx_gain = 40 ##################################################################### # Packet capture configuration # -# MAC-layer packets are captured to file a the compact format decoded -# by the Wireshark. For decoding, use the UDP dissector and the UDP -# heuristic dissection. Edit the preferences (Edit > Preferences > -# Protocols > DLT_USER) for DLT_USER to add an entry for DLT=149 with +# MAC-layer packets are captured to file a the compact format decoded +# by the Wireshark. For decoding, use the UDP dissector and the UDP +# heuristic dissection. Edit the preferences (Edit > Preferences > +# Protocols > DLT_USER) for DLT_USER to add an entry for DLT=149 with # Protocol=udp. Further, enable the heuristic dissection in UDP under: # Analyze > Enabled Protocols > MAC-LTE > mac_lte_udp and MAC-NR > mac_nr_udp # For more information see: https://wiki.wireshark.org/MAC-LTE -# Configuring this Wireshark preferences is needed for decoding the MAC PCAP -# files as well as for the live network capture option. +# Configuring this Wireshark preferences is needed for decoding the MAC PCAP +# files as well as for the live network capture option. # # Please note that this setting will by default only capture MAC # frames on dedicated channels, and not SIB. You have to build with # WRITE_SIB_PCAP enabled in srsenb/src/stack/mac/mac.cc if you want # SIB to be part of the MAC pcap file. # -# S1AP Packets are captured to file in the compact format decoded by -# the Wireshark s1ap dissector and with DLT 150. -# To use the dissector, edit the preferences for DLT_USER to +# S1AP Packets are captured to file in the compact format decoded by +# the Wireshark s1ap dissector and with DLT 150. +# To use the dissector, edit the preferences for DLT_USER to # add an entry with DLT=150, Payload Protocol=s1ap. # # mac_enable: Enable MAC layer packet captures (true/false) @@ -166,10 +166,10 @@ enable = false # max_aggr_level: Optional maximum aggregation level index (l=log2(L) can be 0, 1, 2 or 3) # adaptive_aggr_level: Boolean flag to enable/disable adaptive aggregation level based on target BLER # pdsch_mcs: Optional fixed PDSCH MCS (ignores reported CQIs if specified) -# pdsch_max_mcs: Optional PDSCH MCS limit +# pdsch_max_mcs: Optional PDSCH MCS limit # pusch_mcs: Optional fixed PUSCH MCS (ignores reported CQIs if specified) -# pusch_max_mcs: Optional PUSCH MCS limit -# min_nof_ctrl_symbols: Minimum number of control symbols +# pusch_max_mcs: Optional PUSCH MCS limit +# min_nof_ctrl_symbols: Minimum number of control symbols # max_nof_ctrl_symbols: Maximum number of control symbols # pucch_multiplex_enable: Allow PUCCH HARQ to collide with PUSCH and other PUCCH # pucch_harq_max_rb: Maximum number of RB to be used for PUCCH on the edges of the grid. @@ -328,10 +328,11 @@ enable = false ##################################################################### # Expert configuration options # -# pusch_max_its: Maximum number of turbo decoder iterations (Default 4) +# pusch_max_its: Maximum number of turbo decoder iterations for LTE (Default 4) +# nr_pusch_max_its: Maximum number of LDPC iterations for NR (Default 10) # pusch_8bit_decoder: Use 8-bit for LLR representation and turbo decoder trellis computation (Experimental) # nof_phy_threads: Selects the number of PHY threads (maximum 4, minimum 1, default 3) -# metrics_period_secs: Sets the period at which metrics are requested from the eNB. +# metrics_period_secs: Sets the period at which metrics are requested from the eNB. # metrics_csv_enable: Write eNB metrics to CSV file. # metrics_csv_filename: File path to use for CSV metrics. # report_json_enable: Write eNB report to JSON file (default disabled) @@ -362,6 +363,7 @@ enable = false ##################################################################### [expert] #pusch_max_its = 8 # These are half iterations +#nr_pusch_max_its = 10 #pusch_8bit_decoder = false #nof_phy_threads = 3 #metrics_period_secs = 1 diff --git a/srsenb/hdr/phy/nr/slot_worker.h b/srsenb/hdr/phy/nr/slot_worker.h index 355f10d26..0099927ce 100644 --- a/srsenb/hdr/phy/nr/slot_worker.h +++ b/srsenb/hdr/phy/nr/slot_worker.h @@ -50,15 +50,15 @@ public: }; struct args_t { - uint32_t cell_index = 0; - uint32_t nof_max_prb = SRSRAN_MAX_PRB_NR; - uint32_t nof_tx_ports = 1; - uint32_t nof_rx_ports = 1; - uint32_t rf_port = 0; - srsran_subcarrier_spacing_t scs = srsran_subcarrier_spacing_15kHz; - uint32_t pusch_max_nof_iter = 10; - float pusch_min_snr_dB = -10.0f; - double srate_hz = 0.0; + uint32_t cell_index = 0; + uint32_t nof_max_prb = SRSRAN_MAX_PRB_NR; + uint32_t nof_tx_ports = 1; + uint32_t nof_rx_ports = 1; + uint32_t rf_port = 0; + srsran_subcarrier_spacing_t scs = srsran_subcarrier_spacing_15kHz; + uint32_t pusch_max_its = 10; + float pusch_min_snr_dB = -10.0f; + double srate_hz = 0.0; }; slot_worker(srsran::phy_common_interface& common_, diff --git a/srsenb/hdr/phy/nr/worker_pool.h b/srsenb/hdr/phy/nr/worker_pool.h index f61afbfda..fe543f3a7 100644 --- a/srsenb/hdr/phy/nr/worker_pool.h +++ b/srsenb/hdr/phy/nr/worker_pool.h @@ -98,13 +98,13 @@ private: public: struct args_t { - double srate_hz = 0.0; - uint32_t nof_phy_threads = 3; - uint32_t nof_prach_workers = 0; - uint32_t prio = 52; - uint32_t pusch_max_nof_iter = 10; - float pusch_min_snr_dB = -10; - srsran::phy_log_args_t log = {}; + double srate_hz = 0.0; + uint32_t nof_phy_threads = 3; + uint32_t nof_prach_workers = 0; + uint32_t prio = 52; + uint32_t pusch_max_its = 10; + float pusch_min_snr_dB = -10; + srsran::phy_log_args_t log = {}; }; slot_worker* operator[](std::size_t pos) { return workers.at(pos).get(); } diff --git a/srsenb/hdr/phy/phy_interfaces.h b/srsenb/hdr/phy/phy_interfaces.h index 65e3baaf4..db4cc89e8 100644 --- a/srsenb/hdr/phy/phy_interfaces.h +++ b/srsenb/hdr/phy/phy_interfaces.h @@ -54,7 +54,8 @@ struct phy_args_t { srsran::phy_log_args_t log; float max_prach_offset_us = 10; - int pusch_max_its = 10; + uint32_t pusch_max_its = 10; + uint32_t nr_pusch_max_its = 10; bool pusch_8bit_decoder = false; float tx_amplitude = 1.0f; uint32_t nof_phy_threads = 1; diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index b0670f7af..ab7f1485a 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -211,41 +211,41 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("channel.ul.hst.init_time_s", bpo::value(&args->phy.ul_channel_args.hst_init_time_s)->default_value(0), "Initial time in seconds") /* Expert section */ - ("expert.metrics_period_secs", bpo::value(&args->general.metrics_period_secs)->default_value(1.0), "Periodicity for metrics in seconds") - ("expert.metrics_csv_enable", bpo::value(&args->general.metrics_csv_enable)->default_value(false), "Write metrics to CSV file") - ("expert.metrics_csv_filename", bpo::value(&args->general.metrics_csv_filename)->default_value("/tmp/enb_metrics.csv"), "Metrics CSV filename") - ("expert.pusch_max_its", bpo::value(&args->phy.pusch_max_its)->default_value(8), "Maximum number of turbo decoder iterations") - ("expert.pusch_8bit_decoder", bpo::value(&args->phy.pusch_8bit_decoder)->default_value(false), "Use 8-bit for LLR representation and turbo decoder trellis computation (Experimental)") - ("expert.pusch_meas_evm", bpo::value(&args->phy.pusch_meas_evm)->default_value(false), "Enable/Disable PUSCH EVM measure") - ("expert.tx_amplitude", bpo::value(&args->phy.tx_amplitude)->default_value(0.6), "Transmit amplitude factor") - ("expert.nof_phy_threads", bpo::value(&args->phy.nof_phy_threads)->default_value(3), "Number of PHY threads") - ("expert.nof_prach_threads", bpo::value(&args->phy.nof_prach_threads)->default_value(1), "Number of PRACH workers per carrier. Only 1 or 0 is supported") - ("expert.max_prach_offset_us", bpo::value(&args->phy.max_prach_offset_us)->default_value(30), "Maximum allowed RACH offset (in us)") - ("expert.equalizer_mode", bpo::value(&args->phy.equalizer_mode)->default_value("mmse"), "Equalizer mode") + ("expert.metrics_period_secs", bpo::value(&args->general.metrics_period_secs)->default_value(1.0), "Periodicity for metrics in seconds.") + ("expert.metrics_csv_enable", bpo::value(&args->general.metrics_csv_enable)->default_value(false), "Write metrics to CSV file.") + ("expert.metrics_csv_filename", bpo::value(&args->general.metrics_csv_filename)->default_value("/tmp/enb_metrics.csv"), "Metrics CSV filename.") + ("expert.pusch_max_its", bpo::value(&args->phy.pusch_max_its)->default_value(8), "Maximum number of turbo decoder iterations for LTE.") + ("expert.pusch_8bit_decoder", bpo::value(&args->phy.pusch_8bit_decoder)->default_value(false), "Use 8-bit for LLR representation and turbo decoder trellis computation (Experimental).") + ("expert.pusch_meas_evm", bpo::value(&args->phy.pusch_meas_evm)->default_value(false), "Enable/Disable PUSCH EVM measure.") + ("expert.tx_amplitude", bpo::value(&args->phy.tx_amplitude)->default_value(0.6), "Transmit amplitude factor.") + ("expert.nof_phy_threads", bpo::value(&args->phy.nof_phy_threads)->default_value(3), "Number of PHY threads.") + ("expert.nof_prach_threads", bpo::value(&args->phy.nof_prach_threads)->default_value(1), "Number of PRACH workers per carrier. Only 1 or 0 is supported.") + ("expert.max_prach_offset_us", bpo::value(&args->phy.max_prach_offset_us)->default_value(30), "Maximum allowed RACH offset (in us).") + ("expert.equalizer_mode", bpo::value(&args->phy.equalizer_mode)->default_value("mmse"), "Equalizer mode.") ("expert.estimator_fil_w", bpo::value(&args->phy.estimator_fil_w)->default_value(0.1), "Chooses the coefficients for the 3-tap channel estimator centered filter.") ("expert.lte_sample_rates", bpo::value(&use_standard_lte_rates)->default_value(false), "Whether to use default LTE sample rates instead of shorter variants.") - ("expert.report_json_enable", bpo::value(&args->general.report_json_enable)->default_value(false), "Write eNB report to JSON file (default disabled)") - ("expert.report_json_filename", bpo::value(&args->general.report_json_filename)->default_value("/tmp/enb_report.json"), "Report JSON filename (default /tmp/enb_report.json)") - ("expert.report_json_asn1_oct", bpo::value(&args->general.report_json_asn1_oct)->default_value(false), "Prints ASN1 messages encoded as an octet string instead of plain text in the JSON report file") - ("expert.alarms_log_enable", bpo::value(&args->general.alarms_log_enable)->default_value(false), "Enable Alarms logging (default diabled)") - ("expert.alarms_filename", bpo::value(&args->general.alarms_filename)->default_value("/tmp/enb_alarms.log"), "Alarms logging filename (default /tmp/alarms.log)") - ("expert.tracing_enable", bpo::value(&args->general.tracing_enable)->default_value(false), "Events tracing") - ("expert.tracing_filename", bpo::value(&args->general.tracing_filename)->default_value("/tmp/enb_tracing.log"), "Tracing events filename") - ("expert.tracing_buffcapacity", bpo::value(&args->general.tracing_buffcapacity)->default_value(1000000), "Tracing buffer capcity") - ("expert.stdout_ts_enable", bpo::value(&stdout_ts_enable)->default_value(false), "Prints once per second the timestamp into stdout") + ("expert.report_json_enable", bpo::value(&args->general.report_json_enable)->default_value(false), "Write eNB report to JSON file (default disabled).") + ("expert.report_json_filename", bpo::value(&args->general.report_json_filename)->default_value("/tmp/enb_report.json"), "Report JSON filename (default /tmp/enb_report.json).") + ("expert.report_json_asn1_oct", bpo::value(&args->general.report_json_asn1_oct)->default_value(false), "Prints ASN1 messages encoded as an octet string instead of plain text in the JSON report file.") + ("expert.alarms_log_enable", bpo::value(&args->general.alarms_log_enable)->default_value(false), "Enable Alarms logging (default diabled).") + ("expert.alarms_filename", bpo::value(&args->general.alarms_filename)->default_value("/tmp/enb_alarms.log"), "Alarms logging filename (default /tmp/alarms.log).") + ("expert.tracing_enable", bpo::value(&args->general.tracing_enable)->default_value(false), "Events tracing.") + ("expert.tracing_filename", bpo::value(&args->general.tracing_filename)->default_value("/tmp/enb_tracing.log"), "Tracing events filename.") + ("expert.tracing_buffcapacity", bpo::value(&args->general.tracing_buffcapacity)->default_value(1000000), "Tracing buffer capcity.") + ("expert.stdout_ts_enable", bpo::value(&stdout_ts_enable)->default_value(false), "Prints once per second the timestamp into stdout.") ("expert.rrc_inactivity_timer", bpo::value(&args->general.rrc_inactivity_timer)->default_value(30000), "Inactivity timer in ms.") - ("expert.print_buffer_state", bpo::value(&args->general.print_buffer_state)->default_value(false), "Prints on the console the buffer state every 10 seconds") + ("expert.print_buffer_state", bpo::value(&args->general.print_buffer_state)->default_value(false), "Prints on the console the buffer state every 10 seconds.") ("expert.eea_pref_list", bpo::value(&args->general.eea_pref_list)->default_value("EEA0, EEA2, EEA1"), "Ordered preference list for the selection of encryption algorithm (EEA) (default: EEA0, EEA2, EEA1).") ("expert.eia_pref_list", bpo::value(&args->general.eia_pref_list)->default_value("EIA2, EIA1, EIA0"), "Ordered preference list for the selection of integrity algorithm (EIA) (default: EIA2, EIA1, EIA0).") - ("expert.nof_prealloc_ues", bpo::value(&args->stack.mac.nof_prealloc_ues)->default_value(8), "Number of UE resources to preallocate during eNB initialization") + ("expert.nof_prealloc_ues", bpo::value(&args->stack.mac.nof_prealloc_ues)->default_value(8), "Number of UE resources to preallocate during eNB initialization.") ("expert.lcid_padding", bpo::value(&args->stack.mac.lcid_padding)->default_value(3), "LCID on which to put MAC padding") - ("expert.max_mac_dl_kos", bpo::value(&args->general.max_mac_dl_kos)->default_value(100), "Maximum number of consecutive KOs in DL before triggering the UE's release (default 100)") - ("expert.max_mac_ul_kos", bpo::value(&args->general.max_mac_ul_kos)->default_value(100), "Maximum number of consecutive KOs in UL before triggering the UE's release (default 100)") - ("expert.gtpu_tunnel_timeout", bpo::value(&args->stack.gtpu_indirect_tunnel_timeout_msec)->default_value(0), "Maximum time that GTPU takes to release indirect forwarding tunnel since the last received GTPU PDU. (0 for infinity)") - ("expert.rlf_release_timer_ms", bpo::value(&args->general.rlf_release_timer_ms)->default_value(4000), "Time taken by eNB to release UE context after it detects an RLF") + ("expert.max_mac_dl_kos", bpo::value(&args->general.max_mac_dl_kos)->default_value(100), "Maximum number of consecutive KOs in DL before triggering the UE's release (default 100).") + ("expert.max_mac_ul_kos", bpo::value(&args->general.max_mac_ul_kos)->default_value(100), "Maximum number of consecutive KOs in UL before triggering the UE's release (default 100).") + ("expert.gtpu_tunnel_timeout", bpo::value(&args->stack.gtpu_indirect_tunnel_timeout_msec)->default_value(0), "Maximum time that GTPU takes to release indirect forwarding tunnel since the last received GTPU PDU (0 for infinity).") + ("expert.rlf_release_timer_ms", bpo::value(&args->general.rlf_release_timer_ms)->default_value(4000), "Time taken by eNB to release UE context after it detects an RLF.") ("expert.extended_cp", bpo::value(&args->phy.extended_cp)->default_value(false), "Use extended cyclic prefix") - ("expert.ts1_reloc_prep_timeout", bpo::value(&args->stack.s1ap.ts1_reloc_prep_timeout)->default_value(10000), "S1AP TS 36.413 TS1RelocPrep Expiry Timeout value in milliseconds") - ("expert.ts1_reloc_overall_timeout", bpo::value(&args->stack.s1ap.ts1_reloc_overall_timeout)->default_value(10000), "S1AP TS 36.413 TS1RelocOverall Expiry Timeout value in milliseconds") + ("expert.ts1_reloc_prep_timeout", bpo::value(&args->stack.s1ap.ts1_reloc_prep_timeout)->default_value(10000), "S1AP TS 36.413 TS1RelocPrep Expiry Timeout value in milliseconds.") + ("expert.ts1_reloc_overall_timeout", bpo::value(&args->stack.s1ap.ts1_reloc_overall_timeout)->default_value(10000), "S1AP TS 36.413 TS1RelocOverall Expiry Timeout value in milliseconds.") ("expert.rlf_min_ul_snr_estim", bpo::value(&args->stack.mac.rlf_min_ul_snr_estim)->default_value(-2), "SNR threshold in dB below which the eNB is notified with rlf ko.") // eMBMS section @@ -255,15 +255,16 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("embms.mcs", bpo::value(&args->stack.embms.mcs)->default_value(20), "Modulation and Coding scheme of MBMS traffic.") // NR section - ("scheduler.nr_pdsch_mcs", bpo::value(&args->nr_stack.mac.sched_cfg.fixed_dl_mcs)->default_value(28), "Fixed NR DL MCS (-1 for dynamic)") - ("scheduler.nr_pusch_mcs", bpo::value(&args->nr_stack.mac.sched_cfg.fixed_ul_mcs)->default_value(28), "Fixed NR UL MCS (-1 for dynamic)") + ("scheduler.nr_pdsch_mcs", bpo::value(&args->nr_stack.mac.sched_cfg.fixed_dl_mcs)->default_value(28), "Fixed NR DL MCS (-1 for dynamic).") + ("scheduler.nr_pusch_mcs", bpo::value(&args->nr_stack.mac.sched_cfg.fixed_ul_mcs)->default_value(28), "Fixed NR UL MCS (-1 for dynamic).") + ("expert.nr_pusch_max_its", bpo::value(&args->phy.nr_pusch_max_its)->default_value(10), "Maximum number of LDPC iterations for NR.") // VNF params - ("vnf.type", bpo::value(&args->phy.vnf_args.type)->default_value("gnb"), "VNF instance type [gnb,ue]") - ("vnf.addr", bpo::value(&args->phy.vnf_args.bind_addr)->default_value("localhost"), "Address to bind VNF interface") - ("vnf.port", bpo::value(&args->phy.vnf_args.bind_port)->default_value(3333), "Bind port") - ("log.vnf_level", bpo::value(&args->phy.vnf_args.log_level), "VNF log level") - ("log.vnf_hex_limit", bpo::value(&args->phy.vnf_args.log_hex_limit), "VNF log hex dump limit") + ("vnf.type", bpo::value(&args->phy.vnf_args.type)->default_value("gnb"), "VNF instance type [gnb,ue].") + ("vnf.addr", bpo::value(&args->phy.vnf_args.bind_addr)->default_value("localhost"), "Address to bind VNF interface.") + ("vnf.port", bpo::value(&args->phy.vnf_args.bind_port)->default_value(3333), "Bind port.") + ("log.vnf_level", bpo::value(&args->phy.vnf_args.log_level), "VNF log level.") + ("log.vnf_hex_limit", bpo::value(&args->phy.vnf_args.log_hex_limit), "VNF log hex dump limit.") ; // Positional options - config file location diff --git a/srsenb/src/phy/nr/worker_pool.cc b/srsenb/src/phy/nr/worker_pool.cc index e60caca40..0e9bf6172 100644 --- a/srsenb/src/phy/nr/worker_pool.cc +++ b/srsenb/src/phy/nr/worker_pool.cc @@ -62,7 +62,7 @@ bool worker_pool::init(const args_t& args, const phy_cell_cfg_list_nr_t& cell_li w_args.nof_rx_ports = cell_list[cell_index].carrier.max_mimo_layers; w_args.rf_port = cell_list[cell_index].rf_port; w_args.srate_hz = srate_hz; - w_args.pusch_max_nof_iter = args.pusch_max_nof_iter; + w_args.pusch_max_its = args.pusch_max_its; w_args.pusch_min_snr_dB = args.pusch_min_snr_dB; if (not w->init(w_args)) { diff --git a/srsenb/src/phy/phy.cc b/srsenb/src/phy/phy.cc index 47d59199c..d3d5ec8be 100644 --- a/srsenb/src/phy/phy.cc +++ b/srsenb/src/phy/phy.cc @@ -348,6 +348,7 @@ int phy::init_nr(const phy_args_t& args, const phy_cfg_t& cfg, stack_interface_p worker_args.nof_phy_threads = args.nof_phy_threads; worker_args.log.phy_level = args.log.phy_level; worker_args.log.phy_hex_limit = args.log.phy_hex_limit; + worker_args.pusch_max_its = args.nr_pusch_max_its; if (not nr_workers->init(worker_args, cfg.phy_cell_cfg_nr)) { return SRSRAN_ERROR; diff --git a/test/phy/nr_phy_test.cc b/test/phy/nr_phy_test.cc index 5dde6052c..c6eb3ff30 100644 --- a/test/phy/nr_phy_test.cc +++ b/test/phy/nr_phy_test.cc @@ -80,7 +80,7 @@ test_bench::args_t::args_t(int argc, char** argv) ("gnb.phy.log.level", bpo::value(&gnb_phy.log.phy_level)->default_value("warning"), "gNb PHY log level") ("gnb.phy.log.hex_limit", bpo::value(&gnb_phy.log.phy_hex_limit)->default_value(0), "gNb PHY log hex limit") ("gnb.phy.log.id_preamble", bpo::value(&gnb_phy.log.id_preamble)->default_value("GNB/"), "gNb PHY log ID preamble") - ("gnb.phy.pusch.max_iter", bpo::value(&gnb_phy.pusch_max_nof_iter)->default_value(10), "PUSCH LDPC max number of iterations") + ("gnb.phy.pusch.max_iter", bpo::value(&gnb_phy.pusch_max_its)->default_value(10), "PUSCH LDPC max number of iterations") ; options_ue_phy.add_options() From 8e5fe9018ba4ed6248bb5cb16708a237c7479674 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 19 Oct 2021 15:28:48 +0200 Subject: [PATCH 199/208] Corrected LBRM functionality --- lib/include/srsran/phy/phch/sch_cfg_nr.h | 7 ++++-- lib/src/phy/phch/sch_nr.c | 14 +++++++----- lib/test/phy/phy_dl_nr_test.c | 28 +++++++++++++----------- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/lib/include/srsran/phy/phch/sch_cfg_nr.h b/lib/include/srsran/phy/phch/sch_cfg_nr.h index 31c3f5af6..24abdc7cd 100644 --- a/lib/include/srsran/phy/phch/sch_cfg_nr.h +++ b/lib/include/srsran/phy/phch/sch_cfg_nr.h @@ -19,8 +19,11 @@ typedef struct SRSRAN_API { srsran_mcs_table_t mcs_table; ///< @brief Indicates the MCS table the UE shall use for PDSCH and/or PUSCH without ///< transform precoding - srsran_xoverhead_t xoverhead; ///< Accounts for overhead from CSI-RS, CORESET, etc. If the field is absent, the UE - ///< applies value xOh0 (see TS 38.214 [19], clause 5.1.3.2). + srsran_xoverhead_t xoverhead; ///< @brief Accounts for overhead from CSI-RS, CORESET, etc. If the field is absent, the + ///< UE applies value xOh0 (see TS 38.214 [19], clause 5.1.3.2). + + bool limited_buffer_rm; ///< @brief Enables LBRM (Limited buffer rate-matching). Given by rateMatching parameter in + ///< PUSCH-ServingCellConfig or PDSCH-ServingCellConfig ASN1 sequences } srsran_sch_cfg_t; typedef struct SRSRAN_API { diff --git a/lib/src/phy/phch/sch_nr.c b/lib/src/phy/phch/sch_nr.c index 5c899b4bf..003b381cd 100644 --- a/lib/src/phy/phch/sch_nr.c +++ b/lib/src/phy/phch/sch_nr.c @@ -87,7 +87,7 @@ static int sch_nr_Nref(uint32_t N_rb, srsran_mcs_table_t mcs_table, uint32_t max uint32_t N_re_lbrm = SRSRAN_MAX_NRE_NR * sch_nr_n_prb_lbrm(N_rb); double TCR_lbrm = 948.0 / 1024.0; uint32_t Qm_lbrm = (mcs_table == srsran_mcs_table_256qam) ? 8 : 6; - uint32_t TBS_LRBM = srsran_ra_nr_tbs(N_re_lbrm, 1.0, TCR_lbrm, Qm_lbrm, max_mimo_layers); + uint32_t TBS_LRBM = srsran_ra_nr_tbs(N_re_lbrm, 1.0, TCR_lbrm, Qm_lbrm, SRSRAN_MIN(4, max_mimo_layers)); double R = 2.0 / 3.0; srsran_basegraph_t bg = srsran_sch_nr_select_basegraph(TBS_LRBM, R); @@ -141,11 +141,15 @@ int srsran_sch_nr_fill_tb_info(const srsran_carrier_nr_t* carrier, cfg->Nl = tb->N_L; // Calculate Nref - int Nref = sch_nr_Nref(carrier->nof_prb, sch_cfg->mcs_table, carrier->max_mimo_layers); - if (Nref < SRSRAN_SUCCESS) { - ERROR("Error computing N_ref"); + if (sch_cfg->limited_buffer_rm) { + int Nref = sch_nr_Nref(carrier->nof_prb, sch_cfg->mcs_table, 4); + if (Nref < SRSRAN_SUCCESS) { + ERROR("Error computing N_ref"); + } + cfg->Nref = (uint32_t)Nref; + } else { + cfg->Nref = SRSRAN_LDPC_MAX_LEN_ENCODED_CB; } - cfg->Nref = (uint32_t)Nref; // Calculate number of code blocks after applying CBGTI... not implemented, activate all CB for (uint32_t r = 0; r < cbsegm.C; r++) { diff --git a/lib/test/phy/phy_dl_nr_test.c b/lib/test/phy/phy_dl_nr_test.c index 40fff8944..f478117d0 100644 --- a/lib/test/phy/phy_dl_nr_test.c +++ b/lib/test/phy/phy_dl_nr_test.c @@ -19,17 +19,18 @@ #include "srsran/phy/utils/vector.h" #include -static srsran_carrier_nr_t carrier = SRSRAN_DEFAULT_CARRIER_NR; -static uint32_t n_prb = 0; // Set to 0 for steering -static uint32_t mcs = 30; // Set to 30 for steering -static srsran_sch_cfg_nr_t pdsch_cfg = {}; -static uint32_t nof_slots = 10; -static uint32_t rv_idx = 0; -static uint32_t delay_n = 0; // Integer delay -static float cfo_hz = 0.0f; // CFO Hz -static srsran_dmrs_sch_type_t dmrs_type = srsran_dmrs_sch_type_1; -static srsran_dmrs_sch_add_pos_t dmrs_add_pos = srsran_dmrs_sch_add_pos_2; -static bool interleaved_pdcch = false; +static srsran_carrier_nr_t carrier = SRSRAN_DEFAULT_CARRIER_NR; +static uint32_t n_prb = 0; // Set to 0 for steering +static uint32_t mcs = 30; // Set to 30 for steering +static srsran_sch_cfg_nr_t pdsch_cfg = {}; +static uint32_t nof_slots = 10; +static uint32_t rv_idx = 0; +static uint32_t delay_n = 0; // Integer delay +static float cfo_hz = 0.0f; // CFO Hz +static srsran_dmrs_sch_type_t dmrs_type = srsran_dmrs_sch_type_1; +static srsran_dmrs_sch_add_pos_t dmrs_add_pos = srsran_dmrs_sch_add_pos_2; +static bool interleaved_pdcch = false; +static uint32_t nof_dmrs_cdm_groups_without_data = 1; static void usage(char* prog) { @@ -79,7 +80,7 @@ static int parse_args(int argc, char** argv) dmrs_type = srsran_dmrs_sch_type_2; break; } - switch (strtol(argv[optind], NULL, 10)) { + switch (strtol(argv[optind++], NULL, 10)) { case 0: dmrs_add_pos = srsran_dmrs_sch_add_pos_0; break; @@ -93,6 +94,7 @@ static int parse_args(int argc, char** argv) dmrs_add_pos = srsran_dmrs_sch_add_pos_3; break; } + nof_dmrs_cdm_groups_without_data = (uint32_t)strtol(argv[optind], NULL, 10); break; case 'T': pdsch_cfg.sch_cfg.mcs_table = srsran_mcs_table_from_str(argv[optind]); @@ -357,7 +359,7 @@ int main(int argc, char** argv) pdsch_cfg.grant.L = 13; pdsch_cfg.grant.nof_layers = carrier.max_mimo_layers; pdsch_cfg.grant.dci_format = srsran_dci_format_nr_1_0; - pdsch_cfg.grant.nof_dmrs_cdm_groups_without_data = 1; + pdsch_cfg.grant.nof_dmrs_cdm_groups_without_data = nof_dmrs_cdm_groups_without_data; pdsch_cfg.grant.beta_dmrs = srsran_convert_dB_to_amplitude(3); pdsch_cfg.grant.rnti_type = srsran_rnti_type_c; pdsch_cfg.grant.rnti = 0x4601; From 4edb61212f0a6daab7c2b019536a3b4c5055ab22 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 19 Oct 2021 16:29:29 +0200 Subject: [PATCH 200/208] Added number of CDM groups to phy_dl_nr_test --- lib/test/phy/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test/phy/CMakeLists.txt b/lib/test/phy/CMakeLists.txt index a2b79455c..9ad4a7953 100644 --- a/lib/test/phy/CMakeLists.txt +++ b/lib/test/phy/CMakeLists.txt @@ -70,7 +70,7 @@ foreach(rb 25 52 79 106 133 160 216 270) add_nr_test(phy_dl_nr_test_${rb}prb_interleaved phy_dl_nr_test -P ${rb} -p 25 -m 10 -I) # Maximum throughput with 256QAM - add_nr_test(phy_dl_nr_test_${rb}prb_256qam phy_dl_nr_test -P ${rb} -p ${rb} -m 27 -T 256qam -v -d 1 1 -n 10) + add_nr_test(phy_dl_nr_test_${rb}prb_256qam phy_dl_nr_test -P ${rb} -p ${rb} -m 27 -T 256qam -v -d 1 1 1 -n 10) # Maximum throughput with 64QAM and CFO+Delay impairments add_nr_test(phy_dl_nr_test_${rb}prb_cfo_delay phy_dl_nr_test -P ${rb} -p ${rb} -m 27 -C 100.0 -D 4 -n 10) From 0bd8f640db6500350cdc402d54b5cd81859e35a6 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 19 Oct 2021 15:43:51 +0100 Subject: [PATCH 201/208] lte,enb,sched: Fix hanging handover due to lack of Msg4. --- srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc index 016436a0b..312457b25 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc @@ -351,6 +351,9 @@ void harq_entity::reset() for (auto& h : ul_harqs) { for (uint32_t tb = 0; tb < SRSRAN_MAX_TB; tb++) { h.reset(tb); + // The reset_pending_data() is called after reset(), when generating PHICH. However, in the case of full HARQ + // reset (e.g. during handover) no PHICH is going to be generated. + h.reset_pending_data(); } } } From 6d432646b99e5ca16733b3e8c27f861a918ea45e Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 19 Oct 2021 19:10:23 +0100 Subject: [PATCH 202/208] lte,enb,sched: UL HARQs should return 0 pending bytes if empty --- srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc index 312457b25..1156a1e80 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc @@ -324,7 +324,7 @@ void ul_harq_proc::reset_pending_data() uint32_t ul_harq_proc::get_pending_data() const { - return (uint32_t)pending_data; + return is_empty() ? 0 : (uint32_t)pending_data; } /******************** From ebaa71d190b19b45485a724245696cb96efdc5c2 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Fri, 15 Oct 2021 15:59:00 +0200 Subject: [PATCH 203/208] ue,stdout: fix the SNR formatting in UE console (NR) When the SNR value is INF, the conversion to (int) causes -2147483648 to be displayed in the UE console. This commit fixes the formatting, so that the values INF or NaN would be displayed as N/A NOTE: The issue of getting an INF value for the reported SNR metric still needs to be addressed separately. --- srsue/src/metrics_stdout.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/srsue/src/metrics_stdout.cc b/srsue/src/metrics_stdout.cc index ae66b3f9f..3f7533df9 100644 --- a/srsue/src/metrics_stdout.cc +++ b/srsue/src/metrics_stdout.cc @@ -135,7 +135,11 @@ void metrics_stdout::set_metrics_helper(const phy_metrics_t& phy, fmt::print(" |"); fmt::print(" {:>2}", int(phy.dl[r].mcs)); - fmt::print(" {:>3}", int(phy.ch[r].sinr)); + if (std::isnan(phy.ch[r].sinr) || std::isinf(phy.ch[r].sinr)) { + fmt::print(" {:>3}", "n/a"); + } else { + fmt::print(" {:>3}", int(phy.ch[r].sinr)); + } fmt::print(" {:>4.1f}", phy.dl[r].fec_iters); fmt::print(" {:>6.6}", float_to_eng_string((float)mac[r].rx_brate / (mac[r].nof_tti * 1e-3), 2)); From 4e3564a8a2a12ac40ead8c6cbb5b49f0666876f5 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Mon, 18 Oct 2021 18:58:15 +0200 Subject: [PATCH 204/208] mac,stdout: add PUSCH and PUCCH SINR to stdout This commit implements the PUCCH and PUSCH metrics in the MAC, to be displayed in the eNB console. Signed-off-by: Carlo Galiotto --- srsenb/hdr/stack/mac/nr/ue_nr.h | 6 ++++++ srsenb/src/metrics_stdout.cc | 6 ++++++ srsenb/src/stack/mac/nr/mac_nr.cc | 17 ++++++++++++++--- srsenb/src/stack/mac/nr/ue_nr.cc | 23 +++++++++++++++++++++++ srsue/hdr/phy/phy_metrics.h | 5 ++++- 5 files changed, 53 insertions(+), 4 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/ue_nr.h b/srsenb/hdr/stack/mac/nr/ue_nr.h index 59ef98a15..4fc6259a8 100644 --- a/srsenb/hdr/stack/mac/nr/ue_nr.h +++ b/srsenb/hdr/stack/mac/nr/ue_nr.h @@ -62,6 +62,8 @@ public: void metrics_dl_cqi(const srsran_uci_cfg_nr_t& cfg_, uint32_t dl_cqi); void metrics_dl_mcs(uint32_t mcs); void metrics_ul_mcs(uint32_t mcs); + void metrics_pucch_sinr(float sinr); + void metrics_pusch_sinr(float sinr); void metrics_cnt(); uint32_t read_pdu(uint32_t lcid, uint8_t* payload, uint32_t requested_bytes) final; @@ -83,10 +85,14 @@ private: std::atomic active_state{true}; + // TO DO: some counters are kept as members of class ue_nr, while some others (i.e., mcs) are kept in the ue_metrics + // We should make these counters more uniform uint32_t phr_counter = 0; uint32_t dl_cqi_valid_counter = 0; uint32_t dl_ri_counter = 0; uint32_t dl_pmi_counter = 0; + uint32_t pucch_sinr_counter = 0; + uint32_t pusch_sinr_counter = 0; mac_ue_metrics_t ue_metrics = {}; // UE-specific buffer for MAC PDU packing, unpacking and handling diff --git a/srsenb/src/metrics_stdout.cc b/srsenb/src/metrics_stdout.cc index 0fe35cc1e..06d6e63c1 100644 --- a/srsenb/src/metrics_stdout.cc +++ b/srsenb/src/metrics_stdout.cc @@ -145,6 +145,12 @@ void metrics_stdout::set_metrics_helper(uint32_t num_ue } else { fmt::print(" {:>2}", 0); } + float ul_mcs = (is_nr) ? mac.ues[i].ul_mcs : phy[i].ul.mcs; + if (not isnan(ul_mcs)) { + fmt::print(" {:>2}", int(ul_mcs)); + } else { + fmt::print(" {:>2}", 0); + } if (mac.ues[i].rx_brate > 0) { fmt::print(" {:>6.6}", float_to_eng_string((float)mac.ues[i].rx_brate / (mac.ues[i].nof_tti * 1e-3), 1)); } else { diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index bd418cf53..5a49f1649 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -81,6 +81,8 @@ void mac_nr::stop() /// However, get_metrics is called infrequently enough to cause major halts in the L1/L2 void mac_nr::get_metrics(srsenb::mac_metrics_t& metrics) { + // TO DO: We should comment on the logic we follow to get the metrics. Some of them are retrieved from MAC, some + // others from the scheduler. get_metrics_nolock(metrics); sched.get_metrics(metrics); } @@ -165,9 +167,9 @@ void mac_nr::rach_detected(const rach_info_t& rach_info) 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 = cell_config[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; + ref_args.duplex = cell_config[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 @@ -357,6 +359,14 @@ int mac_nr::pucch_info(const srsran_slot_cfg_t& slot_cfg, const mac_interface_ph logger.error("Error handling UCI data from PUCCH reception"); return SRSRAN_ERROR; } + + // process PUCCH SNR + uint16_t rnti = pucch_info.uci_data.cfg.pucch.rnti; + srsran::rwlock_read_guard rw_lock(rwmutex); + if (ue_db.contains(rnti)) { + ue_db[rnti]->metrics_pucch_sinr(pucch_info.csi.snr_dB); + } + return SRSRAN_SUCCESS; } @@ -419,6 +429,7 @@ int mac_nr::pusch_info(const srsran_slot_cfg_t& slot_cfg, mac_interface_phy_nr:: srsran::rwlock_read_guard rw_lock(rwmutex); if (ue_db.contains(rnti)) { ue_db[rnti]->metrics_rx(pusch_info.pusch_data.tb[0].crc, nof_bytes); + ue_db[rnti]->metrics_pusch_sinr(pusch_info.csi.snr_dB); } return SRSRAN_SUCCESS; } diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc index 0e7a3779b..261b49d00 100644 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ b/srsenb/src/stack/mac/nr/ue_nr.cc @@ -220,9 +220,12 @@ void ue_nr::metrics_read(mac_ue_metrics_t* metrics_) auto it = std::find(cc_list.begin(), cc_list.end(), 0); ue_metrics.cc_idx = std::distance(cc_list.begin(), it); + // printf("RNTI %u: reading and resetting metrics: \n", rnti); *metrics_ = ue_metrics; phr_counter = 0; dl_cqi_valid_counter = 0; + pucch_sinr_counter = 0; + pusch_sinr_counter = 0; ue_metrics = {}; } @@ -286,6 +289,26 @@ void ue_nr::metrics_cnt() ue_metrics.nof_tti++; } +void ue_nr::metrics_pucch_sinr(float sinr) +{ + std::lock_guard lock(metrics_mutex); + // discard nan or inf values for average SINR + if (!std::isinf(sinr) && !std::isnan(sinr)) { + ue_metrics.pucch_sinr = SRSRAN_VEC_SAFE_CMA((float)sinr, ue_metrics.pucch_sinr, pucch_sinr_counter); + pucch_sinr_counter++; + } +} + +void ue_nr::metrics_pusch_sinr(float sinr) +{ + std::lock_guard lock(metrics_mutex); + // discard nan or inf values for average SINR + if (!std::isinf(sinr) && !std::isnan(sinr)) { + ue_metrics.pusch_sinr = SRSRAN_VEC_SAFE_CMA((float)sinr, ue_metrics.pusch_sinr, pusch_sinr_counter); + pusch_sinr_counter++; + } +} + /** Converts the buffer size field of a BSR (5 or 8-bit Buffer Size field) into Bytes * @param buff_size_field The buffer size field contained in the MAC PDU * @param format The BSR format that determines the buffer size field length diff --git a/srsue/hdr/phy/phy_metrics.h b/srsue/hdr/phy/phy_metrics.h index 11233ceb9..7398117bf 100644 --- a/srsue/hdr/phy/phy_metrics.h +++ b/srsue/hdr/phy/phy_metrics.h @@ -79,7 +79,10 @@ struct ch_metrics_t { { count++; PHY_METRICS_SET(n); - PHY_METRICS_SET(sinr); + // We exclude inf and nan from the average SINR + if (!std::isnan(other.sinr) || !std::isinf(other.sinr)) { + PHY_METRICS_SET(sinr); + } PHY_METRICS_SET(rsrp); PHY_METRICS_SET(rsrq); PHY_METRICS_SET(rssi); From a4932564d78ab73f099780e1d5ba9bb9e4dfc422 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Tue, 19 Oct 2021 13:33:07 +0200 Subject: [PATCH 205/208] stdout: remove extra value from eNB stats + ... address PR review - change "TO DO" into "TODO" - remove forgotten "printf" for debug Signed-off-by: Carlo Galiotto --- srsenb/hdr/stack/mac/nr/ue_nr.h | 2 +- srsenb/src/metrics_stdout.cc | 3 +-- srsenb/src/stack/mac/nr/mac_nr.cc | 2 +- srsenb/src/stack/mac/nr/ue_nr.cc | 1 - 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/ue_nr.h b/srsenb/hdr/stack/mac/nr/ue_nr.h index 4fc6259a8..4d63c5cf8 100644 --- a/srsenb/hdr/stack/mac/nr/ue_nr.h +++ b/srsenb/hdr/stack/mac/nr/ue_nr.h @@ -85,7 +85,7 @@ private: std::atomic active_state{true}; - // TO DO: some counters are kept as members of class ue_nr, while some others (i.e., mcs) are kept in the ue_metrics + // TODO: some counters are kept as members of class ue_nr, while some others (i.e., mcs) are kept in the ue_metrics // We should make these counters more uniform uint32_t phr_counter = 0; uint32_t dl_cqi_valid_counter = 0; diff --git a/srsenb/src/metrics_stdout.cc b/srsenb/src/metrics_stdout.cc index 06d6e63c1..2a1a213f2 100644 --- a/srsenb/src/metrics_stdout.cc +++ b/srsenb/src/metrics_stdout.cc @@ -139,9 +139,8 @@ void metrics_stdout::set_metrics_helper(uint32_t num_ue fmt::print(" {:>5.5}", "n/a"); } int phr = mac.ues[i].phr; - fmt::print(" {:>3}", int(phr)); if (not isnan(phr)) { - fmt::print(" {:>2}", int(phr)); + fmt::print(" {:>2}", phr); } else { fmt::print(" {:>2}", 0); } diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 5a49f1649..8949a3331 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -81,7 +81,7 @@ void mac_nr::stop() /// However, get_metrics is called infrequently enough to cause major halts in the L1/L2 void mac_nr::get_metrics(srsenb::mac_metrics_t& metrics) { - // TO DO: We should comment on the logic we follow to get the metrics. Some of them are retrieved from MAC, some + // TODO: We should comment on the logic we follow to get the metrics. Some of them are retrieved from MAC, some // others from the scheduler. get_metrics_nolock(metrics); sched.get_metrics(metrics); diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc index 261b49d00..904b5e97b 100644 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ b/srsenb/src/stack/mac/nr/ue_nr.cc @@ -220,7 +220,6 @@ void ue_nr::metrics_read(mac_ue_metrics_t* metrics_) auto it = std::find(cc_list.begin(), cc_list.end(), 0); ue_metrics.cc_idx = std::distance(cc_list.begin(), it); - // printf("RNTI %u: reading and resetting metrics: \n", rnti); *metrics_ = ue_metrics; phr_counter = 0; dl_cqi_valid_counter = 0; From b8171e493eebe6842b843fb017d73f7179f0c074 Mon Sep 17 00:00:00 2001 From: faluco Date: Wed, 20 Oct 2021 11:35:13 +0200 Subject: [PATCH 206/208] Fix crash in mac_nr when accesing the ue_db and not checking if the rnti is valid, while there fix a potential data race. Fix data race inside sched_nr when modifying per ue metrics. --- srsenb/hdr/stack/mac/nr/sched_nr_ue.h | 1 + srsenb/src/stack/mac/nr/mac_nr.cc | 7 +++++-- srsenb/src/stack/mac/nr/sched_nr.cc | 1 + srsenb/src/stack/mac/nr/sched_nr_worker.cc | 1 + 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h index 666eff1dd..21076a204 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h @@ -77,6 +77,7 @@ public: // metrics mac_ue_metrics_t metrics = {}; + std::mutex metrics_mutex; private: bwp_ue_cfg bwp_cfg; diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 8949a3331..00d710dae 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -389,8 +389,11 @@ bool mac_nr::handle_uci_data(const uint16_t rnti, const srsran_uci_cfg_nr_t& cfg } // Process CQI - if (value.valid) { - ue_db[rnti]->metrics_dl_cqi(cfg_, value.csi->wideband_cri_ri_pmi_cqi.cqi); + { + srsran::rwlock_read_guard rw_lock(rwmutex); + if (ue_db.contains(rnti) && value.valid) { + ue_db[rnti]->metrics_dl_cqi(cfg_, value.csi->wideband_cri_ri_pmi_cqi.cqi); + } } return true; diff --git a/srsenb/src/stack/mac/nr/sched_nr.cc b/srsenb/src/stack/mac/nr/sched_nr.cc index 89cbff2b0..89b1dcf02 100644 --- a/srsenb/src/stack/mac/nr/sched_nr.cc +++ b/srsenb/src/stack/mac/nr/sched_nr.cc @@ -172,6 +172,7 @@ void sched_nr::dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb sched_workers->enqueue_cc_feedback(rnti, cc, [this, pid, tb_idx, ack](ue_carrier& ue_cc) { int tbs = ue_cc.harq_ent.dl_ack_info(pid, tb_idx, ack); if (tbs >= 0) { + std::lock_guard lock(ue_cc.metrics_mutex); if (ack) { ue_cc.metrics.tx_brate += tbs; } else { diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc index 97be29928..871e31117 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_worker.cc @@ -375,6 +375,7 @@ void sched_worker_manager::get_metrics_nolocking(mac_metrics_t& metrics) for (mac_ue_metrics_t& ue_metric : metrics.ues) { if (ue_db.contains(ue_metric.rnti) and ue_db[ue_metric.rnti]->carriers[0] != nullptr) { auto& ue_cc = *ue_db[ue_metric.rnti]->carriers[0]; + std::lock_guard lock(ue_cc.metrics_mutex); ue_metric.tx_brate = ue_cc.metrics.tx_brate; ue_metric.tx_errors = ue_cc.metrics.tx_errors; ue_metric.tx_pkts = ue_cc.metrics.tx_pkts; From d7e8d6bf652b4a482256f4afaa7efd3b54dfa333 Mon Sep 17 00:00:00 2001 From: faluco Date: Wed, 20 Oct 2021 12:52:17 +0200 Subject: [PATCH 207/208] Fix data race in mux_nr::add_bsr_ce. --- srsue/hdr/stack/mac_nr/mux_nr.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/srsue/hdr/stack/mac_nr/mux_nr.h b/srsue/hdr/stack/mac_nr/mux_nr.h index c4bf9e4d4..5356cc08b 100644 --- a/srsue/hdr/stack/mac_nr/mux_nr.h +++ b/srsue/hdr/stack/mac_nr/mux_nr.h @@ -30,7 +30,7 @@ class mux_nr final : mux_base, public mux_interface_bsr_nr public: explicit mux_nr(mac_interface_mux_nr& mac_, srslog::basic_logger& logger); ~mux_nr(){}; - void reset(); + void reset(); int32_t init(rlc_interface_mac* rlc_); void msg3_flush(); @@ -53,9 +53,9 @@ private: // internal helper methods // ctor configured members - mac_interface_mux_nr& mac; - rlc_interface_mac* rlc = nullptr; - srslog::basic_logger& logger; + mac_interface_mux_nr& mac; + rlc_interface_mac* rlc = nullptr; + srslog::basic_logger& logger; // Msg3 related srsran::unique_byte_buffer_t msg3_buff = nullptr; @@ -69,7 +69,8 @@ private: srsran::mac_sch_pdu_nr tx_pdu; /// single MAC PDU for packing - enum { no_bsr, sbsr_ce, lbsr_ce } add_bsr_ce = no_bsr; /// BSR procedure requests MUX to add a BSR CE + enum bsr_req_t { no_bsr, sbsr_ce, lbsr_ce }; + std::atomic add_bsr_ce = {bsr_req_t::no_bsr}; /// BSR procedure requests MUX to add a BSR CE // Mutex for exclusive access std::mutex mutex; From b14e75218d27c5224db67ad9f03caef34b202fb3 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 19 Oct 2021 16:42:55 +0100 Subject: [PATCH 208/208] lte,enb,rrc: avoid creating scells for UEs whose release < 10 --- srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc | 8 ++++++-- srsenb/src/stack/rrc/rrc_ue.cc | 12 ++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc index 355059ee1..95b65d1cc 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc @@ -112,8 +112,12 @@ void sched_ue_cell::set_ue_cfg(const sched_interface::ue_cfg_t& ue_cfg_) case cc_st::active: if (ue_cc_idx < 0 or not ue_cfg->supported_cc_list[ue_cc_idx].active) { cc_state_ = cc_st::deactivating; - logger.info( - "SCHED: Deactivating SCell, rnti=0x%x, cc=%d, SCellIndex=%d...", rnti, cell_cfg->enb_cc_idx, ue_cc_idx); + if (ue_cc_idx > 0) { + logger.info( + "SCHED: Deactivating SCell, rnti=0x%x, cc=%d, SCellIndex=%d...", rnti, cell_cfg->enb_cc_idx, ue_cc_idx); + } else { + logger.info("SCHED: Deactivating previous PCell, rnti=0x%x, cc=%d...", rnti, cell_cfg->enb_cc_idx); + } } break; case cc_st::deactivating: diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 56c1a686d..c870588ce 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -1246,12 +1246,11 @@ void rrc::ue::update_scells() const ue_cell_ded* pcell = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX); const enb_cell_common* pcell_cfg = pcell->cell_common; - if (ue_cell_list.nof_cells() == pcell_cfg->scells.size() + 1) { - // SCells already added + // Check whether UE supports CA + if (eutra_capabilities.access_stratum_release.to_number() < 10) { + parent->logger.info("UE doesn't support CA. Skipping SCell activation"); return; } - - // Check whether UE supports CA if (not eutra_capabilities.non_crit_ext_present or not eutra_capabilities.non_crit_ext.non_crit_ext_present or not eutra_capabilities.non_crit_ext.non_crit_ext.non_crit_ext_present or not eutra_capabilities.non_crit_ext.non_crit_ext.non_crit_ext.rf_params_v1020_present or @@ -1261,6 +1260,11 @@ void rrc::ue::update_scells() return; } + if (ue_cell_list.nof_cells() == pcell_cfg->scells.size() + 1) { + // SCells already added + return; + } + for (const enb_cell_common* scell : pcell_cfg->scells) { ue_cell_list.add_cell(scell->enb_cc_idx); }