mirror of https://github.com/PentHertz/srsLTE.git
Added mac prach nr proc error handling
This commit is contained in:
parent
f9ea02b6bf
commit
7a481c40ab
|
@ -121,6 +121,11 @@ void mac_rar_subpdu_nr::set_backoff(const uint8_t backoff_indicator_)
|
||||||
backoff_indicator = 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
|
std::array<uint8_t, mac_rar_subpdu_nr::UL_GRANT_NBITS> mac_rar_subpdu_nr::get_ul_grant() const
|
||||||
{
|
{
|
||||||
return ul_grant;
|
return ul_grant;
|
||||||
|
|
|
@ -87,6 +87,9 @@ public:
|
||||||
bool msg3_is_pending() { return mux.msg3_is_pending(); }
|
bool msg3_is_pending() { return mux.msg3_is_pending(); }
|
||||||
bool msg3_is_empty() { return mux.msg3_is_empty(); }
|
bool msg3_is_empty() { return mux.msg3_is_empty(); }
|
||||||
|
|
||||||
|
/// RRC
|
||||||
|
void rrc_ra_problem() { rrc->ra_problem(); }
|
||||||
|
|
||||||
/// stack interface
|
/// stack interface
|
||||||
void process_pdus();
|
void process_pdus();
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,9 @@ public:
|
||||||
virtual void msg3_flush() = 0;
|
virtual void msg3_flush() = 0;
|
||||||
virtual void msg3_prepare() = 0;
|
virtual void msg3_prepare() = 0;
|
||||||
virtual bool msg3_is_empty() = 0;
|
virtual bool msg3_is_empty() = 0;
|
||||||
|
|
||||||
|
// RRC functions
|
||||||
|
virtual void rrc_ra_problem() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -82,10 +82,12 @@ private:
|
||||||
srsran::timer_handler::unique_timer prach_send_timer;
|
srsran::timer_handler::unique_timer prach_send_timer;
|
||||||
srsran::timer_handler::unique_timer rar_timeout_timer;
|
srsran::timer_handler::unique_timer rar_timeout_timer;
|
||||||
srsran::timer_handler::unique_timer contention_resolution_timer;
|
srsran::timer_handler::unique_timer contention_resolution_timer;
|
||||||
|
srsran::timer_handler::unique_timer backoff_timer;
|
||||||
|
|
||||||
// 38.321 5.1.1 Variables
|
// 38.321 5.1.1 Variables
|
||||||
uint32_t preamble_index = 0;
|
uint32_t preamble_index = 0;
|
||||||
uint32_t preamble_transmission_counter = 0;
|
uint32_t preamble_transmission_counter = 0;
|
||||||
|
uint32_t preamble_backoff = 0; // in ms
|
||||||
uint32_t preamble_power_ramping_step = 0;
|
uint32_t preamble_power_ramping_step = 0;
|
||||||
int preamble_received_target_power = 0;
|
int preamble_received_target_power = 0;
|
||||||
uint32_t scaling_factor_bi = 0;
|
uint32_t scaling_factor_bi = 0;
|
||||||
|
|
|
@ -96,13 +96,12 @@ public:
|
||||||
void in_sync() final;
|
void in_sync() final;
|
||||||
void out_of_sync() final;
|
void out_of_sync() final;
|
||||||
|
|
||||||
// MAC interface
|
|
||||||
void run_tti(uint32_t tti) final;
|
|
||||||
|
|
||||||
// RLC interface
|
// RLC interface
|
||||||
void max_retx_attempted() final;
|
void max_retx_attempted() final;
|
||||||
|
|
||||||
// MAC interface
|
// MAC interface
|
||||||
|
void run_tti(uint32_t tti) final;
|
||||||
void ra_completed() final;
|
void ra_completed() final;
|
||||||
void ra_problem() final;
|
void ra_problem() final;
|
||||||
void release_pucch_srs() final;
|
void release_pucch_srs() final;
|
||||||
|
|
|
@ -322,7 +322,7 @@ bool mac_nr::set_crnti(const uint16_t c_rnti_)
|
||||||
|
|
||||||
void mac_nr::start_ra_procedure()
|
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)
|
bool mac_nr::is_valid_crnti(const uint16_t crnti)
|
||||||
|
|
|
@ -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();
|
prach_send_timer = task_sched->get_unique_timer();
|
||||||
rar_timeout_timer = task_sched->get_unique_timer();
|
rar_timeout_timer = task_sched->get_unique_timer();
|
||||||
contention_resolution_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 */
|
/* 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)
|
void proc_ra_nr::timer_expired(uint32_t timer_id)
|
||||||
{
|
{
|
||||||
if (prach_send_timer.id() == 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());
|
prach_send_timer.duration());
|
||||||
ra_error();
|
ra_error();
|
||||||
} else if (rar_timeout_timer.id() == timer_id) {
|
} 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();
|
ra_error();
|
||||||
} else if (contention_resolution_timer.id() == timer_id) {
|
} 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();
|
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 {
|
} else {
|
||||||
logger.error("Timer not implemented");
|
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()
|
void proc_ra_nr::ra_procedure_initialization()
|
||||||
{
|
{
|
||||||
mac.msg3_flush();
|
mac.msg3_flush();
|
||||||
|
preamble_transmission_counter = 1;
|
||||||
preamble_power_ramping_step = rach_cfg.powerRampingStep;
|
preamble_power_ramping_step = rach_cfg.powerRampingStep;
|
||||||
scaling_factor_bi = 1;
|
scaling_factor_bi = 1;
|
||||||
|
preamble_backoff = 0;
|
||||||
preambleTransMax = rach_cfg.preambleTransMax;
|
preambleTransMax = rach_cfg.preambleTransMax;
|
||||||
ra_resource_selection();
|
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;
|
rar_rnti = SRSRAN_INVALID_RNTI;
|
||||||
mac.msg3_prepare();
|
mac.msg3_prepare();
|
||||||
current_ta = subpdu.get_ta();
|
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()
|
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
|
// 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);
|
tti);
|
||||||
uint32_t rar_window_st = TTI_ADD(tti, 3);
|
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
|
// 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();
|
rar_timeout_timer.run();
|
||||||
// Wait for RAR reception
|
// Wait for RAR reception
|
||||||
ra_window_length = rach_cfg.ra_responseWindow;
|
ra_window_length = rach_cfg.ra_responseWindow;
|
||||||
|
|
|
@ -1190,7 +1190,11 @@ void rrc_nr::max_retx_attempted() {}
|
||||||
|
|
||||||
// MAC interface
|
// MAC interface
|
||||||
void rrc_nr::ra_completed() {}
|
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() {}
|
void rrc_nr::release_pucch_srs() {}
|
||||||
|
|
||||||
// STACK interface
|
// 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;
|
return proc_outcome_t::error;
|
||||||
}
|
}
|
||||||
|
|
||||||
rrc_ptr->log_rrc_message("RRC NR Reconfiguration",
|
rrc_ptr->log_rrc_message("RRC NRf Reconfiguration",
|
||||||
Rx,
|
Rx,
|
||||||
rrc_recfg.crit_exts.rrc_recfg().secondary_cell_group,
|
rrc_recfg.crit_exts.rrc_recfg().secondary_cell_group,
|
||||||
cell_group_cfg,
|
cell_group_cfg,
|
||||||
|
|
|
@ -53,6 +53,7 @@ private:
|
||||||
class dummy_mac : public mac_interface_proc_ra_nr
|
class dummy_mac : public mac_interface_proc_ra_nr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
dummy_mac() : logger(srslog::fetch_basic_logger("MAC")) {}
|
||||||
uint64_t get_contention_id() { return 0xdeadbeaf; }
|
uint64_t get_contention_id() { return 0xdeadbeaf; }
|
||||||
uint16_t get_crnti() { return crnti; }
|
uint16_t get_crnti() { return crnti; }
|
||||||
bool set_crnti(uint16_t c_rnti)
|
bool set_crnti(uint16_t c_rnti)
|
||||||
|
@ -67,26 +68,24 @@ public:
|
||||||
bool msg3_is_empty() { return true; }
|
bool msg3_is_empty() { return true; }
|
||||||
|
|
||||||
void msga_flush(){};
|
void msga_flush(){};
|
||||||
|
// RRC RA problem
|
||||||
|
void rrc_ra_problem() { logger.warning("Dummy MAC RRC ra problem"); }
|
||||||
|
|
||||||
private:
|
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_phy dummy_phy;
|
||||||
dummy_mac dummy_mac;
|
dummy_mac dummy_mac;
|
||||||
srsran::task_scheduler task_sched{5, 2};
|
srsran::task_scheduler task_sched{5, 2};
|
||||||
srsran::ext_task_sched_handle ext_task_sched_h(&task_sched);
|
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);
|
proc_ra_nr.init(&dummy_phy, &ext_task_sched_h);
|
||||||
|
|
||||||
TESTASSERT(proc_ra_nr.is_rar_opportunity(1) == false);
|
TESTASSERT(proc_ra_nr.is_rar_opportunity(1) == false);
|
||||||
srsran::rach_nr_cfg_t rach_cfg;
|
srsran::rach_nr_cfg_t rach_cfg;
|
||||||
rach_cfg.powerRampingStep = 4;
|
rach_cfg.powerRampingStep = 4;
|
||||||
|
@ -105,7 +104,7 @@ int main()
|
||||||
dummy_phy.get_last_send_prach(&prach_occasion, &preamble_index, &preamble_received_target_power);
|
dummy_phy.get_last_send_prach(&prach_occasion, &preamble_index, &preamble_received_target_power);
|
||||||
TESTASSERT(prach_occasion == 0);
|
TESTASSERT(prach_occasion == 0);
|
||||||
TESTASSERT(preamble_index == 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)
|
// Simulate PHY and call prach_sent (random values)
|
||||||
uint32_t tti_start = 0;
|
uint32_t tti_start = 0;
|
||||||
proc_ra_nr.prach_sent(tti_start, 7, 1, 0, 0);
|
proc_ra_nr.prach_sent(tti_start, 7, 1, 0, 0);
|
||||||
|
@ -135,9 +134,64 @@ int main()
|
||||||
task_sched.tic();
|
task_sched.tic();
|
||||||
task_sched.run_pending_tasks();
|
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.tic();
|
||||||
task_sched.run_pending_tasks();
|
task_sched.run_pending_tasks();
|
||||||
return SRSRAN_SUCCESS;
|
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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue