ue,mac_nr: add basic SR procedure

the current implementation support only one SR config
and doesn't support the prohibit timer
This commit is contained in:
Andre Puschmann 2021-03-25 14:20:52 +01:00
parent 6219500148
commit bde7b49ca3
10 changed files with 248 additions and 23 deletions

View File

@ -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(); }

View File

@ -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;

View File

@ -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;
};

View File

@ -47,6 +47,7 @@ public:
void pdcch_to_crnti();
void start_by_rrc();
void start_by_mac();
void reset();
private:

View File

@ -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 <stdint.h>
/// 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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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);
}
}