From bde7b49ca3a67b10c2cddd5dd5cb3b5feb43da0d Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 25 Mar 2021 14:20:52 +0100 Subject: [PATCH] ue,mac_nr: add basic SR procedure the current implementation support only one SR config and doesn't support the prohibit timer --- .../srsran/interfaces/mac_interface_types.h | 14 ++ .../srsran/interfaces/ue_nr_interfaces.h | 9 +- srsue/hdr/stack/mac_nr/mac_nr.h | 16 ++- srsue/hdr/stack/mac_nr/proc_ra_nr.h | 1 + srsue/hdr/stack/mac_nr/proc_sr_nr.h | 57 ++++++++ srsue/src/stack/mac_nr/CMakeLists.txt | 2 +- srsue/src/stack/mac_nr/mac_nr.cc | 15 ++- srsue/src/stack/mac_nr/proc_ra_nr.cc | 12 ++ srsue/src/stack/mac_nr/proc_sr_nr.cc | 125 ++++++++++++++++++ srsue/src/stack/rrc/rrc_nr.cc | 20 ++- 10 files changed, 248 insertions(+), 23 deletions(-) create mode 100644 srsue/hdr/stack/mac_nr/proc_sr_nr.h create mode 100644 srsue/src/stack/mac_nr/proc_sr_nr.cc diff --git a/lib/include/srsran/interfaces/mac_interface_types.h b/lib/include/srsran/interfaces/mac_interface_types.h index 2cf7940a2..836330366 100644 --- a/lib/include/srsran/interfaces/mac_interface_types.h +++ b/lib/include/srsran/interfaces/mac_interface_types.h @@ -136,6 +136,20 @@ struct rach_nr_cfg_t { } }; +// 38.321 Section 5.4.4 (only one config supported right now) +struct sr_cfg_item_nr_t { + uint8_t sched_request_id; + uint8_t prohibit_timer; + uint8_t trans_max; +}; + +#define SRSRAN_MAX_MAX_NR_OF_SR_CFG_PER_CELL_GROUP (8) +struct sr_cfg_nr_t { + bool enabled; + uint8_t num_items; + sr_cfg_item_nr_t item[SRSRAN_MAX_MAX_NR_OF_SR_CFG_PER_CELL_GROUP]; +}; + struct mac_cfg_t { // Default constructor with default values as in 36.331 9.2.2 mac_cfg_t() { set_defaults(); } diff --git a/lib/include/srsran/interfaces/ue_nr_interfaces.h b/lib/include/srsran/interfaces/ue_nr_interfaces.h index 34db1f4ad..bada51663 100644 --- a/lib/include/srsran/interfaces/ue_nr_interfaces.h +++ b/lib/include/srsran/interfaces/ue_nr_interfaces.h @@ -98,10 +98,11 @@ public: class mac_interface_rrc_nr { public: - virtual void setup_lcid(const srsran::logical_channel_config_t& config) = 0; - virtual void set_config(const srsran::bsr_cfg_t& bsr_cfg) = 0; - virtual void set_config(const srsran::sr_cfg_t& sr_cfg) = 0; - virtual void set_config(const srsran::rach_nr_cfg_t& rach_cfg) = 0; + // Config calls that return SRSRAN_SUCCESS or SRSRAN_ERROR + virtual void setup_lcid(const srsran::logical_channel_config_t& config) = 0; + virtual void set_config(const srsran::bsr_cfg_t& bsr_cfg) = 0; + virtual int32_t set_config(const srsran::sr_cfg_nr_t& sr_cfg) = 0; + virtual void set_config(const srsran::rach_nr_cfg_t& rach_cfg) = 0; // RRC triggers MAC ra procedure virtual void start_ra_procedure() = 0; diff --git a/srsue/hdr/stack/mac_nr/mac_nr.h b/srsue/hdr/stack/mac_nr/mac_nr.h index 465b923db..40f2e00ac 100644 --- a/srsue/hdr/stack/mac_nr/mac_nr.h +++ b/srsue/hdr/stack/mac_nr/mac_nr.h @@ -15,6 +15,7 @@ #include "mac_nr_interfaces.h" #include "proc_ra_nr.h" +#include "proc_sr_nr.h" #include "srsran/common/block_queue.h" #include "srsran/common/mac_pcap.h" #include "srsran/interfaces/mac_interface_types.h" @@ -66,13 +67,13 @@ public: void get_metrics(mac_metrics_t* metrics); /// Interface for RRC (RRC -> MAC) - void setup_lcid(const srsran::logical_channel_config_t& config); - void set_config(const srsran::bsr_cfg_t& bsr_cfg); - void set_config(const srsran::sr_cfg_t& sr_cfg); - void set_config(const srsran::rach_nr_cfg_t& rach_cfg); - void set_contention_id(const uint64_t ue_identity); - bool set_crnti(const uint16_t crnti); - void start_ra_procedure(); + void setup_lcid(const srsran::logical_channel_config_t& config); + void set_config(const srsran::bsr_cfg_t& bsr_cfg); + int32_t set_config(const srsran::sr_cfg_nr_t& sr_cfg); + void set_config(const srsran::rach_nr_cfg_t& rach_cfg); + void set_contention_id(const uint64_t ue_identity); + bool set_crnti(const uint16_t crnti); + void start_ra_procedure(); /// procedure ra nr interface uint64_t get_contention_id(); @@ -144,6 +145,7 @@ private: // MAC Uplink-related procedures proc_ra_nr proc_ra; + proc_sr_nr proc_sr; mux_nr mux; }; diff --git a/srsue/hdr/stack/mac_nr/proc_ra_nr.h b/srsue/hdr/stack/mac_nr/proc_ra_nr.h index 726313514..88feb0f57 100644 --- a/srsue/hdr/stack/mac_nr/proc_ra_nr.h +++ b/srsue/hdr/stack/mac_nr/proc_ra_nr.h @@ -47,6 +47,7 @@ public: void pdcch_to_crnti(); void start_by_rrc(); + void start_by_mac(); void reset(); private: diff --git a/srsue/hdr/stack/mac_nr/proc_sr_nr.h b/srsue/hdr/stack/mac_nr/proc_sr_nr.h new file mode 100644 index 000000000..12dee8275 --- /dev/null +++ b/srsue/hdr/stack/mac_nr/proc_sr_nr.h @@ -0,0 +1,57 @@ +/** + * + * \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 SRSUE_PROC_SR_NR_H +#define SRSUE_PROC_SR_NR_H + +#include "srsran/interfaces/ue_mac_interfaces.h" +#include "srsran/srslog/srslog.h" +#include + +/// Scheduling Request procedure as defined in 5.4.4 of 38.321 +/// Note: currently only a single SR config for all logical channels is supported + +namespace srsue { + +class proc_ra_nr; +class phy_interface_mac_nr; +class rrc_interface_mac; + +class proc_sr_nr +{ +public: + explicit proc_sr_nr(srslog::basic_logger& logger); + int32_t init(proc_ra_nr* ra_, phy_interface_mac_nr* phy_, rrc_interface_mac* rrc_); + void step(uint32_t tti); + int32_t set_config(const srsran::sr_cfg_nr_t& cfg); + void reset(); + void start(); + +private: + bool need_tx(uint32_t tti); + + int sr_counter = 0; + bool is_pending_sr = 0; + + srsran::sr_cfg_nr_t cfg = {}; + + proc_ra_nr* ra = nullptr; + rrc_interface_mac* rrc = nullptr; + phy_interface_mac_nr* phy = nullptr; + srslog::basic_logger& logger; + + bool initiated = false; +}; + +} // namespace srsue + +#endif // SRSUE_PROC_SR_H diff --git a/srsue/src/stack/mac_nr/CMakeLists.txt b/srsue/src/stack/mac_nr/CMakeLists.txt index d051c0d1a..90ccea98c 100644 --- a/srsue/src/stack/mac_nr/CMakeLists.txt +++ b/srsue/src/stack/mac_nr/CMakeLists.txt @@ -6,6 +6,6 @@ # the distribution. # -set(SOURCES mac_nr.cc proc_ra_nr.cc mux_nr.cc) +set(SOURCES mac_nr.cc proc_ra_nr.cc proc_sr_nr.cc mux_nr.cc) add_library(srsue_mac_nr STATIC ${SOURCES}) target_link_libraries(srsue_mac_nr srsran_mac) \ No newline at end of file diff --git a/srsue/src/stack/mac_nr/mac_nr.cc b/srsue/src/stack/mac_nr/mac_nr.cc index e28ea60ab..f84f69b4a 100644 --- a/srsue/src/stack/mac_nr/mac_nr.cc +++ b/srsue/src/stack/mac_nr/mac_nr.cc @@ -17,9 +17,13 @@ namespace srsue { mac_nr::mac_nr(srsran::ext_task_sched_handle task_sched_) : - task_sched(task_sched_), logger(srslog::fetch_basic_logger("MAC")), proc_ra(logger), mux(logger), pcap(nullptr) -{ -} + task_sched(task_sched_), + logger(srslog::fetch_basic_logger("MAC")), + proc_ra(logger), + proc_sr(logger), + mux(logger), + pcap(nullptr) +{} mac_nr::~mac_nr() { @@ -307,10 +311,9 @@ void mac_nr::set_config(const srsran::bsr_cfg_t& bsr_cfg) logger.warning("Not handling BSR config yet"); } -void mac_nr::set_config(const srsran::sr_cfg_t& sr_cfg) +int32_t mac_nr::set_config(const srsran::sr_cfg_nr_t& sr_cfg) { - logger.info("Scheduling Request Config DSR tansmax %d", sr_cfg.dsr_transmax); - logger.warning("Not Scheduling Request Config yet"); + return proc_sr.set_config(sr_cfg); } void mac_nr::set_config(const srsran::rach_nr_cfg_t& rach_cfg) diff --git a/srsue/src/stack/mac_nr/proc_ra_nr.cc b/srsue/src/stack/mac_nr/proc_ra_nr.cc index 024d1787f..b67c80e92 100644 --- a/srsue/src/stack/mac_nr/proc_ra_nr.cc +++ b/srsue/src/stack/mac_nr/proc_ra_nr.cc @@ -74,6 +74,18 @@ void proc_ra_nr::start_by_rrc() ra_procedure_initialization(); } +void proc_ra_nr::start_by_mac() +{ + if (state != IDLE || configured == false) { + logger.warning("Trying to start PRACH by MAC order in invalid state (%s)", + srsran::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, state)); + return; + } + started_by = initiators_t::MAC; + logger.info("Starting PRACH by MAC order"); + ra_procedure_initialization(); +} + bool proc_ra_nr::is_rar_opportunity(uint32_t tti) { // TODO replace second "&&"" by rar_timeout_timer.running if timer thread safe and delayed starting (tti+3) diff --git a/srsue/src/stack/mac_nr/proc_sr_nr.cc b/srsue/src/stack/mac_nr/proc_sr_nr.cc new file mode 100644 index 000000000..e40e1a8ac --- /dev/null +++ b/srsue/src/stack/mac_nr/proc_sr_nr.cc @@ -0,0 +1,125 @@ +/** + * + * \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 "srsue/hdr/stack/mac_nr/proc_sr_nr.h" +#include "srsran/common/standard_streams.h" +#include "srsran/interfaces/ue_phy_interfaces.h" +#include "srsran/interfaces/ue_rrc_interfaces.h" +#include "srsue/hdr/stack/mac_nr/proc_ra_nr.h" + +namespace srsue { + +proc_sr_nr::proc_sr_nr(srslog::basic_logger& logger) : logger(logger) {} + +int32_t proc_sr_nr::init(proc_ra_nr* ra_, phy_interface_mac_nr* phy_, rrc_interface_mac* rrc_) +{ + rrc = rrc_; + ra = ra_; + phy = phy_; + initiated = true; + sr_counter = 0; + return SRSRAN_SUCCESS; +} + +void proc_sr_nr::reset() +{ + is_pending_sr = false; +} + +bool proc_sr_nr::need_tx(uint32_t tti) +{ + int last_tx_tti = 0; // FIXME: phy->sr_last_tx_tti(); + logger.debug("SR: need_tx(): last_tx_tti=%d, tti=%d", last_tx_tti, tti); + if (last_tx_tti >= 0) { + // TODO: implement prohibit timer + if (TTI_SUB(last_tx_tti, tti) >= 8) { + return true; + } + } + return false; +} + +int32_t proc_sr_nr::set_config(const srsran::sr_cfg_nr_t& cfg_) +{ + // disable by default + cfg.enabled = false; + + if (cfg_.num_items != 1) { + logger.error("Only one SR config supported. Disabling SR."); + return SRSRAN_ERROR; + } + + if (cfg_.enabled && cfg_.item[0].trans_max == 0) { + logger.error("Zero is an invalid value for sr-TransMax (n4, n8, n16, n32, n64 are supported). Disabling SR."); + return SRSRAN_ERROR; + } + + if (cfg_.enabled && cfg_.item[0].prohibit_timer > 0) { + logger.error("sr-ProhibitTimer isn't supported. Disabling SR."); + return SRSRAN_ERROR; + } + + if (cfg_.enabled) { + logger.info("SR: Set sr-TransMax=%d", cfg_.item[0].trans_max); + } + + // store config + cfg = cfg_; + + return SRSRAN_SUCCESS; +} + +void proc_sr_nr::step(uint32_t tti) +{ + if (initiated) { + if (is_pending_sr) { + if (cfg.enabled) { + if (sr_counter < cfg.item[0].trans_max) { + if (sr_counter == 0 || need_tx(tti)) { + sr_counter++; + logger.info("SR: Signalling PHY sr_counter=%d", sr_counter); + phy->sr_send(0); // @xavierarteaga what is the ID you expect here? + } + } else { + if (need_tx(tti)) { + logger.info("SR: Releasing PUCCH/SRS resources, sr_counter=%d, sr-TransMax=%d", + sr_counter, + cfg.item[0].trans_max); + srsran::console("Scheduling request failed: releasing RRC connection...\n"); + rrc->release_pucch_srs(); + // TODO: + // - clear any configured downlink assignments and uplink grants; + // - clear any PUSCH resources for semi-persistent CSI reporting; + ra->start_by_mac(); + reset(); + } + } + } else { + logger.info("SR: PUCCH not configured. Starting RA procedure"); + ra->start_by_mac(); + reset(); + } + } + } +} + +void proc_sr_nr::start() +{ + if (initiated) { + if (!is_pending_sr) { + sr_counter = 0; + is_pending_sr = true; + } + } +} + +} // namespace srsue diff --git a/srsue/src/stack/rrc/rrc_nr.cc b/srsue/src/stack/rrc/rrc_nr.cc index dadc003fd..240a4e80c 100644 --- a/srsue/src/stack/rrc/rrc_nr.cc +++ b/srsue/src/stack/rrc/rrc_nr.cc @@ -527,14 +527,24 @@ bool rrc_nr::apply_rlc_add_mod(const rlc_bearer_cfg_s& rlc_bearer_cfg) bool rrc_nr::apply_mac_cell_group(const mac_cell_group_cfg_s& mac_cell_group_cfg) { if (mac_cell_group_cfg.sched_request_cfg_present) { - sr_cfg_t sr_cfg; if (mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list_present) { - if (mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list.size() > 1) { + if (mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list.size() == 1) { + const sched_request_to_add_mod_s& asn1_cfg = + mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list[0]; + sr_cfg_nr_t sr_cfg = {}; + sr_cfg.num_items = 1; + sr_cfg.item[0].sched_request_id = asn1_cfg.sched_request_id; + sr_cfg.item[0].trans_max = asn1_cfg.sr_trans_max.to_number(); + if (asn1_cfg.sr_prohibit_timer_present) { + sr_cfg.item[0].prohibit_timer = asn1_cfg.sr_trans_max; + } + if (mac->set_config(sr_cfg) != SRSRAN_SUCCESS) { + logger.error("Couldn't configure SR procedure."); + return false; + } + } else { logger.warning("Only handling 1 scheduling request index to add"); return false; - } else { - sr_cfg.dsr_transmax = mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list[1].sr_trans_max; - mac->set_config(sr_cfg); } }