|
|
|
@ -50,6 +50,10 @@ void proc_ra_nr::init(phy_interface_mac_nr* phy_, srsran::ext_task_sched_handle*
|
|
|
|
|
rar_timeout_timer = task_sched->get_unique_timer();
|
|
|
|
|
contention_resolution_timer = task_sched->get_unique_timer();
|
|
|
|
|
backoff_timer = task_sched->get_unique_timer();
|
|
|
|
|
|
|
|
|
|
struct timeval tv;
|
|
|
|
|
gettimeofday(&tv, NULL);
|
|
|
|
|
random_gen = srsran_random_init(tv.tv_usec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Sets a new configuration. The configuration is applied by initialization() function */
|
|
|
|
@ -127,7 +131,7 @@ bool proc_ra_nr::has_rar_rnti()
|
|
|
|
|
void proc_ra_nr::received_contention_resolution(bool is_successful)
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
|
|
|
ra_contention_resolution(is_successful);
|
|
|
|
|
ra_contention_resolution(is_successful, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void proc_ra_nr::timer_expired(uint32_t timer_id)
|
|
|
|
@ -175,7 +179,11 @@ void proc_ra_nr::ra_preamble_transmission()
|
|
|
|
|
preamble_received_target_power = rach_cfg.PreambleReceivedTargetPower + delta_preamble +
|
|
|
|
|
(preamble_transmission_counter - 1) * rach_cfg.powerRampingStep +
|
|
|
|
|
power_offset_2step_ra;
|
|
|
|
|
preamble_index = 0;
|
|
|
|
|
if (rach_cfg.nof_preambles) {
|
|
|
|
|
preamble_index = srsran_random_uniform_int_dist(random_gen, 0, rach_cfg.nof_preambles);
|
|
|
|
|
} else {
|
|
|
|
|
preamble_index = 0;
|
|
|
|
|
}
|
|
|
|
|
prach_occasion = 0;
|
|
|
|
|
// instruct the physical layer to transmit the Random Access Preamble using the selected PRACH occasion, corresponding
|
|
|
|
|
// RA-RNTI (if available), PREAMBLE_INDEX, and PREAMBLE_RECEIVED_TARGET_POWER.
|
|
|
|
@ -197,8 +205,6 @@ void proc_ra_nr::ra_response_reception(const mac_interface_phy_nr::tb_action_dl_
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Stop rar timer
|
|
|
|
|
rar_timeout_timer.stop();
|
|
|
|
|
if (tb.ack && tb.payload != nullptr) {
|
|
|
|
|
srsran::mac_rar_pdu_nr pdu;
|
|
|
|
|
if (!pdu.unpack(tb.payload->msg, tb.payload->N_bytes)) {
|
|
|
|
@ -212,6 +218,9 @@ void proc_ra_nr::ra_response_reception(const mac_interface_phy_nr::tb_action_dl_
|
|
|
|
|
|
|
|
|
|
for (auto& subpdu : pdu.get_subpdus()) {
|
|
|
|
|
if (subpdu.has_rapid() && subpdu.get_rapid() == preamble_index) {
|
|
|
|
|
// Stop rar timer
|
|
|
|
|
rar_timeout_timer.stop();
|
|
|
|
|
|
|
|
|
|
logger.debug("PROC RA NR: Setting UL grant and prepare Msg3");
|
|
|
|
|
mac.set_temp_crnti(subpdu.get_temp_crnti());
|
|
|
|
|
|
|
|
|
@ -232,18 +241,20 @@ void proc_ra_nr::ra_response_reception(const mac_interface_phy_nr::tb_action_dl_
|
|
|
|
|
} else {
|
|
|
|
|
preamble_backoff = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
contention_resolution_timer.set(rach_cfg.ra_ContentionResolutionTimer,
|
|
|
|
|
[this](uint32_t tid) { timer_expired(tid); });
|
|
|
|
|
contention_resolution_timer.run();
|
|
|
|
|
logger.debug("Waiting for Contention Resolution");
|
|
|
|
|
state = WAITING_FOR_CONTENTION_RESOLUTION;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
contention_resolution_timer.set(rach_cfg.ra_ContentionResolutionTimer, [this](uint32_t tid) { timer_expired(tid); });
|
|
|
|
|
contention_resolution_timer.run();
|
|
|
|
|
logger.debug("Waiting for Contention Resolution");
|
|
|
|
|
state = WAITING_FOR_CONTENTION_RESOLUTION;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TS 38.321 Section 5.1.5 2 ways to resolve contention resolution
|
|
|
|
|
// if the C-RNTI MAC CE was included in Msg3: (only this one is implemented)
|
|
|
|
|
void proc_ra_nr::ra_contention_resolution(bool received_con_res_matches_ue_id)
|
|
|
|
|
void proc_ra_nr::ra_contention_resolution(bool is_successful, bool is_ul_grant)
|
|
|
|
|
{
|
|
|
|
|
if (state != WAITING_FOR_CONTENTION_RESOLUTION) {
|
|
|
|
|
logger.warning(
|
|
|
|
@ -252,15 +263,20 @@ void proc_ra_nr::ra_contention_resolution(bool received_con_res_matches_ue_id)
|
|
|
|
|
srsran::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, WAITING_FOR_CONTENTION_RESOLUTION));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (started_by == initiators_t::RRC || started_by == initiators_t::MAC || received_con_res_matches_ue_id) {
|
|
|
|
|
if (received_con_res_matches_ue_id) {
|
|
|
|
|
logger.info("Received CONRES ID matches transmitted UE ID");
|
|
|
|
|
if (started_by == initiators_t::RRC || started_by == initiators_t::MAC || is_successful) {
|
|
|
|
|
if (is_successful) {
|
|
|
|
|
if (is_ul_grant) {
|
|
|
|
|
logger.info("PDCCH to C-RNTI received with a new UL grant of transmission");
|
|
|
|
|
} else {
|
|
|
|
|
logger.info("Received CONRES ID matches transmitted UE ID");
|
|
|
|
|
}
|
|
|
|
|
contention_resolution_timer.stop();
|
|
|
|
|
state = WAITING_FOR_COMPLETION;
|
|
|
|
|
ra_completion();
|
|
|
|
|
} else {
|
|
|
|
|
logger.info("PDCCH to C-RNTI received with a new UL grant of transmission");
|
|
|
|
|
logger.info("Received CONRES ID DOES NOT match transmitted UE ID");
|
|
|
|
|
mac.set_temp_crnti(SRSRAN_INVALID_RNTI);
|
|
|
|
|
}
|
|
|
|
|
contention_resolution_timer.stop();
|
|
|
|
|
state = WAITING_FOR_COMPLETION;
|
|
|
|
|
ra_completion();
|
|
|
|
|
} else {
|
|
|
|
|
logger.error("Not started by the correct initiator MAC or RRC");
|
|
|
|
|
}
|
|
|
|
@ -376,7 +392,7 @@ void proc_ra_nr::handle_rar_pdu(mac_interface_phy_nr::tb_action_dl_result_t& res
|
|
|
|
|
// Called from PHY thread, defer actions therefore.
|
|
|
|
|
void proc_ra_nr::pdcch_to_crnti()
|
|
|
|
|
{
|
|
|
|
|
task_queue.push([this]() { ra_contention_resolution(false); });
|
|
|
|
|
task_queue.push([this]() { ra_contention_resolution(true, true); });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool proc_ra_nr::is_contention_resolution()
|
|
|
|
|