Commit e4a6d60d authored by francescomani's avatar francescomani

implementation of time alignment timer at MAC UE

parent 25b94f12
......@@ -1545,6 +1545,42 @@ static void configure_common_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Up
}
}
static void configure_timeAlignmentTimer(NR_timer_t *time_alignment_timer, NR_TimeAlignmentTimer_t timer_config, int scs)
{
uint32_t timer_ms = 0;
switch (timer_config) {
case NR_TimeAlignmentTimer_ms500 :
timer_ms = 500;
break;
case NR_TimeAlignmentTimer_ms750 :
timer_ms = 750;
break;
case NR_TimeAlignmentTimer_ms1280 :
timer_ms = 1280;
break;
case NR_TimeAlignmentTimer_ms1920 :
timer_ms = 1920;
break;
case NR_TimeAlignmentTimer_ms2560 :
timer_ms = 2560;
break;
case NR_TimeAlignmentTimer_ms5120 :
timer_ms = 5120;
break;
case NR_TimeAlignmentTimer_ms10240 :
timer_ms = 10240;
break;
case NR_TimeAlignmentTimer_infinity :
timer_ms = UINT_MAX;
break;
default :
AssertFatal(false, "Invalid timeAlignmentTimer\n");
}
// length of slot is (1/2^scs)ms
uint32_t n_slots = timer_ms != UINT_MAX ? (timer_ms << scs) : UINT_MAX;
nr_timer_setup(time_alignment_timer, n_slots, 1); // 1 slot update rate
}
void nr_rrc_mac_config_req_reset(module_id_t module_id,
NR_UE_MAC_reset_cause_t cause)
{
......@@ -1577,6 +1613,8 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id,
nr_ue_mac_default_configs(mac);
nr_ue_reset_sync_state(mac);
release_mac_configuration(mac, cause);
// apply the timeAlignmentTimerCommon included in SIB1
configure_timeAlignmentTimer(&mac->time_alignment_timer, mac->timeAlignmentTimerCommon, mac->current_UL_BWP->scs);
// new sync with old cell ID (re-establishment on the same cell)
sync_req.target_Nid_cell = mac->physCellId;
sync_req.ssb_bw_scan = false;
......@@ -1636,6 +1674,7 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id,
AssertFatal(mac->current_DL_BWP, "Couldn't find DL-BWP0\n");
mac->current_UL_BWP = get_ul_bwp_structure(mac, 0, false);
AssertFatal(mac->current_UL_BWP, "Couldn't find DL-BWP0\n");
configure_timeAlignmentTimer(&mac->time_alignment_timer, mac->timeAlignmentTimerCommon, mac->current_UL_BWP->scs);
}
// Setup the SSB to Rach Occasions mapping according to the config
......@@ -2476,6 +2515,12 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id,
if (cell_group_config->mac_CellGroupConfig)
configure_maccellgroup(mac, cell_group_config->mac_CellGroupConfig);
for (int j = 0; j < mac->TAG_list.count; j++) {
// apply the Timing Advance Command for the indicated TAG
if (mac->TAG_list.array[j]->tag_Id == mac->tag_Id)
configure_timeAlignmentTimer(&mac->time_alignment_timer, mac->TAG_list.array[j]->timeAlignmentTimer, mac->current_UL_BWP->scs);
}
configure_logicalChannelBearer(mac,
cell_group_config->rlc_BearerToAddModList,
cell_group_config->rlc_BearerToReleaseList);
......
......@@ -596,6 +596,7 @@ typedef struct NR_UE_MAC_INST_s {
NR_TAG_Id_t tag_Id;
A_SEQUENCE_OF(NR_TAG_t) TAG_list;
NR_TimeAlignmentTimer_t timeAlignmentTimerCommon;
NR_timer_t time_alignment_timer;
nr_emulated_l1_t nr_ue_emul_l1;
......
......@@ -350,7 +350,7 @@ void schedule_RA_after_SR_failure(NR_UE_MAC_INST_t *mac);
void nr_Msg1_transmitted(NR_UE_MAC_INST_t *mac);
void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id);
void nr_get_msg3_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max);
void handle_time_alignment_timer_expired(NR_UE_MAC_INST_t *mac);
int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
NR_PDSCH_Config_t *pdsch_Config,
......
......@@ -202,6 +202,7 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac)
}
if (nr_mac->data_inactivity_timer)
nr_timer_stop(nr_mac->data_inactivity_timer);
nr_timer_stop(&nr_mac->time_alignment_timer);
nr_timer_stop(&nr_mac->ra.contention_resolution_timer);
nr_timer_stop(&nr_mac->scheduling_info.sr_DelayTimer);
nr_timer_stop(&nr_mac->scheduling_info.retxBSR_Timer);
......@@ -209,7 +210,7 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac)
nr_timer_stop(&nr_mac->scheduling_info.sr_info[i].prohibitTimer);
// consider all timeAlignmentTimers as expired and perform the corresponding actions in clause 5.2
// TODO
handle_time_alignment_timer_expired(nr_mac);
// set the NDIs for all uplink HARQ processes to the value 0
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++)
......
......@@ -912,9 +912,14 @@ void nr_ra_failed(NR_UE_MAC_INST_t *mac, uint8_t CC_id, NR_PRACH_RESOURCES_t *pr
prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER++;
if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER == ra->preambleTransMax + 1){
// when the Contention Resolution is considered not successful
// stop timeAlignmentTimer
nr_timer_stop(&mac->time_alignment_timer);
LOG_D(MAC, "[UE %d][%d.%d] Maximum number of RACH attempts (%d) reached, selecting backoff time...\n",
if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER == ra->preambleTransMax + 1) {
LOG_D(NR_MAC,
"[UE %d][%d.%d] Maximum number of RACH attempts (%d) reached, selecting backoff time...\n",
mac->ue_id,
frame,
slot,
......
......@@ -2953,8 +2953,11 @@ void nr_ue_send_sdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info, in
{
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN);
LOG_D(MAC, "In [%d.%d] Handling DLSCH PDU type %d\n",
dl_info->frame, dl_info->slot, dl_info->rx_ind->rx_indication_body[pdu_id].pdu_type);
LOG_D(NR_MAC,
"In [%d.%d] Handling DLSCH PDU type %d\n",
dl_info->frame,
dl_info->slot,
dl_info->rx_ind->rx_indication_body[pdu_id].pdu_type);
// Processing MAC PDU
// it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs
......@@ -2969,10 +2972,9 @@ void nr_ue_send_sdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info, in
case FAPI_NR_RX_PDU_TYPE_RAR :
nr_ue_process_rar(mac, dl_info, pdu_id);
break;
default:
AssertFatal(false, "Invalid PDU type\n");
default :
AssertFatal(false, "Invalid DLSCH PDU type\n");
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
}
......@@ -3412,6 +3414,21 @@ static nr_dci_format_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
return format;
}
static void set_time_alignment(NR_UE_MAC_INST_t *mac, int ta, ta_type_t type, int frame, int slot)
{
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment;
ul_time_alignment->ta_command = ta;
ul_time_alignment->ta_apply = type;
const int ntn_ue_koffset = get_NTN_UE_Koffset(mac->sc_info.ntn_Config_r17, mac->current_UL_BWP->scs);
const int n_slots_frame = nr_slots_per_frame[mac->current_UL_BWP->scs];
ul_time_alignment->frame = (frame + (slot + ntn_ue_koffset) / n_slots_frame) % MAX_FRAME_NUMBER;
ul_time_alignment->slot = (slot + ntn_ue_koffset) % n_slots_frame;
// start or restart the timeAlignmentTimer associated with the indicated TAG
nr_timer_start(&mac->time_alignment_timer);
}
///////////////////////////////////
// brief: nr_ue_process_mac_pdu
// function: parsing DL PDU header
......@@ -3572,20 +3589,7 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i
break;
}
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment;
ul_time_alignment->ta_command = ta;
ul_time_alignment->ta_apply = adjustment_ta;
const int ntn_ue_koffset = get_NTN_UE_Koffset(mac->sc_info.ntn_Config_r17, mac->current_UL_BWP->scs);
const int n_slots_frame = nr_slots_per_frame[mac->current_UL_BWP->scs];
ul_time_alignment->frame = (frameP + (slot + ntn_ue_koffset) / n_slots_frame) % MAX_FRAME_NUMBER;
ul_time_alignment->slot = (slot + ntn_ue_koffset) % n_slots_frame;
/*
#ifdef DEBUG_HEADER_PARSING
LOG_D(MAC, "[UE] CE %d : UE Timing Advance : %d\n", i, pduP[1]);
#endif
*/
set_time_alignment(mac, ta, adjustment_ta, frameP, slot);
if (ta == 31)
LOG_D(NR_MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d \n", frameP, slot, ta, tag, CC_id);
......@@ -3934,13 +3938,15 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d
}
}
#ifdef DEBUG_RAR
LOG_D(MAC, "[DEBUG_RAR] (%d,%d) number of RAR subheader %d; number of RAR pyloads %d\n",
#ifdef DEBUG_RAR
LOG_D(NR_MAC,
"[DEBUG_RAR] (%d,%d) number of RAR subheader %d; number of RAR pyloads %d\n",
frame,
slot,
n_subheaders,
n_subPDUs);
LOG_D(MAC, "[DEBUG_RAR] Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n",
LOG_D(NR_MAC,
"[DEBUG_RAR] Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n",
*(uint8_t *) rarh,
rar[0],
rar[1],
......@@ -3950,30 +3956,18 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d
rar[5],
rarh->RAPID,
preamble_index);
#endif
#endif
if (ra->RA_RAPID_found) {
RAR_grant_t rar_grant;
unsigned char tpc_command;
#ifdef DEBUG_RAR
unsigned char csi_req;
#endif
// TA command
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment;
const int ta = rar->TA2 + (rar->TA1 << 5);
ul_time_alignment->ta_command = ta;
ul_time_alignment->ta_apply = rar_ta;
LOG_W(MAC, "received TA command %d\n", 31 + ta);
#ifdef DEBUG_RAR
// CSI
csi_req = (unsigned char) (rar->UL_GRANT_4 & 0x01);
unsigned char csi_req = (unsigned char) (rar->UL_GRANT_4 & 0x01);
#endif
// TPC
tpc_command = (unsigned char) ((rar->UL_GRANT_4 >> 1) & 0x07);
unsigned char tpc_command = (unsigned char) ((rar->UL_GRANT_4 >> 1) & 0x07);
switch (tpc_command){
case 0:
ra->Msg3_TPC = -6;
......@@ -4011,6 +4005,31 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d
// frequency hopping
rar_grant.freq_hopping = (unsigned char) (rar->UL_GRANT_1 >> 2);
// Schedule Msg3
const NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
const NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP;
const NR_BWP_PDCCH_t *pdcch_config = &mac->config_BWP_PDCCH[current_DL_BWP->bwp_id];
NR_tda_info_t tda_info = get_ul_tda_info(current_UL_BWP,
*pdcch_config->ra_SS->controlResourceSetId,
pdcch_config->ra_SS->searchSpaceType->present,
TYPE_RA_RNTI_,
rar_grant.Msg3_t_alloc);
if (!tda_info.valid_tda || tda_info.nrOfSymbols == 0) {
LOG_E(MAC, "Cannot schedule Msg3. Something wrong in TDA information\n");
return;
}
const int ntn_ue_koffset = get_NTN_UE_Koffset(mac->sc_info.ntn_Config_r17, mac->current_UL_BWP->scs);
ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset);
// TA command
// if the timeAlignmentTimer associated with this TAG is not running
if (!nr_timer_is_active(&mac->time_alignment_timer)) {
const int ta = rar->TA2 + (rar->TA1 << 5);
set_time_alignment(mac, ta, rar_ta, frame_tx, slot_tx);
LOG_W(MAC, "received TA command %d\n", 31 + ta);
}
// else ignore the received Timing Advance Command
#ifdef DEBUG_RAR
LOG_I(NR_MAC, "rarh->E = 0x%x\n", rarh->E);
LOG_I(NR_MAC, "rarh->T = 0x%x\n", rarh->T);
......@@ -4041,26 +4060,6 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d
tpc_command);
#endif
// Schedule Msg3
const NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
const NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP;
const NR_BWP_PDCCH_t *pdcch_config = &mac->config_BWP_PDCCH[current_DL_BWP->bwp_id];
NR_tda_info_t tda_info = get_ul_tda_info(current_UL_BWP,
*pdcch_config->ra_SS->controlResourceSetId,
pdcch_config->ra_SS->searchSpaceType->present,
TYPE_RA_RNTI_,
rar_grant.Msg3_t_alloc);
if (!tda_info.valid_tda || tda_info.nrOfSymbols == 0) {
LOG_E(MAC, "Cannot schedule Msg3. Something wrong in TDA information\n");
return;
}
const int ntn_ue_koffset = get_NTN_UE_Koffset(mac->sc_info.ntn_Config_r17, mac->current_UL_BWP->scs);
ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset);
const int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs];
ul_time_alignment->frame = (frame_tx + (slot_tx + ntn_ue_koffset) / n_slots_frame) % MAX_FRAME_NUMBER;
ul_time_alignment->slot = (slot_tx + ntn_ue_koffset) % n_slots_frame;
if (ret != -1) {
uint16_t rnti = mac->crnti;
// Upon successful reception, set the T-CRNTI to the RAR value if the RA preamble is selected among the contention-based RA Preambles
......@@ -4090,6 +4089,9 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d
} else {
ra->t_crnti = 0;
// TODO if the Random Access Preamble was not selected by the MAC entity
// among the contention-based Random Access Preamble
// apply the Timing Advance Command and start or restart the timeAlignmentTimer
}
return;
}
......
......@@ -152,6 +152,30 @@ static void trigger_regular_bsr(NR_UE_MAC_INST_t *mac, NR_LogicalChannelIdentity
nr_timer_stop(&mac->scheduling_info.sr_DelayTimer);
}
void handle_time_alignment_timer_expired(NR_UE_MAC_INST_t *mac)
{
// flush all HARQ buffers for all Serving Cells
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) {
memset(&mac->dl_harq_info[k], 0, sizeof(NR_UE_HARQ_STATUS_t));
memset(&mac->ul_harq_info[k], 0, sizeof(NR_UL_HARQ_INFO_t));
mac->dl_harq_info[k].last_ndi = -1; // initialize to invalid value
mac->ul_harq_info[k].last_ndi = -1; // initialize to invalid value
}
// release PUCCH for all Serving Cells;
// release SRS for all Serving Cells;
release_PUCCH_SRS(mac);
// clear any configured downlink assignments and uplink grants;
int scs = mac->current_UL_BWP ? mac->current_UL_BWP->scs : get_softmodem_params()->numerology;
if (mac->dl_config_request)
memset(mac->dl_config_request, 0, sizeof(*mac->dl_config_request));
if (mac->ul_config_request)
clear_ul_config_request(mac, scs);
// clear any PUSCH resources for semi-persistent CSI reporting
// TODO we don't have semi-persistent CSI reporting
// maintain N_TA
// TODO not sure what to do here
}
void update_mac_timers(NR_UE_MAC_INST_t *mac)
{
if (mac->data_inactivity_timer) {
......@@ -159,6 +183,9 @@ void update_mac_timers(NR_UE_MAC_INST_t *mac)
if (inactivity_timer_expired)
nr_mac_rrc_inactivity_timer_ind(mac->ue_id);
}
bool alignment_timer_expired = nr_timer_tick(&mac->time_alignment_timer);
if (alignment_timer_expired)
handle_time_alignment_timer_expired(mac);
nr_timer_tick(&mac->ra.contention_resolution_timer);
for (int j = 0; j < NR_MAX_SR_ID; j++)
nr_timer_tick(&mac->scheduling_info.sr_info[j].prohibitTimer);
......
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