|
|
@ -38,12 +38,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
namespace srsue {
|
|
|
|
namespace srsue {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const char* state_str[6] = {
|
|
|
|
|
|
|
|
"RA: INIT: ", "RA: PDCCH: ", "RA: Rx: ", "RA: Backof: ", "RA: ConRes: ", "RA: Complt: "};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define rError(fmt, ...) Error("%s" fmt, state_str[state], ##__VA_ARGS__)
|
|
|
|
|
|
|
|
#define rInfo(fmt, ...) Info("%s" fmt, state_str[state], ##__VA_ARGS__)
|
|
|
|
|
|
|
|
#define rDebug(fmt, ...) Debug("%s" fmt, state_str[state], ##__VA_ARGS__)
|
|
|
|
|
|
|
|
|
|
|
|
// Table 7.2-1. Backoff Parameter values
|
|
|
|
// Table 7.2-1. Backoff Parameter values
|
|
|
|
uint32_t backoff_table[16] = {0, 10, 20, 30, 40, 60, 80, 120, 160, 240, 320, 480, 960, 960, 960, 960};
|
|
|
|
uint32_t backoff_table[16] = {0, 10, 20, 30, 40, 60, 80, 120, 160, 240, 320, 480, 960, 960, 960, 960};
|
|
|
|
|
|
|
|
|
|
|
|
// Table 7.6-1: DELTA_PREAMBLE values.
|
|
|
|
// Table 7.6-1: DELTA_PREAMBLE values.
|
|
|
|
int delta_preamble_db_table[5] = {0, 0, -3, -3, 8};
|
|
|
|
int delta_preamble_db_table[5] = {0, 0, -3, -3, 8};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Initializes memory and pointers to other objects
|
|
|
|
void ra_proc::init(phy_interface_mac_lte* phy_h_,
|
|
|
|
void ra_proc::init(phy_interface_mac_lte* phy_h_,
|
|
|
|
rrc_interface_mac* rrc_,
|
|
|
|
rrc_interface_mac* rrc_,
|
|
|
|
srslte::log* log_h_,
|
|
|
|
srslte::log* log_h_,
|
|
|
@ -80,15 +88,17 @@ void ra_proc::reset() {
|
|
|
|
|
|
|
|
|
|
|
|
void ra_proc::start_pcap(srslte::mac_pcap* pcap_)
|
|
|
|
void ra_proc::start_pcap(srslte::mac_pcap* pcap_)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pcap = pcap_;
|
|
|
|
pcap = pcap_;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Sets a new configuration. The configuration is applied by initialization() function */
|
|
|
|
void ra_proc::set_config(srsue::mac_interface_rrc::rach_cfg_t& rach_cfg)
|
|
|
|
void ra_proc::set_config(srsue::mac_interface_rrc::rach_cfg_t& rach_cfg)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::unique_lock<std::mutex> ul(mutex);
|
|
|
|
std::unique_lock<std::mutex> ul(mutex);
|
|
|
|
new_cfg = rach_cfg;
|
|
|
|
new_cfg = rach_cfg;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Reads the configuration and configures internal variables */
|
|
|
|
void ra_proc::read_params()
|
|
|
|
void ra_proc::read_params()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
mutex.lock();
|
|
|
|
mutex.lock();
|
|
|
@ -117,75 +127,129 @@ void ra_proc::read_params()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool ra_proc::is_contention_resolution() {
|
|
|
|
/* Function called by MAC every TTI. Runs a state function until it changes to a different state
|
|
|
|
return state == CONTENTION_RESOLUTION;
|
|
|
|
*/
|
|
|
|
|
|
|
|
void ra_proc::step(uint32_t tti_)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
switch (state) {
|
|
|
|
|
|
|
|
case IDLE:
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PDCCH_SETUP:
|
|
|
|
|
|
|
|
state_pdcch_setup();
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RESPONSE_RECEPTION:
|
|
|
|
|
|
|
|
state_response_reception(tti_);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BACKOFF_WAIT:
|
|
|
|
|
|
|
|
state_backoff_wait(tti_);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CONTENTION_RESOLUTION:
|
|
|
|
|
|
|
|
state_contention_resolution();
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case COMPLETITION:
|
|
|
|
|
|
|
|
state_completition();
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const char* state_str[12] = {"Idle",
|
|
|
|
/* Waits for PRACH to be transmitted by PHY. Once it's transmitted, configure RA-RNTI and wait for RAR reception
|
|
|
|
"RA: INIT: ",
|
|
|
|
*/
|
|
|
|
"RA: Select: ",
|
|
|
|
void ra_proc::state_pdcch_setup()
|
|
|
|
"RA: TX: ",
|
|
|
|
{
|
|
|
|
"RA: PDCCH: ",
|
|
|
|
|
|
|
|
"RA: Rx: ",
|
|
|
|
|
|
|
|
"RA: RxErr: ",
|
|
|
|
|
|
|
|
"RA: Backof: ",
|
|
|
|
|
|
|
|
"RA: ConRes: ",
|
|
|
|
|
|
|
|
"RA: Done: ",
|
|
|
|
|
|
|
|
"RA: Done: ",
|
|
|
|
|
|
|
|
"RA: Error: "};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define rError(fmt, ...) Error("%s" fmt, state_str[state], ##__VA_ARGS__)
|
|
|
|
|
|
|
|
#define rInfo(fmt, ...) Info("%s" fmt, state_str[state], ##__VA_ARGS__)
|
|
|
|
|
|
|
|
#define rDebug(fmt, ...) Debug("%s" fmt, state_str[state], ##__VA_ARGS__)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
phy_interface_mac_lte::prach_info_t info = phy_h->prach_get_info();
|
|
|
|
// Process Timing Advance Command as defined in Section 5.2
|
|
|
|
if (info.is_transmitted) {
|
|
|
|
void ra_proc::process_timeadv_cmd(uint32_t ta) {
|
|
|
|
ra_tti = info.tti_ra;
|
|
|
|
if (preambleIndex == 0) {
|
|
|
|
ra_rnti = 1 + (ra_tti % 10) + info.f_id;
|
|
|
|
// Preamble not selected by UE MAC
|
|
|
|
rInfo("seq=%d, ra-rnti=0x%x, ra-tti=%d, f_id=%d\n", sel_preamble, ra_rnti, info.tti_ra, info.f_id);
|
|
|
|
phy_h->set_timeadv_rar(ta);
|
|
|
|
log_h->console("Random Access Transmission: seq=%d, ra-rnti=0x%x\n", sel_preamble, ra_rnti);
|
|
|
|
// Only if timer is running reset the timer
|
|
|
|
rar_window_st = ra_tti + 3;
|
|
|
|
if (time_alignment_timer->is_running()) {
|
|
|
|
rntis->rar_rnti = ra_rnti;
|
|
|
|
time_alignment_timer->reset();
|
|
|
|
state = RESPONSE_RECEPTION;
|
|
|
|
time_alignment_timer->run();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Debug("Applying RAR TA CMD %d\n", ta);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
// Preamble selected by UE MAC
|
|
|
|
rDebug("preamble not yet transmitted\n");
|
|
|
|
if (!time_alignment_timer->is_running()) {
|
|
|
|
}
|
|
|
|
phy_h->set_timeadv_rar(ta);
|
|
|
|
}
|
|
|
|
time_alignment_timer->run();
|
|
|
|
|
|
|
|
Debug("Applying RAR TA CMD %d\n", ta);
|
|
|
|
/* Waits for RAR reception. rar_received variable will be set by tb_decoded_ok() function which is called when a DL
|
|
|
|
|
|
|
|
* TB assigned to RA-RNTI is received
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
void ra_proc::state_response_reception(uint32_t tti)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// do nothing. Processing done in tb_decoded_ok()
|
|
|
|
|
|
|
|
if (!rar_received) {
|
|
|
|
|
|
|
|
uint32_t interval = srslte_tti_interval(tti, ra_tti + 3 + rach_cfg.responseWindowSize - 1);
|
|
|
|
|
|
|
|
if (interval > 0 && interval < 100) {
|
|
|
|
|
|
|
|
Error("RA response not received within the response window\n");
|
|
|
|
|
|
|
|
response_error();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Waits for given backoff interval to expire
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
void ra_proc::state_backoff_wait(uint32_t tti)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (backoff_interval > 0) {
|
|
|
|
|
|
|
|
// Backoff_interval = 0 is handled before entering here
|
|
|
|
|
|
|
|
// When we arrive to this state, there is already 1 TTI delay
|
|
|
|
|
|
|
|
if (backoff_interval == 1) {
|
|
|
|
|
|
|
|
resource_selection();
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
// Ignore TA CMD
|
|
|
|
// If it's the first time, save TTI
|
|
|
|
Warning("Ignoring RAR TA CMD because timeAlignmentTimer still running\n");
|
|
|
|
if (backoff_interval_start == -1) {
|
|
|
|
|
|
|
|
backoff_interval_start = tti;
|
|
|
|
|
|
|
|
backoff_interval--;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (srslte_tti_interval(tti, backoff_interval_start) >= backoff_interval) {
|
|
|
|
|
|
|
|
backoff_interval = 0;
|
|
|
|
|
|
|
|
resource_selection();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ra_proc::step_initialization() {
|
|
|
|
/* Actions during contention resolution state as defined in 5.1.5
|
|
|
|
|
|
|
|
* Resolution of the Contention is made by contention_resolution_id_received() and pdcch_to_crnti()
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
void ra_proc::state_contention_resolution()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// Once Msg3 is transmitted, start contention resolution timer
|
|
|
|
|
|
|
|
if (mux_unit->msg3_is_transmitted() && !contention_resolution_timer->is_running()) {
|
|
|
|
|
|
|
|
// Start contention resolution timer
|
|
|
|
|
|
|
|
rInfo("Starting ContentionResolutionTimer=%d ms\n", contention_resolution_timer->get_timeout());
|
|
|
|
|
|
|
|
contention_resolution_timer->reset();
|
|
|
|
|
|
|
|
contention_resolution_timer->run();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* This step just configures the PHY to generate the C-RNTI. It is called from a state because it takes a long time to
|
|
|
|
|
|
|
|
* compute
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
void ra_proc::state_completition()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
phy_h->set_crnti(rntis->crnti);
|
|
|
|
|
|
|
|
state = IDLE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* RA procedure initialization as defined in 5.1.1 */
|
|
|
|
|
|
|
|
void ra_proc::initialization()
|
|
|
|
|
|
|
|
{
|
|
|
|
read_params();
|
|
|
|
read_params();
|
|
|
|
pdcch_to_crnti_received = PDCCH_CRNTI_NOT_RECEIVED;
|
|
|
|
transmitted_contention_id = 0;
|
|
|
|
transmitted_contention_id = 0;
|
|
|
|
|
|
|
|
preambleTransmissionCounter = 1;
|
|
|
|
preambleTransmissionCounter = 1;
|
|
|
|
first_rar_received = true;
|
|
|
|
|
|
|
|
mux_unit->msg3_flush();
|
|
|
|
mux_unit->msg3_flush();
|
|
|
|
msg3_flushed = false;
|
|
|
|
backoff_param_ms = 0;
|
|
|
|
backoff_param_ms = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// FIXME: This is because RA in Connected state not working in amarisoft
|
|
|
|
|
|
|
|
transmitted_crnti = rntis->crnti;
|
|
|
|
|
|
|
|
if(transmitted_crnti) {
|
|
|
|
|
|
|
|
state = RESPONSE_ERROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Instruct phy to configure PRACH
|
|
|
|
// Instruct phy to configure PRACH
|
|
|
|
phy_h->configure_prach_params();
|
|
|
|
phy_h->configure_prach_params();
|
|
|
|
state = RESOURCE_SELECTION;
|
|
|
|
|
|
|
|
|
|
|
|
// Jump directly to Resource selection
|
|
|
|
|
|
|
|
resource_selection();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ra_proc::step_resource_selection()
|
|
|
|
/* Resource selection as defined in 5.1.2 */
|
|
|
|
|
|
|
|
void ra_proc::resource_selection()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ra_group_t sel_group;
|
|
|
|
ra_group_t sel_group;
|
|
|
|
|
|
|
|
|
|
|
@ -217,7 +281,7 @@ void ra_proc::step_resource_selection()
|
|
|
|
sel_preamble = rand() % rach_cfg.nof_groupA_preambles;
|
|
|
|
sel_preamble = rand() % rach_cfg.nof_groupA_preambles;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
rError("Selected group preamble A but nof_groupA_preambles=0\n");
|
|
|
|
rError("Selected group preamble A but nof_groupA_preambles=0\n");
|
|
|
|
state = RA_PROBLEM;
|
|
|
|
state = IDLE;
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
@ -226,7 +290,7 @@ void ra_proc::step_resource_selection()
|
|
|
|
sel_preamble = rach_cfg.nof_groupA_preambles + rand() % nof_groupB_preambles;
|
|
|
|
sel_preamble = rach_cfg.nof_groupA_preambles + rand() % nof_groupB_preambles;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
rError("Selected group preamble B but nof_groupA_preambles=0\n");
|
|
|
|
rError("Selected group preamble B but nof_groupA_preambles=0\n");
|
|
|
|
state = RA_PROBLEM;
|
|
|
|
state = IDLE;
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -238,51 +302,55 @@ void ra_proc::step_resource_selection()
|
|
|
|
sel_maskIndex,
|
|
|
|
sel_maskIndex,
|
|
|
|
rach_cfg.nof_groupA_preambles,
|
|
|
|
rach_cfg.nof_groupA_preambles,
|
|
|
|
nof_groupB_preambles);
|
|
|
|
nof_groupB_preambles);
|
|
|
|
state = PREAMBLE_TRANSMISSION;
|
|
|
|
|
|
|
|
|
|
|
|
// Jump directly to transmission
|
|
|
|
|
|
|
|
preamble_transmission();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ra_proc::step_preamble_transmission() {
|
|
|
|
/* Preamble transmission as defined in 5.1.3 */
|
|
|
|
|
|
|
|
void ra_proc::preamble_transmission()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
received_target_power_dbm = rach_cfg.iniReceivedTargetPower + delta_preamble_db +
|
|
|
|
received_target_power_dbm = rach_cfg.iniReceivedTargetPower + delta_preamble_db +
|
|
|
|
(preambleTransmissionCounter - 1) * rach_cfg.powerRampingStep;
|
|
|
|
(preambleTransmissionCounter - 1) * rach_cfg.powerRampingStep;
|
|
|
|
|
|
|
|
|
|
|
|
rar_received = false;
|
|
|
|
|
|
|
|
phy_h->prach_send(sel_preamble, sel_maskIndex - 1, received_target_power_dbm);
|
|
|
|
phy_h->prach_send(sel_preamble, sel_maskIndex - 1, received_target_power_dbm);
|
|
|
|
|
|
|
|
rntis->rar_rnti = 0;
|
|
|
|
|
|
|
|
ra_tti = 0;
|
|
|
|
|
|
|
|
rar_received = false;
|
|
|
|
|
|
|
|
backoff_interval_start = -1;
|
|
|
|
|
|
|
|
|
|
|
|
state = PDCCH_SETUP;
|
|
|
|
state = PDCCH_SETUP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool ra_proc::is_rar_window(int* rar_window_start, int* rar_window_length)
|
|
|
|
// Process Timing Advance Command as defined in Section 5.2
|
|
|
|
|
|
|
|
void ra_proc::process_timeadv_cmd(uint32_t ta)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (state == RESPONSE_RECEPTION) {
|
|
|
|
if (preambleIndex == 0) {
|
|
|
|
if (rar_window_length) {
|
|
|
|
// Preamble not selected by UE MAC
|
|
|
|
*rar_window_length = rach_cfg.responseWindowSize;
|
|
|
|
phy_h->set_timeadv_rar(ta);
|
|
|
|
}
|
|
|
|
// Only if timer is running reset the timer
|
|
|
|
if (rar_window_start) {
|
|
|
|
if (time_alignment_timer->is_running()) {
|
|
|
|
*rar_window_start = rar_window_st;
|
|
|
|
time_alignment_timer->reset();
|
|
|
|
|
|
|
|
time_alignment_timer->run();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
Debug("Applying RAR TA CMD %d\n", ta);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (rar_window_length) {
|
|
|
|
// Preamble selected by UE MAC
|
|
|
|
*rar_window_length = -1;
|
|
|
|
if (!time_alignment_timer->is_running()) {
|
|
|
|
|
|
|
|
phy_h->set_timeadv_rar(ta);
|
|
|
|
|
|
|
|
time_alignment_timer->run();
|
|
|
|
|
|
|
|
Debug("Applying RAR TA CMD %d\n", ta);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// Ignore TA CMD
|
|
|
|
|
|
|
|
Warning("Ignoring RAR TA CMD because timeAlignmentTimer still running\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ra_proc::step_pdcch_setup()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
phy_interface_mac_lte::prach_info_t info = phy_h->prach_get_info();
|
|
|
|
|
|
|
|
if (info.is_transmitted) {
|
|
|
|
|
|
|
|
ra_rnti = 1 + info.tti_ra % 10 + info.f_id;
|
|
|
|
|
|
|
|
rInfo("seq=%d, ra-rnti=0x%x, ra-tti=%d, f_id=%d\n", sel_preamble, ra_rnti, info.tti_ra, info.f_id);
|
|
|
|
|
|
|
|
log_h->console("Random Access Transmission: seq=%d, ra-rnti=0x%x\n", sel_preamble, ra_rnti);
|
|
|
|
|
|
|
|
rar_window_st = info.tti_ra + 3;
|
|
|
|
|
|
|
|
rntis->rar_rnti = ra_rnti;
|
|
|
|
|
|
|
|
state = RESPONSE_RECEPTION;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Called upon the reception of a DL grant for RA-RNTI
|
|
|
|
|
|
|
|
* Configures the action and softbuffer for the reception of the associated TB
|
|
|
|
|
|
|
|
*/
|
|
|
|
void ra_proc::new_grant_dl(mac_interface_phy_lte::mac_grant_dl_t grant, mac_interface_phy_lte::tb_action_dl_t* action)
|
|
|
|
void ra_proc::new_grant_dl(mac_interface_phy_lte::mac_grant_dl_t grant, mac_interface_phy_lte::tb_action_dl_t* action)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
bzero(action, sizeof(mac_interface_phy_lte::tb_action_dl_t));
|
|
|
|
bzero(action, sizeof(mac_interface_phy_lte::tb_action_dl_t));
|
|
|
@ -299,10 +367,12 @@ void ra_proc::new_grant_dl(mac_interface_phy_lte::mac_grant_dl_t grant, mac_inte
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
rError("Received RAR dci exceeds buffer length (%d>%d)\n", grant.tb[0].tbs, MAX_RAR_PDU_LEN);
|
|
|
|
rError("Received RAR dci exceeds buffer length (%d>%d)\n", grant.tb[0].tbs, MAX_RAR_PDU_LEN);
|
|
|
|
state = RESPONSE_ERROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Called upon the successful decoding of a TB addressed to RA-RNTI.
|
|
|
|
|
|
|
|
* Processes the reception of a RAR as defined in 5.1.4
|
|
|
|
|
|
|
|
*/
|
|
|
|
void ra_proc::tb_decoded_ok() {
|
|
|
|
void ra_proc::tb_decoded_ok() {
|
|
|
|
if (pcap) {
|
|
|
|
if (pcap) {
|
|
|
|
pcap->write_dl_ranti(rar_pdu_buffer, rar_grant_nbytes, ra_rnti, true, 0);
|
|
|
|
pcap->write_dl_ranti(rar_pdu_buffer, rar_grant_nbytes, ra_rnti, true, 0);
|
|
|
@ -312,6 +382,7 @@ void ra_proc::tb_decoded_ok() {
|
|
|
|
|
|
|
|
|
|
|
|
rar_pdu_msg.init_rx(rar_grant_nbytes);
|
|
|
|
rar_pdu_msg.init_rx(rar_grant_nbytes);
|
|
|
|
rar_pdu_msg.parse_packet(rar_pdu_buffer);
|
|
|
|
rar_pdu_msg.parse_packet(rar_pdu_buffer);
|
|
|
|
|
|
|
|
|
|
|
|
// Set Backoff parameter
|
|
|
|
// Set Backoff parameter
|
|
|
|
if (rar_pdu_msg.has_backoff()) {
|
|
|
|
if (rar_pdu_msg.has_backoff()) {
|
|
|
|
backoff_param_ms = backoff_table[rar_pdu_msg.get_backoff()%16];
|
|
|
|
backoff_param_ms = backoff_table[rar_pdu_msg.get_backoff()%16];
|
|
|
@ -345,14 +416,14 @@ void ra_proc::tb_decoded_ok() {
|
|
|
|
|
|
|
|
|
|
|
|
if (preambleIndex > 0) {
|
|
|
|
if (preambleIndex > 0) {
|
|
|
|
// Preamble selected by Network
|
|
|
|
// Preamble selected by Network
|
|
|
|
state = COMPLETION;
|
|
|
|
complete();
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
// Preamble selected by UE MAC
|
|
|
|
// Preamble selected by UE MAC
|
|
|
|
mux_unit->msg3_prepare();
|
|
|
|
mux_unit->msg3_prepare();
|
|
|
|
rntis->temp_rnti = rar_pdu_msg.get()->get_temp_crnti();
|
|
|
|
rntis->temp_rnti = rar_pdu_msg.get()->get_temp_crnti();
|
|
|
|
|
|
|
|
|
|
|
|
if (first_rar_received) {
|
|
|
|
// If this is the first successfully received RAR within this procedure, Msg3 is empty
|
|
|
|
first_rar_received = false;
|
|
|
|
if (mux_unit->msg3_is_empty()) {
|
|
|
|
|
|
|
|
|
|
|
|
// Save transmitted C-RNTI (if any)
|
|
|
|
// Save transmitted C-RNTI (if any)
|
|
|
|
transmitted_crnti = rntis->crnti;
|
|
|
|
transmitted_crnti = rntis->crnti;
|
|
|
@ -361,16 +432,14 @@ void ra_proc::tb_decoded_ok() {
|
|
|
|
if (transmitted_crnti) {
|
|
|
|
if (transmitted_crnti) {
|
|
|
|
rInfo("Appending C-RNTI MAC CE 0x%x in next transmission\n", transmitted_crnti);
|
|
|
|
rInfo("Appending C-RNTI MAC CE 0x%x in next transmission\n", transmitted_crnti);
|
|
|
|
mux_unit->append_crnti_ce_next_tx(transmitted_crnti);
|
|
|
|
mux_unit->append_crnti_ce_next_tx(transmitted_crnti);
|
|
|
|
rntis->crnti = transmitted_crnti;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
rDebug("Going to Contention Resolution state\n");
|
|
|
|
|
|
|
|
state = CONTENTION_RESOLUTION;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Start contention resolution timer
|
|
|
|
// Save transmitted UE contention id, as defined by higher layers
|
|
|
|
rInfo("Starting ContentionResolutionTimer=%d ms\n", contention_resolution_timer->get_timeout());
|
|
|
|
transmitted_contention_id = rntis->contention_id;
|
|
|
|
contention_resolution_timer->reset();
|
|
|
|
|
|
|
|
contention_resolution_timer->run();
|
|
|
|
rDebug("Waiting for Contention Resolution\n");
|
|
|
|
|
|
|
|
state = CONTENTION_RESOLUTION;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (rar_pdu_msg.get()->has_rapid()) {
|
|
|
|
if (rar_pdu_msg.get()->has_rapid()) {
|
|
|
@ -380,170 +449,61 @@ void ra_proc::tb_decoded_ok() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ra_proc::step_response_reception(uint32_t tti)
|
|
|
|
/* Called after RA response window expiration without a valid RAPID or after a reception of an invalid
|
|
|
|
{
|
|
|
|
* Contention Resolution ID
|
|
|
|
// do nothing. Processing done in tb_decoded_ok()
|
|
|
|
*/
|
|
|
|
phy_interface_mac_lte::prach_info_t prach_info = phy_h->prach_get_info();
|
|
|
|
void ra_proc::response_error()
|
|
|
|
if (prach_info.is_transmitted && !rar_received) {
|
|
|
|
|
|
|
|
uint32_t interval = srslte_tti_interval(tti, prach_info.tti_ra + 3 + rach_cfg.responseWindowSize);
|
|
|
|
|
|
|
|
if (interval > 1 && interval < 100) {
|
|
|
|
|
|
|
|
Error("RA response not received within the response window\n");
|
|
|
|
|
|
|
|
state = RESPONSE_ERROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ra_proc::step_response_error(uint32_t tti)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
rntis->temp_rnti = 0;
|
|
|
|
preambleTransmissionCounter++;
|
|
|
|
preambleTransmissionCounter++;
|
|
|
|
if (preambleTransmissionCounter >= rach_cfg.preambleTransMax + 1) {
|
|
|
|
if (preambleTransmissionCounter >= rach_cfg.preambleTransMax + 1) {
|
|
|
|
rError("Maximum number of transmissions reached (%d)\n", rach_cfg.preambleTransMax);
|
|
|
|
rError("Maximum number of transmissions reached (%d)\n", rach_cfg.preambleTransMax);
|
|
|
|
rrc->ra_problem();
|
|
|
|
rrc->ra_problem();
|
|
|
|
state = RA_PROBLEM;
|
|
|
|
state = IDLE;
|
|
|
|
if (ra_is_ho) {
|
|
|
|
if (ra_is_ho) {
|
|
|
|
rrc->ho_ra_completed(false);
|
|
|
|
rrc->ho_ra_completed(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
backoff_interval_start = tti;
|
|
|
|
backoff_interval_start = -1;
|
|
|
|
if (backoff_param_ms) {
|
|
|
|
if (backoff_param_ms) {
|
|
|
|
backoff_inteval = rand() % backoff_param_ms;
|
|
|
|
backoff_interval = rand() % backoff_param_ms;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
backoff_inteval = 0;
|
|
|
|
backoff_interval = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (backoff_inteval) {
|
|
|
|
if (backoff_interval) {
|
|
|
|
rDebug("Backoff wait interval %d\n", backoff_inteval);
|
|
|
|
rDebug("Backoff wait interval %d\n", backoff_interval);
|
|
|
|
state = BACKOFF_WAIT;
|
|
|
|
state = BACKOFF_WAIT;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
rDebug("Transmitting inmediatly (%d/%d)\n", preambleTransmissionCounter, rach_cfg.preambleTransMax);
|
|
|
|
rDebug("Transmitting inmediatly (%d/%d)\n", preambleTransmissionCounter, rach_cfg.preambleTransMax);
|
|
|
|
state = RESOURCE_SELECTION;
|
|
|
|
resource_selection();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ra_proc::step_backoff_wait(uint32_t tti)
|
|
|
|
bool ra_proc::is_contention_resolution()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (srslte_tti_interval(tti, backoff_interval_start) >= backoff_inteval) {
|
|
|
|
return state == CONTENTION_RESOLUTION;
|
|
|
|
state = RESOURCE_SELECTION;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Random Access initiated by RRC by the transmission of CCCH SDU
|
|
|
|
|
|
|
|
bool ra_proc::contention_resolution_id_received(uint64_t rx_contention_id) {
|
|
|
|
|
|
|
|
bool uecri_successful = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rDebug("MAC PDU Contains Contention Resolution ID CE\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// MAC PDU successfully decoded and contains MAC CE contention Id
|
|
|
|
|
|
|
|
contention_resolution_timer->stop();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (transmitted_contention_id == rx_contention_id)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// UE Contention Resolution ID included in MAC CE matches the CCCH SDU transmitted in Msg3
|
|
|
|
|
|
|
|
uecri_successful = true;
|
|
|
|
|
|
|
|
state = COMPLETION;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
rInfo("Transmitted UE Contention Id differs from received Contention ID (0x%" PRIu64 " != 0x%" PRIu64 ")\n",
|
|
|
|
|
|
|
|
transmitted_contention_id, rx_contention_id);
|
|
|
|
|
|
|
|
// Discard MAC PDU
|
|
|
|
|
|
|
|
uecri_successful = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Contention Resolution not successfully is like RAR not successful
|
|
|
|
|
|
|
|
// FIXME: Need to flush Msg3 HARQ buffer. Why?
|
|
|
|
|
|
|
|
state = RESPONSE_ERROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return uecri_successful;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ra_proc::step_contention_resolution() {
|
|
|
|
|
|
|
|
// If Msg3 has been sent
|
|
|
|
|
|
|
|
if (mux_unit->msg3_is_transmitted())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
msg3_transmitted = true;
|
|
|
|
|
|
|
|
if (transmitted_crnti) {
|
|
|
|
|
|
|
|
// Random Access with transmission of MAC C-RNTI CE
|
|
|
|
|
|
|
|
if ((!started_by_pdcch && pdcch_to_crnti_received == PDCCH_CRNTI_UL_GRANT) ||
|
|
|
|
|
|
|
|
(started_by_pdcch && pdcch_to_crnti_received != PDCCH_CRNTI_NOT_RECEIVED))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
rDebug("PDCCH for C-RNTI received\n");
|
|
|
|
|
|
|
|
contention_resolution_timer->stop();
|
|
|
|
|
|
|
|
state = COMPLETION;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
pdcch_to_crnti_received = PDCCH_CRNTI_NOT_RECEIVED;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// RA with transmission of CCCH SDU is resolved in contention_resolution_id_received() callback function
|
|
|
|
|
|
|
|
if (!transmitted_contention_id) {
|
|
|
|
|
|
|
|
// Save transmitted UE contention id, as defined by higher layers
|
|
|
|
|
|
|
|
transmitted_contention_id = rntis->contention_id;
|
|
|
|
|
|
|
|
rntis->contention_id = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
rDebug("Msg3 not yet transmitted\n");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ra_proc::step_completition()
|
|
|
|
/* Perform the actions upon completition of the RA procedure as defined in 5.1.6 */
|
|
|
|
|
|
|
|
void ra_proc::complete()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
/* Start looking for PDCCH CRNTI */
|
|
|
|
// Start looking for PDCCH CRNTI
|
|
|
|
|
|
|
|
if (!transmitted_crnti) {
|
|
|
|
if (!transmitted_crnti) {
|
|
|
|
rntis->crnti = rntis->temp_rnti;
|
|
|
|
rntis->crnti = rntis->temp_rnti;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
rntis->temp_rnti = 0;
|
|
|
|
rntis->temp_rnti = 0;
|
|
|
|
|
|
|
|
|
|
|
|
log_h->console("Random Access Complete. c-rnti=0x%x, ta=%d\n", rntis->crnti, current_ta);
|
|
|
|
mux_unit->msg3_flush();
|
|
|
|
rInfo("Random Access Complete. c-rnti=0x%x, ta=%d\n", rntis->crnti, current_ta);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!msg3_flushed) {
|
|
|
|
|
|
|
|
mux_unit->msg3_flush();
|
|
|
|
|
|
|
|
msg3_flushed = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
phy_h->set_crnti(rntis->crnti);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
msg3_transmitted = false;
|
|
|
|
msg3_transmitted = false;
|
|
|
|
state = COMPLETION_DONE;
|
|
|
|
|
|
|
|
if (ra_is_ho) {
|
|
|
|
if (ra_is_ho) {
|
|
|
|
rrc->ho_ra_completed(true);
|
|
|
|
rrc->ho_ra_completed(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log_h->console("Random Access Complete. c-rnti=0x%x, ta=%d\n", rntis->crnti, current_ta);
|
|
|
|
|
|
|
|
rInfo("Random Access Complete. c-rnti=0x%x, ta=%d\n", rntis->crnti, current_ta);
|
|
|
|
|
|
|
|
|
|
|
|
void ra_proc::step(uint32_t tti_)
|
|
|
|
state = COMPLETITION;
|
|
|
|
{
|
|
|
|
|
|
|
|
switch(state) {
|
|
|
|
|
|
|
|
case IDLE:
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case INITIALIZATION:
|
|
|
|
|
|
|
|
step_initialization();
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RESOURCE_SELECTION:
|
|
|
|
|
|
|
|
step_resource_selection();
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PREAMBLE_TRANSMISSION:
|
|
|
|
|
|
|
|
step_preamble_transmission();
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PDCCH_SETUP:
|
|
|
|
|
|
|
|
step_pdcch_setup();
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RESPONSE_RECEPTION:
|
|
|
|
|
|
|
|
step_response_reception(tti_);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RESPONSE_ERROR:
|
|
|
|
|
|
|
|
step_response_error(tti_);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BACKOFF_WAIT:
|
|
|
|
|
|
|
|
step_backoff_wait(tti_);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CONTENTION_RESOLUTION:
|
|
|
|
|
|
|
|
step_contention_resolution();
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case COMPLETION:
|
|
|
|
|
|
|
|
step_completition();
|
|
|
|
|
|
|
|
case COMPLETION_DONE:
|
|
|
|
|
|
|
|
case RA_PROBLEM:
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ra_proc::start_noncont(uint32_t preamble_index, uint32_t prach_mask) {
|
|
|
|
void ra_proc::start_noncont(uint32_t preamble_index, uint32_t prach_mask) {
|
|
|
@ -555,21 +515,25 @@ void ra_proc::start_noncont(uint32_t preamble_index, uint32_t prach_mask) {
|
|
|
|
|
|
|
|
|
|
|
|
void ra_proc::start_mac_order(uint32_t msg_len_bits, bool is_ho)
|
|
|
|
void ra_proc::start_mac_order(uint32_t msg_len_bits, bool is_ho)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (state == IDLE || state == COMPLETION_DONE || state == RA_PROBLEM) {
|
|
|
|
if (state == IDLE) {
|
|
|
|
ra_is_ho = is_ho;
|
|
|
|
ra_is_ho = is_ho;
|
|
|
|
started_by_pdcch = false;
|
|
|
|
started_by_pdcch = false;
|
|
|
|
new_ra_msg_len = msg_len_bits;
|
|
|
|
new_ra_msg_len = msg_len_bits;
|
|
|
|
state = INITIALIZATION;
|
|
|
|
|
|
|
|
rInfo("Starting PRACH by MAC order\n");
|
|
|
|
rInfo("Starting PRACH by MAC order\n");
|
|
|
|
|
|
|
|
initialization();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
Warning("Trying to start PRACH by MAC order in invalid state (%s)\n", state_str[state]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ra_proc::start_pdcch_order()
|
|
|
|
void ra_proc::start_pdcch_order()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (state == IDLE || state == COMPLETION_DONE || state == RA_PROBLEM) {
|
|
|
|
if (state == IDLE) {
|
|
|
|
started_by_pdcch = true;
|
|
|
|
started_by_pdcch = true;
|
|
|
|
state = INITIALIZATION;
|
|
|
|
|
|
|
|
rInfo("Starting PRACH by PDCCH order\n");
|
|
|
|
rInfo("Starting PRACH by PDCCH order\n");
|
|
|
|
|
|
|
|
initialization();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
Warning("Trying to start PRACH by MAC order in invalid state (%s)\n", state_str[state]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -577,29 +541,79 @@ void ra_proc::start_pdcch_order()
|
|
|
|
void ra_proc::timer_expired(uint32_t timer_id)
|
|
|
|
void ra_proc::timer_expired(uint32_t timer_id)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
rInfo("Contention Resolution Timer expired. Stopping PDCCH Search and going to Response Error\n");
|
|
|
|
rInfo("Contention Resolution Timer expired. Stopping PDCCH Search and going to Response Error\n");
|
|
|
|
bzero(rntis, sizeof(mac_interface_rrc::ue_rnti_t));
|
|
|
|
response_error();
|
|
|
|
state = RESPONSE_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Function called by MAC when a Contention Resolution ID CE is received.
|
|
|
|
|
|
|
|
* Performs the actions defined in 5.1.5 for Temporal C-RNTI Contention Resolution
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool ra_proc::contention_resolution_id_received(uint64_t rx_contention_id)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
bool uecri_successful = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rDebug("MAC PDU Contains Contention Resolution ID CE\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// MAC PDU successfully decoded and contains MAC CE contention Id
|
|
|
|
|
|
|
|
contention_resolution_timer->stop();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (transmitted_contention_id == rx_contention_id) {
|
|
|
|
|
|
|
|
// UE Contention Resolution ID included in MAC CE matches the CCCH SDU transmitted in Msg3
|
|
|
|
|
|
|
|
uecri_successful = true;
|
|
|
|
|
|
|
|
complete();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
rInfo("Transmitted UE Contention Id differs from received Contention ID (0x%lx != 0x%lx)\n",
|
|
|
|
|
|
|
|
transmitted_contention_id,
|
|
|
|
|
|
|
|
rx_contention_id);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Discard MAC PDU
|
|
|
|
|
|
|
|
uecri_successful = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Contention Resolution not successfully is like RAR not successful
|
|
|
|
|
|
|
|
response_error();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return uecri_successful;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ra_proc::pdcch_to_crnti(bool contains_uplink_grant) {
|
|
|
|
void ra_proc::pdcch_to_crnti(bool is_new_uplink_transmission)
|
|
|
|
rDebug("PDCCH to C-RNTI received %s UL dci\n", contains_uplink_grant ? "with" : "without");
|
|
|
|
{
|
|
|
|
if (contains_uplink_grant) {
|
|
|
|
rDebug("PDCCH to C-RNTI received %s new UL transmission\n", is_new_uplink_transmission ? "with" : "without");
|
|
|
|
pdcch_to_crnti_received = PDCCH_CRNTI_UL_GRANT;
|
|
|
|
if ((!started_by_pdcch && is_new_uplink_transmission) || started_by_pdcch) {
|
|
|
|
} else if (pdcch_to_crnti_received == PDCCH_CRNTI_NOT_RECEIVED) {
|
|
|
|
rDebug("PDCCH for C-RNTI received\n");
|
|
|
|
pdcch_to_crnti_received = PDCCH_CRNTI_DL_GRANT;
|
|
|
|
contention_resolution_timer->stop();
|
|
|
|
|
|
|
|
complete();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool ra_proc::update_rar_window(int* rar_window_start, int* rar_window_length)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (state == RESPONSE_RECEPTION) {
|
|
|
|
|
|
|
|
if (rar_window_length) {
|
|
|
|
|
|
|
|
*rar_window_length = rach_cfg.responseWindowSize;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rar_window_start) {
|
|
|
|
|
|
|
|
*rar_window_start = rar_window_st;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (rar_window_length) {
|
|
|
|
|
|
|
|
*rar_window_length = -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Restart timer at each Msg3 HARQ retransmission (5.1.5)
|
|
|
|
void ra_proc::harq_retx()
|
|
|
|
void ra_proc::harq_retx()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
rInfo("Restarting ContentionResolutionTimer=%d ms\n", contention_resolution_timer->get_timeout());
|
|
|
|
contention_resolution_timer->reset();
|
|
|
|
contention_resolution_timer->reset();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ra_proc::harq_max_retx()
|
|
|
|
void ra_proc::harq_max_retx()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Warning("Contention Resolution is considered not successful. Stopping PDCCH Search and going to Response Error\n");
|
|
|
|
Warning("Contention Resolution is considered not successful. Stopping PDCCH Search and going to Response Error\n");
|
|
|
|
bzero(rntis, sizeof(mac_interface_rrc::ue_rnti_t));
|
|
|
|
response_error();
|
|
|
|
state = RESPONSE_ERROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|