Added mac prach nr proc error handling

This commit is contained in:
David Rupprecht 2021-03-26 18:44:15 +01:00 committed by Andre Puschmann
parent f9ea02b6bf
commit 7a481c40ab
9 changed files with 128 additions and 21 deletions

View File

@ -121,6 +121,11 @@ void mac_rar_subpdu_nr::set_backoff(const uint8_t backoff_indicator_)
backoff_indicator = backoff_indicator_;
}
uint8_t mac_rar_subpdu_nr::get_backoff() const
{
return backoff_indicator;
}
std::array<uint8_t, mac_rar_subpdu_nr::UL_GRANT_NBITS> mac_rar_subpdu_nr::get_ul_grant() const
{
return ul_grant;

View File

@ -87,6 +87,9 @@ public:
bool msg3_is_pending() { return mux.msg3_is_pending(); }
bool msg3_is_empty() { return mux.msg3_is_empty(); }
/// RRC
void rrc_ra_problem() { rrc->ra_problem(); }
/// stack interface
void process_pdus();

View File

@ -32,6 +32,9 @@ public:
virtual void msg3_flush() = 0;
virtual void msg3_prepare() = 0;
virtual bool msg3_is_empty() = 0;
// RRC functions
virtual void rrc_ra_problem() = 0;
};
/**

View File

@ -82,10 +82,12 @@ private:
srsran::timer_handler::unique_timer prach_send_timer;
srsran::timer_handler::unique_timer rar_timeout_timer;
srsran::timer_handler::unique_timer contention_resolution_timer;
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_backoff = 0; // in ms
uint32_t preamble_power_ramping_step = 0;
int preamble_received_target_power = 0;
uint32_t scaling_factor_bi = 0;

View File

@ -96,13 +96,12 @@ public:
void in_sync() final;
void out_of_sync() final;
// MAC interface
void run_tti(uint32_t tti) final;
// RLC interface
void max_retx_attempted() final;
// MAC interface
void run_tti(uint32_t tti) final;
void ra_completed() final;
void ra_problem() final;
void release_pucch_srs() final;

View File

@ -322,7 +322,7 @@ bool mac_nr::set_crnti(const uint16_t c_rnti_)
void mac_nr::start_ra_procedure()
{
proc_ra.start_by_rrc();
stack_task_dispatch_queue.push([this]() {proc_ra.start_by_rrc();});
}
bool mac_nr::is_valid_crnti(const uint16_t crnti)

View File

@ -40,6 +40,7 @@ void proc_ra_nr::init(phy_interface_mac_nr* phy_, srsran::ext_task_sched_handle*
prach_send_timer = task_sched->get_unique_timer();
rar_timeout_timer = task_sched->get_unique_timer();
contention_resolution_timer = task_sched->get_unique_timer();
backoff_timer = task_sched->get_unique_timer();
}
/* Sets a new configuration. The configuration is applied by initialization() function */
@ -124,15 +125,18 @@ uint16_t proc_ra_nr::get_temp_rnti()
void proc_ra_nr::timer_expired(uint32_t timer_id)
{
if (prach_send_timer.id() == timer_id) {
logger.error("PRACH Send timer expired. PRACH was not transmitted within %d ttis by phy. (TODO)",
logger.warning("PRACH Send timer expired. PRACH was not transmitted within %d ttis by phy. (TODO)",
prach_send_timer.duration());
ra_error();
} else if (rar_timeout_timer.id() == timer_id) {
logger.error("RAR Timer expired. RA response not received within the response window Response Error (TODO)");
logger.warning("RAR Timer expired. RA response not received within the response window");
ra_error();
} else if (contention_resolution_timer.id() == timer_id) {
logger.error("Contention Resolution Timer expired. Stopping PDCCH Search and going to Response Error (TODO)");
logger.warning("Contention Resolution Timer expired. Stopping PDCCH Search and going to Response Error (TODO)");
ra_error();
} else if (backoff_timer.id() == timer_id) {
logger.info("Transmitting new preamble (%d/%d)", preamble_transmission_counter, rach_cfg.preambleTransMax);
ra_resource_selection();
} else {
logger.error("Timer not implemented");
}
@ -142,8 +146,10 @@ void proc_ra_nr::timer_expired(uint32_t timer_id)
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_backoff = 0;
preambleTransMax = rach_cfg.preambleTransMax;
ra_resource_selection();
}
@ -205,6 +211,13 @@ void proc_ra_nr::ra_response_reception(const mac_interface_phy_nr::mac_nr_grant_
rar_rnti = SRSRAN_INVALID_RNTI;
mac.msg3_prepare();
current_ta = subpdu.get_ta();
// Set Backoff parameter
if (subpdu.has_backoff()) {
preamble_backoff = backoff_table_nr[subpdu.get_backoff() % 16]; // TODO multiplied with SCALING_FACTOR_BI.
} else {
preamble_backoff = 0;
}
}
}
}
@ -265,7 +278,31 @@ void proc_ra_nr::ra_completion()
void proc_ra_nr::ra_error()
{
logger.error("NR random access procedure error recovery not implemented yet");
temp_rnti = 0;
preamble_transmission_counter++;
contention_resolution_timer.stop();
uint32_t backoff_wait;
bool ra_procedure_completed = false; // true = (unsuccessfully) completed, false = uncompleted
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;
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.
reset();
}
} else {
// if the Random Access procedure is not completed
if (preamble_backoff) {
backoff_wait = rand() % preamble_backoff;
} else {
backoff_wait = 0;
}
logger.warning("Backoff wait interval %d", backoff_wait);
backoff_timer.set(backoff_wait, [this](uint32_t tid) { timer_expired(tid); });
backoff_timer.run();
}
}
// Is called by PHY once it has transmitted the prach transmitted, than configure RA-RNTI and wait for RAR reception
@ -297,7 +334,7 @@ void proc_ra_nr::prach_sent(uint32_t tti, uint32_t s_id, uint32_t t_id, uint32_t
tti);
uint32_t rar_window_st = TTI_ADD(tti, 3);
// TODO check ra_response window (delayed start)? // last 3 check if needed when we have a delayed start
rar_timeout_timer.set(rach_cfg.ra_responseWindow + 3 + 3, [this](uint32_t tid) { timer_expired(tid); });
rar_timeout_timer.set(rach_cfg.ra_responseWindow + 3 + 10, [this](uint32_t tid) { timer_expired(tid); });
rar_timeout_timer.run();
// Wait for RAR reception
ra_window_length = rach_cfg.ra_responseWindow;

View File

@ -1190,7 +1190,11 @@ void rrc_nr::max_retx_attempted() {}
// MAC interface
void rrc_nr::ra_completed() {}
void rrc_nr::ra_problem() {}
void rrc_nr::ra_problem()
{
rrc_eutra->nr_scg_failure_information(scg_failure_cause_t::random_access_problem);
}
void rrc_nr::release_pucch_srs() {}
// STACK interface
@ -1245,7 +1249,7 @@ proc_outcome_t rrc_nr::connection_reconf_no_ho_proc::init(const reconf_initiator
return proc_outcome_t::error;
}
rrc_ptr->log_rrc_message("RRC NR Reconfiguration",
rrc_ptr->log_rrc_message("RRC NRf Reconfiguration",
Rx,
rrc_recfg.crit_exts.rrc_recfg().secondary_cell_group,
cell_group_cfg,

View File

@ -53,6 +53,7 @@ private:
class dummy_mac : public mac_interface_proc_ra_nr
{
public:
dummy_mac() : logger(srslog::fetch_basic_logger("MAC")) {}
uint64_t get_contention_id() { return 0xdeadbeaf; }
uint16_t get_crnti() { return crnti; }
bool set_crnti(uint16_t c_rnti)
@ -67,26 +68,24 @@ public:
bool msg3_is_empty() { return true; }
void msga_flush(){};
// RRC RA problem
void rrc_ra_problem() { logger.warning("Dummy MAC RRC ra problem"); }
private:
uint16_t crnti = SRSRAN_INVALID_RNTI;
uint16_t crnti = SRSRAN_INVALID_RNTI;
srslog::basic_logger& logger;
};
int main()
int proc_ra_normal_test()
{
srslog::init();
auto& mac_logger = srslog::fetch_basic_logger("MAC");
mac_logger.set_level(srslog::basic_levels::debug);
mac_logger.set_hex_dump_max_size(-1);
dummy_phy dummy_phy;
dummy_mac dummy_mac;
srsran::task_scheduler task_sched{5, 2};
srsran::ext_task_sched_handle ext_task_sched_h(&task_sched);
proc_ra_nr proc_ra_nr(dummy_mac, mac_logger);
proc_ra_nr proc_ra_nr(dummy_mac, srslog::fetch_basic_logger("MAC"));
proc_ra_nr.init(&dummy_phy, &ext_task_sched_h);
TESTASSERT(proc_ra_nr.is_rar_opportunity(1) == false);
srsran::rach_nr_cfg_t rach_cfg;
rach_cfg.powerRampingStep = 4;
@ -105,7 +104,7 @@ int main()
dummy_phy.get_last_send_prach(&prach_occasion, &preamble_index, &preamble_received_target_power);
TESTASSERT(prach_occasion == 0);
TESTASSERT(preamble_index == 0);
TESTASSERT(preamble_received_target_power == -114);
TESTASSERT(preamble_received_target_power == -110);
// Simulate PHY and call prach_sent (random values)
uint32_t tti_start = 0;
proc_ra_nr.prach_sent(tti_start, 7, 1, 0, 0);
@ -135,9 +134,64 @@ int main()
task_sched.tic();
task_sched.run_pending_tasks();
proc_ra_nr.pdcch_to_crnti();
return SRSRAN_SUCCESS;
}
int proc_ra_timeout_test()
{
dummy_phy dummy_phy;
dummy_mac dummy_mac;
srsran::task_scheduler task_sched{5, 2};
srsran::ext_task_sched_handle ext_task_sched_h(&task_sched);
proc_ra_nr proc_ra_nr(dummy_mac, srslog::fetch_basic_logger("MAC"));
proc_ra_nr.init(&dummy_phy, &ext_task_sched_h);
TESTASSERT(proc_ra_nr.is_rar_opportunity(1) == false);
srsran::rach_nr_cfg_t rach_cfg;
rach_cfg.powerRampingStep = 4;
rach_cfg.prach_ConfigurationIndex = 16;
rach_cfg.PreambleReceivedTargetPower = -110;
rach_cfg.preambleTransMax = 7;
rach_cfg.ra_ContentionResolutionTimer = 64;
rach_cfg.ra_responseWindow = 10;
proc_ra_nr.set_config(rach_cfg);
proc_ra_nr.start_by_rrc();
// Test send prach parameters
uint32_t prach_occasion = 0;
uint32_t preamble_index = 0;
int preamble_received_target_power = 0;
dummy_phy.get_last_send_prach(&prach_occasion, &preamble_index, &preamble_received_target_power);
TESTASSERT(prach_occasion == 0);
TESTASSERT(preamble_index == 0);
TESTASSERT(preamble_received_target_power == -110);
// Simulate PHY and call prach_sent (random values)
uint32_t tti = 0;
for (uint32_t j = 0; j < rach_cfg.preambleTransMax; j++) {
proc_ra_nr.prach_sent(tti, 7, 1, 0, 0);
uint32_t i = 0;
for (i = tti; i < tti + rach_cfg.ra_responseWindow + 100; i++) {
// update clock and run internal tasks
task_sched.tic();
task_sched.run_pending_tasks();
}
tti = i;
}
task_sched.tic();
task_sched.run_pending_tasks();
return SRSRAN_SUCCESS;
}
int main()
{
srslog::init();
auto& mac_logger = srslog::fetch_basic_logger("MAC");
mac_logger.set_level(srslog::basic_levels::debug);
mac_logger.set_hex_dump_max_size(-1);
// TESTASSERT(proc_ra_normal_test() == SRSRAN_SUCCESS);
TESTASSERT(proc_ra_timeout_test() == SRSRAN_SUCCESS);
return SRSRAN_SUCCESS;
}