Commit f09ee3e5 authored by cig's avatar cig

Cleanup and review of RA procedure after Msg3 transmission

- related to section 5 of 3GPP TS 38.321 specs
- handling of RA failure
- handling of RA completion
- first implementation of contention-based RA procedures
- minor fixes related to ue_get_rach and init_ra functions
parent 2e8e9b7d
......@@ -899,27 +899,6 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
return 0;
}
// if contention resolution fails, go back to UE mode PRACH
void nr_ra_failed(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index) {
PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
ue->UE_mode[gNB_index] = PRACH;
for (int i=0; i <RX_NB_TH_MAX; i++ ) {
ue->pdcch_vars[i][gNB_index]->pdcch_config[0].rnti = 0;
}
LOG_E(PHY,"[UE %d] [RAPROC] Random-access procedure fails, going back to PRACH\n", Mod_id);
}
void nr_ra_succeeded(uint8_t Mod_id,
uint8_t CC_id,
uint8_t gNB_index){
LOG_I(PHY,"[UE %d][RAPROC] RA procedure succeeded. UE set to PUSCH mode\n", Mod_id);
PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
ue->ulsch_Msg3_active[gNB_index] = 0;
ue->UE_mode[gNB_index] = PUSCH;
}
void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
int eNB_id,
......@@ -2159,7 +2138,7 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
}
}
nr_prach = nr_ue_get_rach(ue->prach_resources[gNB_id], &ue->prach_vars[0]->prach_pdu, mod_id, ue->CC_id, UE_mode, frame_tx, gNB_id, nr_slot_tx);
nr_prach = nr_ue_get_rach(ue->prach_resources[gNB_id], &ue->prach_vars[0]->prach_pdu, mod_id, ue->CC_id, frame_tx, gNB_id, nr_slot_tx);
if (ue->prach_resources[gNB_id] != NULL && nr_prach == 1 && prach_resources->init_msg1) {
......@@ -2210,8 +2189,20 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
if (ue->prach_cnt == 3)
ue->prach_cnt = 0;
} else if (nr_prach == 2) {
nr_ra_succeeded(mod_id, ue->CC_id, gNB_id);
LOG_D(PHY, "In %s: [UE %d] RA completed, setting UE mode to PUSCH\n", __FUNCTION__, mod_id);
ue->ulsch_Msg3_active[gNB_id] = 0;
ue->UE_mode[gNB_id] = PUSCH;
} else if(nr_prach == 3){
LOG_D(PHY, "In %s: [UE %d] RA failed, setting UE mode to PRACH\n", __FUNCTION__, mod_id);
ue->UE_mode[gNB_id] = PRACH;
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
}
......@@ -36,7 +36,6 @@
#include "NR_CellGroupConfig.h"
#include "nr_mac.h"
// ===============================================
// SSB to RO mapping public defines and structures
// ===============================================
......@@ -47,6 +46,8 @@
// Definitions for MAC control and data
#define MAX_BWP_SIZE 275
extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
typedef enum frequency_range_e {
FR1 = 0,
FR2
......
......@@ -198,6 +198,8 @@ typedef struct {
/* Random Access parameters */
/// state of RA procedure
RA_state_t ra_state;
/// RA contention type
uint8_t cfra;
/// RA rx frame offset: compensate RA rx offset introduced by OAI gNB.
uint8_t RA_offset;
/// RA-rnti
......
......@@ -233,11 +233,11 @@ void nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
void nr_process_rar(nr_downlink_indication_t *dl_info);
void ue_contention_resolution(module_id_t module_id, uint8_t gNB_index, int cc_id, frame_t tx_frame);
void nr_ue_contention_resolution(module_id_t module_id, int cc_id, frame_t frame, int slot, NR_PRACH_RESOURCES_t *prach_resources);
void nr_ra_failed(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index);
void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_resources, frame_t frame, int slot);
void nr_ra_succeeded(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index);
void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot);
/* \brief Function called by PHY to retrieve information to be transmitted using the RA procedure.
If the UE is not in PUSCH mode for a particular eNB index, this is assumed to be an Msg3 and MAC
......@@ -254,7 +254,6 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
fapi_nr_ul_config_prach_pdu *prach_pdu,
module_id_t mod_id,
int CC_id,
UE_MODE_t UE_mode,
frame_t frame,
uint8_t gNB_id,
int nr_slot_tx);
......
......@@ -49,9 +49,6 @@
#include "NR_MAC_COMMON/nr_mac.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
//extern uint8_t nfapi_mode;
static uint8_t first_Msg3 = 0;
static int starting_preamble_nb = 0;
static long cb_preambles_per_ssb; // Nb of preambles per SSB
......@@ -74,6 +71,10 @@ void init_RA(module_id_t mod_id,
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric,
NR_RACH_ConfigDedicated_t *rach_ConfigDedicated) {
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
mac->RA_active = 1;
mac->RA_RAPID_found = 0;
prach_resources->RA_PREAMBLE_BACKOFF = 0;
prach_resources->RA_PCMAX = nr_get_Pcmax(mod_id);
prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
......@@ -85,6 +86,7 @@ void init_RA(module_id_t mod_id,
if (rach_ConfigDedicated->cfra){
LOG_I(MAC, "Initialization of 4-step contention-free random access procedure\n");
prach_resources->RA_TYPE = RA_4STEP;
mac->cfra = 1;
}
} else if (rach_ConfigDedicated->ext1){
if (rach_ConfigDedicated->ext1->cfra_TwoStep_r16){
......@@ -449,11 +451,16 @@ void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint
}
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
LOG_D(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Starting contention resolution timer\n", mod_id, frameP);
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
LOG_D(MAC,"In %s: [UE %d] Frame %d, CB-RA: starting contention resolution timer\n", __FUNCTION__, mod_id, frameP);
// start contention resolution timer
mac->RA_contention_resolution_cnt = 0;
mac->RA_contention_resolution_cnt = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1) * 8;
mac->RA_contention_resolution_timer_active = 1;
}
/////////////////////////////////////////////////////////////////////////
......@@ -476,7 +483,6 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
fapi_nr_ul_config_prach_pdu *prach_pdu,
module_id_t mod_id,
int CC_id,
UE_MODE_t UE_mode,
frame_t frame,
uint8_t gNB_id,
int nr_slot_tx){
......@@ -538,9 +544,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
LOG_D(MAC, "[UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", mod_id, frame, nr_slot_tx);
mac->RA_active = 1;
mac->RA_RAPID_found = 0;
first_Msg3 = 0;
first_Msg3 = 1;
RA_backoff_cnt = 0;
Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT);
......@@ -584,46 +588,15 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
if (mac->RA_window_cnt >= 0 && mac->RA_RAPID_found == 1) {
// Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213)
// TbD Msg3 Retransmissions to be scheduled by DCI 0_0
if (rach_ConfigDedicated) {
if (rach_ConfigDedicated->cfra){
// CFRA
mac->RA_active = 0;
mac->RA_window_cnt = -1;
mac->ra_state = RA_SUCCEEDED;
mac->generate_nr_prach = 2;
LOG_I(MAC, "[UE %d][%d.%d] RAR successfully received\n", mod_id, frame, nr_slot_tx);
nr_ra_succeeded(mod_id, frame, nr_slot_tx);
}
} else {
LOG_E(MAC, "[%s:%d][UE %d] todo: handling of received contention-based RA praemble...\n", __FUNCTION__, __LINE__, mod_id);
}
} else if (mac->RA_window_cnt == 0 && !mac->RA_RAPID_found) {
LOG_I(MAC, "[UE %d][%d:%d] RAR reception failed \n", mod_id, frame, nr_slot_tx);
mac->ra_state = RA_UE_IDLE;
prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER++;
if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax + 1){
LOG_D(MAC, "[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n", mod_id, frame, preambleTransMax);
RA_backoff_cnt = rand() % (prach_resources->RA_PREAMBLE_BACKOFF + 1);
prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP += 2; // 2 dB increment
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id);
} else {
// Resetting RA window
nr_get_RA_window(mac);
nr_ra_failed(mod_id, CC_id, prach_resources, frame, nr_slot_tx);
}
} else if (mac->RA_window_cnt > 0) {
LOG_D(MAC, "[UE %d][%d.%d]: RAR not received yet (RA window count %d) \n", mod_id, frame, nr_slot_tx, mac->RA_window_cnt);
......@@ -644,10 +617,10 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
}
}
} else if (UE_mode == PUSCH) {
AssertFatal(1 == 0, "[UE %d] FATAL: Should not have checked for RACH in PUSCH yet...", mod_id);
}
if (mac->RA_contention_resolution_timer_active){
nr_ue_contention_resolution(mod_id, CC_id, frame, nr_slot_tx, prach_resources);
}
return mac->generate_nr_prach;
......@@ -698,3 +671,107 @@ void nr_get_RA_window(NR_UE_MAC_INST_t *mac){
break;
}
}
////////////////////////////////////////////////////////////////////////////
/////////* Random Access Contention Resolution (5.1.35 TS 38.321) */////////
////////////////////////////////////////////////////////////////////////////
// Handling contention resolution timer
// WIP todo:
// - beam failure recovery
// - RA completed
void nr_ue_contention_resolution(module_id_t module_id, int cc_id, frame_t frame, int slot, NR_PRACH_RESOURCES_t *prach_resources){
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
if (mac->RA_contention_resolution_timer_active == 1) {
mac->RA_contention_resolution_cnt--;
LOG_D(MAC, "In %s: [%d.%d] RA contention resolution timer %d\n", __FUNCTION__, frame, slot, mac->RA_contention_resolution_cnt);
if (mac->RA_contention_resolution_cnt == 0) {
mac->t_crnti = 0;
mac->RA_active = 0;
mac->RA_contention_resolution_timer_active = 0;
// Signal PHY to quit RA procedure
LOG_E(MAC, "[UE %d] CB-RA: Contention resolution timer has expired, RA procedure has failed...\n", module_id);
nr_ra_failed(module_id, cc_id, prach_resources, frame, slot);
}
}
}
// Handlig successful RA completion @ MAC layer
// according to section 5 of 3GPP TS 38.321 version 16.2.1 Release 16
// todo:
// - complete handling of received contention-based RA preamble
void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
if (mac->cfra) {
LOG_I(MAC, "[UE %d][%d.%d] CF-RA: RAR successfully received, RA procedure is completed\n", mod_id, frame, slot);
mac->RA_window_cnt = -1;
} else {
LOG_I(MAC, "[UE %d][%d.%d] CB-RA: Contention Resolution is successful, RA is completed\n", mod_id, frame, slot);
mac->RA_contention_resolution_cnt = -1;
mac->RA_contention_resolution_timer_active = 0;
mac->t_crnti = 0;
LOG_D(MAC, "In %s: [UE %d][%d.%d] CB-RA: cleared contention resolution timer...\n", __FUNCTION__, mod_id, frame, slot);
}
LOG_D(MAC, "In %s: [UE %d] clearing RA_active flag...\n", __FUNCTION__, mod_id);
ra->RA_active = 0;
ra->generate_nr_prach = 2;
ra->ra_state = RA_SUCCEEDED;
}
// Handlig failure of RA procedure @ MAC layer
// according to section 5 of 3GPP TS 38.321 version 16.2.1 Release 16
// todo:
// - complete handling of received contention-based RA preamble
// - 2-step RA implementation
void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_resources, frame_t frame, int slot) {
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
first_Msg3 = 0;
mac->generate_nr_prach = 3;
mac->ra_state = RA_UE_IDLE;
prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER++;
if(prach_resources->RA_TYPE == RA_4STEP){
if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax + 1){
LOG_D(MAC, "In %s: [UE %d][%d.%d] Maximum number of RACH attempts (%d) reached, selecting backoff time...\n", __FUNCTION__, mod_id, frame, slot, preambleTransMax);
RA_backoff_cnt = rand() % (prach_resources->RA_PREAMBLE_BACKOFF + 1);
prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP += 2; // 2 dB increment
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id);
} else {
// Resetting RA window
nr_get_RA_window(mac);
}
} else if (prach_resources->RA_TYPE == RA_2STEP){
LOG_E(MAC, "Missing implementation of RA failure handling for 2-step RA...\n");
}
}
......@@ -1368,7 +1368,72 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
module_id_t mod_id = ul_info->module_id;
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
if (mac->ra_state == RA_SUCCEEDED || get_softmodem_params()->phy_test) {
if (mac->ra_state == WAIT_RAR){
if (mac->RA_active && ul_info->slot_tx == mac->msg3_slot && ul_info->frame_tx == mac->msg3_frame){
uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
nr_scheduled_response_t scheduled_response;
fapi_nr_tx_request_t tx_req;
//fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, ul_info->slot_tx);
fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request[0];
fapi_nr_ul_config_request_pdu_t *ul_config_list = &ul_config->ul_config_list[ul_config->number_pdus];
uint16_t TBS_bytes = ul_config_list->pusch_config_pdu.pusch_data.tb_size;
//if (IS_SOFTMODEM_NOS1){
// // Getting IP traffic to be transmitted
// data_existing = nr_ue_get_sdu(mod_id,
// cc_id,
// frame_tx,
// slot_tx,
// 0,
// ulsch_input_buffer,
// TBS_bytes,
// &access_mode);
//}
//Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
//if (!IS_SOFTMODEM_NOS1 || !data_existing) {
//Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
//and block this traffic from being forwarded to the upper layers at the gNB
LOG_D(MAC, "Random data to be tranmsitted (TBS_bytes %d): \n", TBS_bytes);
//Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2)
//in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should
//have a valid LCID (nr_process_mac_pdu function)
ulsch_input_buffer[0] = 0x31;
for (int i = 1; i < TBS_bytes; i++) {
ulsch_input_buffer[i] = (unsigned char) rand();
//printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
}
//}
LOG_D(MAC, "[UE %d] Frame %d, Subframe %d Adding Msg3 UL Config Request for rnti: %x\n",
ul_info->module_id,
ul_info->frame_tx,
ul_info->slot_tx,
mac->t_crnti);
// Config UL TX PDU
tx_req.slot = ul_info->slot_tx;
tx_req.sfn = ul_info->frame_tx;
tx_req.number_of_pdus = 1;
tx_req.tx_request_body[0].pdu_length = TBS_bytes;
tx_req.tx_request_body[0].pdu_index = 0;
tx_req.tx_request_body[0].pdu = ulsch_input_buffer;
ul_config_list->pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
ul_config->number_pdus++;
// scheduled_response
fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, ul_info->module_id, ul_info->cc_id, ul_info->frame_rx, ul_info->slot_rx, ul_info->thread_id);
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
mac->if_module->scheduled_response(&scheduled_response);
}
if (!mac->cfra){
nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->gNB_index);
}
}
} else if (mac->ra_state == RA_SUCCEEDED || get_softmodem_params()->phy_test) {
uint8_t nb_dmrs_re_per_rb;
uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
......@@ -1512,75 +1577,6 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
mac->if_module->scheduled_response(&scheduled_response);
}
// TODO: expand
// Note: Contention resolution is currently not active
if (mac->RA_contention_resolution_timer_active == 1)
ue_contention_resolution(mod_id, gNB_index, cc_id, ul_info->frame_tx);
}
} else if (get_softmodem_params()->do_ra){
NR_UE_MAC_INST_t *mac = get_mac_inst(ul_info->module_id);
if (mac->RA_active && ul_info->slot_tx == mac->msg3_slot && ul_info->frame_tx == mac->msg3_frame){
uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
nr_scheduled_response_t scheduled_response;
fapi_nr_tx_request_t tx_req;
//fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, ul_info->slot_tx);
fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request[0];
fapi_nr_ul_config_request_pdu_t *ul_config_list = &ul_config->ul_config_list[ul_config->number_pdus];
uint16_t TBS_bytes = ul_config_list->pusch_config_pdu.pusch_data.tb_size;
//if (IS_SOFTMODEM_NOS1){
// // Getting IP traffic to be transmitted
// data_existing = nr_ue_get_sdu(mod_id,
// cc_id,
// frame_tx,
// slot_tx,
// 0,
// ulsch_input_buffer,
// TBS_bytes,
// &access_mode);
//}
//Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
//if (!IS_SOFTMODEM_NOS1 || !data_existing) {
//Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
//and block this traffic from being forwarded to the upper layers at the gNB
LOG_D(MAC, "Random data to be tranmsitted (TBS_bytes %d): \n", TBS_bytes);
//Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2)
//in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should
//have a valid LCID (nr_process_mac_pdu function)
ulsch_input_buffer[0] = 0x31;
for (int i = 1; i < TBS_bytes; i++) {
ulsch_input_buffer[i] = (unsigned char) rand();
//printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
}
//}
LOG_D(MAC, "[UE %d] Frame %d, Subframe %d Adding Msg3 UL Config Request for rnti: %x\n",
ul_info->module_id,
ul_info->frame_tx,
ul_info->slot_tx,
mac->t_crnti);
// Config UL TX PDU
tx_req.slot = ul_info->slot_tx;
tx_req.sfn = ul_info->frame_tx;
tx_req.number_of_pdus = 1;
tx_req.tx_request_body[0].pdu_length = TBS_bytes;
tx_req.tx_request_body[0].pdu_index = 0;
tx_req.tx_request_body[0].pdu = ulsch_input_buffer;
ul_config_list->pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
ul_config->number_pdus++;
// scheduled_response
fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, ul_info->module_id, ul_info->cc_id, ul_info->frame_rx, ul_info->slot_rx, ul_info->thread_id);
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
mac->if_module->scheduled_response(&scheduled_response);
}
}
}
}
......@@ -1766,40 +1762,6 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
} // if is_nr_UL_slot
}
////////////////////////////////////////////////////////////////////////////
/////////* Random Access Contention Resolution (5.1.35 TS 38.321) */////////
////////////////////////////////////////////////////////////////////////////
// Handling contention resolution timer
// WIP todo:
// - beam failure recovery
// - RA completed
void ue_contention_resolution(module_id_t module_id, uint8_t gNB_index, int cc_id, frame_t tx_frame){
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
NR_ServingCellConfigCommon_t *scc = mac->scc;
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
if (mac->RA_contention_resolution_timer_active == 1) {
if (nr_rach_ConfigCommon){
LOG_I(MAC, "Frame %d: Contention resolution timer %d/%ld\n",
tx_frame,
mac->RA_contention_resolution_cnt,
((1 + nr_rach_ConfigCommon->ra_ContentionResolutionTimer) << 3));
mac->RA_contention_resolution_cnt++;
if (mac->RA_contention_resolution_cnt == ((1 + nr_rach_ConfigCommon->ra_ContentionResolutionTimer) << 3)) {
mac->t_crnti = 0;
mac->RA_active = 0;
mac->RA_contention_resolution_timer_active = 0;
// Signal PHY to quit RA procedure
LOG_E(MAC, "[UE %u] [RAPROC] Contention resolution timer expired, RA failed, discarded TC-RNTI\n", module_id);
nr_ra_failed(module_id, cc_id, gNB_index);
}
}
}
}
/*
* This code contains all the functions needed to process all dci fields.
* These tables and functions are going to be called by function nr_ue_process_dci
......@@ -2505,6 +2467,18 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
/* TIME_DOM_RESOURCE_ASSIGNMENT */
if (nr_ue_process_dci_time_dom_resource_assignment(mac,pusch_config_pdu_0_0,NULL,dci->time_domain_assignment.val) < 0)
return -1;
LOG_D(MAC, "In %s: received UL grant (rb_start %d, rb_size %d, start_symbol_index %d, nr_of_symbols %d) \n",
__FUNCTION__,
pusch_config_pdu_0_0->rb_start,
pusch_config_pdu_0_0->rb_size,
pusch_config_pdu_0_0->start_symbol_index,
pusch_config_pdu_0_0->nr_of_symbols);
if (mac->RA_active && mac->crnti){
nr_ra_succeeded(module_id, frame, slot);
}
/* FREQ_HOPPING_FLAG */
if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.resource_allocation != 0) &&
(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.frequency_hopping !=0))
......@@ -2627,6 +2601,18 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
/* TIME_DOM_RESOURCE_ASSIGNMENT */
if (nr_ue_process_dci_time_dom_resource_assignment(mac,pusch_config_pdu_0_1,NULL,dci->time_domain_assignment.val) < 0)
return -1;
LOG_D(MAC, "In %s: received UL grant (rb_start %d, rb_size %d, start_symbol_index %d, nr_of_symbols %d) \n",
__FUNCTION__,
pusch_config_pdu_0_1->rb_start,
pusch_config_pdu_0_1->rb_size,
pusch_config_pdu_0_1->start_symbol_index,
pusch_config_pdu_0_1->nr_of_symbols);
if (mac->RA_active && mac->crnti){
nr_ra_succeeded(module_id, frame, slot);
}
/* FREQ_HOPPING_FLAG */
if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.resource_allocation != 0) &&
(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.frequency_hopping !=0))
......@@ -4164,35 +4150,16 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
break;
case DL_SCH_LCID_CON_RES_ID:
// 38.321 Ch6.1.3.3
// Clause 5.1.5 and 6.1.3.3 of 3GPP TS 38.321 version 16.2.1 Release 16
// WIP todo: handle CCCH_pdu
mac_ce_len = 6;
LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution msg: %x.%x.%x.%x.%x.%x, Terminating RA procedure\n", module_idP, frameP, pduP[0], pduP[1], pduP[2], pduP[3], pduP[4], pduP[5]);
if (mac->RA_active == 1) {
LOG_I(MAC, "[UE %d][RAPROC] Frame %d : Clearing RA_active flag\n", module_idP, frameP);
mac->RA_active = 0;
// // check if RA procedure has finished completely (no contention)
// tx_sdu = &mac->CCCH_pdu.payload[3];
// //Note: 3 assumes sizeof(SCH_SUBHEADER_SHORT) + PADDING CE, which is when UL-Grant has TBS >= 9 (64 bits)
// // (other possibility is 1 for TBS=7 (SCH_SUBHEADER_FIXED), or 2 for TBS=8 (SCH_SUBHEADER_FIXED+PADDING or // SCH_SUBHEADER_SHORT)
// for (i = 0; i < 6; i++)
// if (tx_sdu[i] != payload_ptr[i]) {
// LOG_E(MAC, "[UE %d][RAPROC] Contention detected, RA failed\n", module_idP);
// nr_ra_failed(module_idP, CC_id, eNB_index);
// mac->RA_contention_resolution_timer_active = 0;
// return;
// }
LOG_I(MAC, "[UE %d][RAPROC] Frame %d : Cleared contention resolution timer. Set C-RNTI to TC-RNTI\n",
module_idP,
frameP);
mac->RA_contention_resolution_timer_active = 0;
nr_ra_succeeded(module_idP, CC_id, gNB_index);
mac->crnti = mac->t_crnti;
mac->t_crnti = 0;
mac->ra_state = RA_SUCCEEDED;
nr_ra_succeeded(module_idP, frameP, slot);
}
break;
case DL_SCH_LCID_PADDING:
done = 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment