From eb09a63001558d1067bd4cfcd85ece0d73559fa0 Mon Sep 17 00:00:00 2001 From: francescomani <email@francescomani.it> Date: Thu, 6 Apr 2023 19:02:40 +0200 Subject: [PATCH] separating MAC and PHY procedures for TA --- .../telnetsrv/telnetsrv_5Gue_measurements.c | 5 +- executables/nr-ue.c | 9 +- .../nfapi/public_inc/fapi_nr_ue_constants.h | 3 +- .../nfapi/public_inc/fapi_nr_ue_interface.h | 6 + openair1/PHY/INIT/nr_init_ue.c | 5 +- openair1/PHY/NR_UE_TRANSPORT/csi_rx.c | 5 +- .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 4 +- openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c | 4 +- openair1/PHY/defs_nr_UE.h | 24 +-- openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 62 +++++- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 198 +++--------------- .../SCHED_NR_UE/phy_sch_processing_time.h | 12 +- .../NR_UE_PHY/unit_tests/src/pucch_uci_test.c | 1 - openair2/LAYER2/NR_MAC_UE/mac_defs.h | 19 +- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 5 +- openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 12 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 53 +++-- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 14 ++ .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 8 +- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 31 ++- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h | 4 +- 21 files changed, 201 insertions(+), 283 deletions(-) diff --git a/common/utils/telnetsrv/telnetsrv_5Gue_measurements.c b/common/utils/telnetsrv/telnetsrv_5Gue_measurements.c index 969521b3c5c..ae04666c95a 100644 --- a/common/utils/telnetsrv/telnetsrv_5Gue_measurements.c +++ b/common/utils/telnetsrv/telnetsrv_5Gue_measurements.c @@ -96,10 +96,7 @@ void measurcmd_display_phyta(telnet_printfunc_t prnt) PHY_VARS_NR_UE *UE = PHY_vars_UE_g[0][0]; prnt("%s PHY TA stats\n", HDR); prnt("N_TA_offset %d\n", UE->N_TA_offset); - for (int i = 0; i < UE->n_connected_gNB; ++i) { - NR_UL_TIME_ALIGNMENT_t *ta = &UE->ul_time_alignment[i]; - prnt("gNB %d TA command %d TA total %d TAG ID %d\n", i, ta->ta_command, ta->ta_total, ta->tag_id); - } + prnt("TA command %d\n", UE->ta_command); prnt("timing_advance %d (samples)\n", UE->timing_advance); } /* diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 40240756519..1d96b7aa2eb 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -154,7 +154,6 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, int nb_connected_gNB = 1; ue->Mod_id = UE_id; - ue->mac_enabled = 1; ue->if_inst = nr_ue_if_module_init(0); ue->dci_thres = 0; ue->target_Nid_cell = -1; @@ -259,8 +258,6 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) reset_queue(&nr_ul_dci_req_queue); reset_queue(&nr_ul_tti_req_queue); - NR_UL_TIME_ALIGNMENT_t ul_time_alignment; - memset(&ul_time_alignment, 0, sizeof(ul_time_alignment)); int last_sfn_slot = -1; uint16_t sfn_slot = 0; @@ -305,7 +302,7 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) if (get_softmodem_params()->sa && mac->mib == NULL) { LOG_D(NR_MAC, "We haven't gotten MIB. Lets see if we received it\n"); - nr_ue_dl_indication(&mac->dl_info, &ul_time_alignment); + nr_ue_dl_indication(&mac->dl_info); process_queued_nr_nfapi_msgs(mac, sfn_slot); } if (mac->scc == NULL && mac->scc_SIB == NULL) { @@ -347,7 +344,7 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) mac->dl_info.slot = slot; mac->dl_info.dci_ind = NULL; mac->dl_info.rx_ind = NULL; - nr_ue_dl_indication(&mac->dl_info, &ul_time_alignment); + nr_ue_dl_indication(&mac->dl_info); } if (pthread_mutex_unlock(&mac->mutex_dl_info)) abort(); @@ -629,7 +626,7 @@ nr_phy_data_t UE_dl_preprocessing(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { if(UE->if_inst != NULL && UE->if_inst->dl_indication != NULL) { nr_downlink_indication_t dl_indication; nr_fill_dl_indication(&dl_indication, NULL, NULL, proc, UE, &phy_data); - UE->if_inst->dl_indication(&dl_indication, NULL); + UE->if_inst->dl_indication(&dl_indication); } uint64_t a=rdtsc_oai(); diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h index 6d40752a9aa..276f417fbb7 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h @@ -50,7 +50,8 @@ #define FAPI_NR_DL_CONFIG_TYPE_P_DLSCH 0x05 #define FAPI_NR_DL_CONFIG_TYPE_CSI_RS 0x06 #define FAPI_NR_DL_CONFIG_TYPE_CSI_IM 0x07 -#define FAPI_NR_DL_CONFIG_TYPES 0x07 +#define FAPI_NR_CONFIG_TA_COMMAND 0x08 +#define FAPI_NR_DL_CONFIG_TYPES 0x08 #define FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01 #define FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02 diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 87fe5b82bc3..95ae91b4d49 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -526,6 +526,11 @@ typedef struct { fapi_nr_dl_config_csiim_pdu_rel15_t csiim_config_rel15; } fapi_nr_dl_config_csiim_pdu; +typedef struct { + int ta_frame; + int ta_slot; + int ta_command; +} fapi_nr_ta_command_pdu; typedef struct { uint8_t pdu_type; @@ -534,6 +539,7 @@ typedef struct { fapi_nr_dl_config_dlsch_pdu dlsch_config_pdu; fapi_nr_dl_config_csirs_pdu csirs_config_pdu; fapi_nr_dl_config_csiim_pdu csiim_config_pdu; + fapi_nr_ta_command_pdu ta_command_pdu; }; } fapi_nr_dl_config_request_pdu_t; diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 65d3f86f7a7..6c65f6a8035 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -234,9 +234,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) ue->bitrate[gNB_id] = 0; ue->total_received_bits[gNB_id] = 0; - ue->ul_time_alignment[gNB_id].apply_ta = 0; - ue->ul_time_alignment[gNB_id].ta_frame = -1; - ue->ul_time_alignment[gNB_id].ta_slot = -1; } // init NR modulation lookup tables nr_generate_modulation_table(); @@ -691,6 +688,8 @@ void init_N_TA_offset(PHY_VARS_NR_UE *ue){ } ue->N_TA_offset = (int)(N_TA_offset * factor); + ue->ta_frame = -1; + ue->ta_slot = -1; LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d, mu %d)\n", ue->Mod_id, ue->N_TA_offset, factor, fp->ul_CarrierFreq, fp->N_RB_DL, fp->numerology_index); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c index 0e5ba62da7a..02f087b2ef2 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c @@ -980,9 +980,8 @@ int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, c16_t r fapi_nr_rx_indication_t rx_ind = {0}; nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL); nr_fill_rx_indication(&rx_ind, FAPI_NR_CSIRS_IND, ue, NULL, NULL, 1, proc, (void *)&csirs_measurements, NULL); - if (ue->if_inst && ue->if_inst->dl_indication) { - ue->if_inst->dl_indication(&dl_indication, NULL); - } + if (ue->if_inst && ue->if_inst->dl_indication) + ue->if_inst->dl_indication(&dl_indication); return 0; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index da99ba7405f..e81f8551c08 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -515,7 +515,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, } // if stand alone and sync on ssb do sib1 detection as part of initial sync - if (sa==1 && ret==0) { + if (sa == 1 && ret == 0) { nr_ue_dlsch_init(phy_data.dlsch, 1, ue->max_ldpc_iterations); bool dec = false; proc->gNB_id = 0; //FIXME @@ -524,7 +524,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, int32_t pdcch_est_size = ((((fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH))+15)/16)*16); __attribute__ ((aligned(16))) int32_t pdcch_dl_ch_estimates[4*fp->nb_antennas_rx][pdcch_est_size]; - for(int n_ss = 0; n_ss<phy_pdcch_config->nb_search_space; n_ss++) { + for(int n_ss = 0; n_ss < phy_pdcch_config->nb_search_space; n_ss++) { proc->nr_slot_rx = phy_pdcch_config->slot; // setting PDCCH slot to proc uint8_t nb_symb_pdcch = phy_pdcch_config->pdcch_config[n_ss].coreset.duration; int start_symb = phy_pdcch_config->pdcch_config[n_ss].coreset.StartSymbolIndex; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 2fa9ca37ef7..8195f6bcb2c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -520,7 +520,7 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue, nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, phy_data); nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc, NULL, NULL); if (ue->if_inst && ue->if_inst->dl_indication) - ue->if_inst->dl_indication(&dl_indication, NULL); + ue->if_inst->dl_indication(&dl_indication); return(decoderState); } // printf("polar decoder output 0x%08x\n",pbch_a_prime); @@ -591,7 +591,7 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue, nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc, (void *)result, NULL); if (ue->if_inst && ue->if_inst->dl_indication) - ue->if_inst->dl_indication(&dl_indication, NULL); + ue->if_inst->dl_indication(&dl_indication); return 0; } diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 1543c81e00c..e942ef2e5e0 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -358,18 +358,6 @@ typedef struct UE_NR_SCAN_INFO_s { int32_t freq_offset_Hz[3][10]; } UE_NR_SCAN_INFO_t; -typedef struct NR_UL_TIME_ALIGNMENT { - /// flag used by MAC to inform PHY about a TA to be applied - unsigned char apply_ta; - /// frame and slot when to apply the TA as stated in TS 38.213 setion 4.2 - int16_t ta_frame; - char ta_slot; - /// TA command and TAGID received from the gNB - uint16_t ta_command; - uint32_t ta_total; - uint8_t tag_id; -} NR_UL_TIME_ALIGNMENT_t; - /// Top-level PHY Data Structure for UE typedef struct { /// \brief Module ID indicator for this instance @@ -519,7 +507,6 @@ typedef struct { int dlsch_mcch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; int current_dlsch_cqi[NUMBER_OF_CONNECTED_gNB_MAX]; - unsigned char first_run_timing_advance[NUMBER_OF_CONNECTED_gNB_MAX]; uint8_t decode_SIB; uint8_t decode_MIB; uint8_t init_sync_frame; @@ -533,9 +520,11 @@ typedef struct { /// Timing Advance updates variables /// Timing advance update computed from the TA command signalled from gNB - int timing_advance; - int N_TA_offset; ///timing offset used in TDD - NR_UL_TIME_ALIGNMENT_t ul_time_alignment[NUMBER_OF_CONNECTED_gNB_MAX]; + int timing_advance; + int N_TA_offset; ///timing offset used in TDD + int ta_frame; + int ta_slot; + int ta_command; /// Flag to tell if UE is secondary user (cognitive mode) unsigned char is_secondary_ue; @@ -546,9 +535,6 @@ typedef struct { /// holds the maximum channel/precoder coefficient char log2_maxp; - /// if ==0 enables phy only test mode - int mac_enabled; - /// Flag to initialize averaging of PHY measurements int init_averaging; diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 64ec900b2a9..562deb05934 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -40,10 +40,11 @@ #include "PHY/impl_defs_nr.h" #include "utils.h" #include "openair2/PHY_INTERFACE/queue_t.h" +#include "SCHED_NR_UE/phy_sch_processing_time.h" extern PHY_VARS_NR_UE ***PHY_vars_UE_g; -const char *dl_pdu_type[]={"DCI", "DLSCH", "RA_DLSCH", "SI_DLSCH", "P_DLSCH", "CSI_RS", "CSI_IM"}; +const char *dl_pdu_type[]={"DCI", "DLSCH", "RA_DLSCH", "SI_DLSCH", "P_DLSCH", "CSI_RS", "CSI_IM", "TA"}; const char *ul_pdu_type[]={"PRACH", "PUCCH", "PUSCH", "SRS"}; queue_t nr_rx_ind_queue; queue_t nr_crc_ind_queue; @@ -332,6 +333,62 @@ void configure_dlsch(NR_UE_DLSCH_t *dlsch0, } +void configure_ta_command(PHY_VARS_NR_UE *ue, fapi_nr_ta_command_pdu *ta_command_pdu) +{ + + /* Time Alignment procedure + // - UE processing capability 1 + // - Setting the TA update to be applied after the reception of the TA command + // - Timing adjustment computed according to TS 38.213 section 4.2 + // - Durations of N1 and N2 symbols corresponding to PDSCH and PUSCH are + // computed according to sections 5.3 and 6.4 of TS 38.214 */ + const int numerology = ue->frame_parms.numerology_index; + const int ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size; + const int nb_prefix_samples = ue->frame_parms.nb_prefix_samples; + const int samples_per_subframe = ue->frame_parms.samples_per_subframe; + const int slots_per_frame = ue->frame_parms.slots_per_frame; + const int slots_per_subframe = ue->frame_parms.slots_per_subframe; + + const double tc_factor = 1.0 / samples_per_subframe; + // convert time factor "16 * 64 * T_c / (2^mu)" in N_TA calculation in TS38.213 section 4.2 to samples by multiplying with samples per second + // 16 * 64 * T_c / (2^mu) * samples_per_second + // = 16 * T_s / (2^mu) * samples_per_second + // = 16 * 1 / (15 kHz * 2048) / (2^mu) * (15 kHz * 2^mu * ofdm_symbol_size) + // = 16 * 1 / 2048 * ofdm_symbol_size + // = 16 * ofdm_symbol_size / 2048 + uint16_t bw_scaling = 16 * ofdm_symbol_size / 2048; + + const int Ta_max = 3846; // Max value of 12 bits TA Command + const double N_TA_max = Ta_max * bw_scaling * tc_factor; + + // symbols corresponding to a PDSCH processing time for UE processing capability 1 + // when additional PDSCH DM-RS is configured + int N_1 = pdsch_N_1_capability_1[numerology][3]; + + /* PUSCH preapration time N_2 for processing capability 1 */ + const int N_2 = pusch_N_2_timing_capability_1[numerology][1]; + + /* N_t_1 time duration in msec of N_1 symbols corresponding to a PDSCH reception time + // N_t_2 time duration in msec of N_2 symbols corresponding to a PUSCH preparation time */ + double N_t_1 = N_1 * (ofdm_symbol_size + nb_prefix_samples) * tc_factor; + double N_t_2 = N_2 * (ofdm_symbol_size + nb_prefix_samples) * tc_factor; + + /* Time alignment procedure */ + // N_t_1 + N_t_2 + N_TA_max must be in msec + const double t_subframe = 1.0; // subframe duration of 1 msec + const int ul_tx_timing_adjustment = 1 + (int)ceil(slots_per_subframe*(N_t_1 + N_t_2 + N_TA_max + 0.5)/t_subframe); + + ue->ta_slot = (ta_command_pdu->ta_slot + ul_tx_timing_adjustment) % slots_per_frame; + if (ta_command_pdu->ta_slot + ul_tx_timing_adjustment > slots_per_frame) + ue->ta_frame = (ta_command_pdu->ta_frame + 1) % 1024; + else + ue->ta_frame = ta_command_pdu->ta_frame; + + ue->ta_command = ta_command_pdu->ta_command; + LOG_D(PHY,"TA command received in Frame.Slot %d.%d -- Starting UL time alignment procedures. TA update will be applied at frame %d slot %d\n", + ta_command_pdu->ta_frame, ta_command_pdu->ta_slot, ue->ta_frame, ue->ta_slot); +} + int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ bool found = false; @@ -406,6 +463,9 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ configure_dlsch(dlsch0, PHY_vars_UE_g[module_id][cc_id]->dl_harq_processes[0], dlsch_config_pdu, module_id, dl_config->dl_config_list[i].dlsch_config_pdu.rnti); break; + case FAPI_NR_CONFIG_TA_COMMAND: + configure_ta_command(PHY_vars_UE_g[module_id][cc_id], &dl_config->dl_config_list[i].ta_command_pdu); + break; } } dl_config->number_pdus = 0; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 664cddcfdff..f4debbb4534 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -50,7 +50,6 @@ #endif #include "executables/softmodem-common.h" #include "executables/nr-uesoftmodem.h" -#include "LAYER2/NR_MAC_UE/mac_proto.h" #include "SCHED_NR_UE/pucch_uci_ue_nr.h" #include <openair1/PHY/TOOLS/phy_scope_interface.h> @@ -87,8 +86,8 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind, fapi_nr_rx_indication_t *rx_ind, UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, - void *phy_data){ - + void *phy_data) +{ memset((void*)dl_ind, 0, sizeof(nr_downlink_indication_t)); dl_ind->gNB_index = proc->gNB_id; @@ -223,49 +222,37 @@ int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL){ return (amp_x_100); } -// convert time factor "16 * 64 * T_c / (2^mu)" in N_TA calculation in TS38.213 section 4.2 to samples by multiplying with samples per second -// 16 * 64 * T_c / (2^mu) * samples_per_second -// = 16 * T_s / (2^mu) * samples_per_second -// = 16 * 1 / (15 kHz * 2048) / (2^mu) * (15 kHz * 2^mu * ofdm_symbol_size) -// = 16 * 1 / 2048 * ofdm_symbol_size -// = 16 * ofdm_symbol_size / 2048 -static inline -uint16_t get_bw_scaling(uint16_t ofdm_symbol_size){ - return 16 * ofdm_symbol_size / 2048; -} - // UL time alignment procedures: -// - If the current tx frame and slot match the TA configuration in ul_time_alignment +// - If the current tx frame and slot match the TA configuration // then timing advance is processed and set to be applied in the next UL transmission // - Application of timing adjustment according to TS 38.213 p4.2 // todo: // - handle RAR TA application as per ch 4.2 TS 38.213 -void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx){ - - if (ue->mac_enabled == 1) { - - uint8_t gNB_id = 0; - NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[gNB_id]; - - if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot) { +void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx) +{ + if (frame_tx == ue->ta_frame && slot_tx == ue->ta_slot) { - uint16_t ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size; - uint16_t bw_scaling = get_bw_scaling(ofdm_symbol_size); + uint16_t ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size; - ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling; + // convert time factor "16 * 64 * T_c / (2^mu)" in N_TA calculation in TS38.213 section 4.2 to samples by multiplying with samples per second + // 16 * 64 * T_c / (2^mu) * samples_per_second + // = 16 * T_s / (2^mu) * samples_per_second + // = 16 * 1 / (15 kHz * 2048) / (2^mu) * (15 kHz * 2^mu * ofdm_symbol_size) + // = 16 * 1 / 2048 * ofdm_symbol_size + // = 16 * ofdm_symbol_size / 2048 + uint16_t bw_scaling = 16 * ofdm_symbol_size / 2048; - LOG_D(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n", - __FUNCTION__, - ue->Mod_id, - frame_tx, - slot_tx, - ul_time_alignment->ta_command, - ue->timing_advance); + ue->timing_advance += (ue->ta_command - 31) * bw_scaling; - ul_time_alignment->ta_frame = -1; - ul_time_alignment->ta_slot = -1; + LOG_D(PHY, "[UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n", + ue->Mod_id, + frame_tx, + slot_tx, + ue->ta_command, + ue->timing_advance); - } + ue->ta_frame = -1; + ue->ta_slot = -1; } } @@ -516,7 +503,7 @@ int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue, // fill dl_indication message nr_fill_dl_indication(&dl_indication, &dci_ind, NULL, proc, ue, phy_data); // send to mac - ue->if_inst->dl_indication(&dl_indication, NULL); + ue->if_inst->dl_indication(&dl_indication); stop_meas(&ue->dlsch_rx_pdcch_stats); @@ -705,13 +692,10 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, nr_downlink_indication_t dl_indication; fapi_nr_rx_indication_t rx_ind = {0}; uint16_t number_pdus = 1; - // params for UL time alignment procedure - NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[gNB_id]; uint8_t is_cw0_active = dl_harq0->status; uint8_t is_cw1_active = dl_harq1->status; uint16_t nb_symb_sch = dlsch[0].dlsch_config.number_symbols; - uint16_t start_symbol = dlsch[0].dlsch_config.start_symbol; uint8_t dmrs_type = dlsch[0].dlsch_config.dmrsConfigType; uint8_t nb_re_dmrs; @@ -805,7 +789,7 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL); nr_fill_rx_indication(&rx_ind, ind_type, ue, &dlsch[0], NULL, number_pdus, proc, NULL, p_b); - LOG_D(PHY, "In %s DL PDU length in bits: %d, in bytes: %d \n", __FUNCTION__, dlsch[0].dlsch_config.TBS, dlsch[0].dlsch_config.TBS / 8); + LOG_D(PHY, "DL PDU length in bits: %d, in bytes: %d \n", dlsch[0].dlsch_config.TBS, dlsch[0].dlsch_config.TBS / 8); stop_meas(&ue->dlsch_decoding_stats); if (cpumeas(CPUMEAS_GETSTATE)) { @@ -857,9 +841,10 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, } LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch[1].dlsch_config.TBS); } + // send to mac if (ue->if_inst && ue->if_inst->dl_indication) { - ue->if_inst->dl_indication(&dl_indication, ul_time_alignment); + ue->if_inst->dl_indication(&dl_indication); } // DLSCH decoding finished! don't wait anymore @@ -869,135 +854,6 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, if (ue->phy_sim_dlsch_b) memcpy(ue->phy_sim_dlsch_b, p_b, dlsch_bytes); - if (ue->mac_enabled == 1) { // TODO: move this from PHY to MAC layer! - - /* Time Alignment procedure - // - UE processing capability 1 - // - Setting the TA update to be applied after the reception of the TA command - // - Timing adjustment computed according to TS 38.213 section 4.2 - // - Durations of N1 and N2 symbols corresponding to PDSCH and PUSCH are - // computed according to sections 5.3 and 6.4 of TS 38.214 */ - const int numerology = ue->frame_parms.numerology_index; - const int ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size; - const int nb_prefix_samples = ue->frame_parms.nb_prefix_samples; - const int samples_per_subframe = ue->frame_parms.samples_per_subframe; - const int slots_per_frame = ue->frame_parms.slots_per_frame; - const int slots_per_subframe = ue->frame_parms.slots_per_subframe; - - const double tc_factor = 1.0 / samples_per_subframe; - const uint16_t bw_scaling = get_bw_scaling(ofdm_symbol_size); - - const int Ta_max = 3846; // Max value of 12 bits TA Command - const double N_TA_max = Ta_max * bw_scaling * tc_factor; - - NR_UE_MAC_INST_t *mac = get_mac_inst(0); - NR_BWP_Id_t ul_bwp = mac->current_UL_BWP.bwp_id; - - NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL; - if(ul_bwp){ - if (mac->ULbwp[ul_bwp-1] && - mac->ULbwp[ul_bwp-1]->bwp_Dedicated && - mac->ULbwp[ul_bwp-1]->bwp_Dedicated->pusch_Config && - mac->ULbwp[ul_bwp-1]->bwp_Dedicated->pusch_Config->choice.setup && - mac->ULbwp[ul_bwp-1]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) { - pusch_TimeDomainAllocationList = mac->ULbwp[ul_bwp-1]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList->choice.setup; - } - else if (mac->ULbwp[ul_bwp-1] && - mac->ULbwp[ul_bwp-1]->bwp_Common && - mac->ULbwp[ul_bwp-1]->bwp_Common->pusch_ConfigCommon && - mac->ULbwp[ul_bwp-1]->bwp_Common->pusch_ConfigCommon->choice.setup && - mac->ULbwp[ul_bwp-1]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) { - pusch_TimeDomainAllocationList = mac->ULbwp[ul_bwp-1]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } - } - else if (mac->scc_SIB && - mac->scc_SIB->uplinkConfigCommon && - mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon && - mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup && - mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) { - pusch_TimeDomainAllocationList = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } - long mapping_type_ul = pusch_TimeDomainAllocationList ? pusch_TimeDomainAllocationList->list.array[0]->mappingType : NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA; - - NR_PDSCH_Config_t *pdsch_Config = mac->current_DL_BWP.pdsch_Config; - NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = mac->current_DL_BWP.tdaList_Common; - long mapping_type_dl = pdsch_TimeDomainAllocationList ? pdsch_TimeDomainAllocationList->list.array[0]->mappingType : NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; - - NR_DMRS_DownlinkConfig_t *NR_DMRS_dlconfig = NULL; - if (pdsch_Config) { - if (mapping_type_dl == NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA) - NR_DMRS_dlconfig = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup; - else - NR_DMRS_dlconfig = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup; - } - - pdsch_dmrs_AdditionalPosition_t add_pos_dl = pdsch_dmrs_pos2; - if (NR_DMRS_dlconfig && NR_DMRS_dlconfig->dmrs_AdditionalPosition) - add_pos_dl = *NR_DMRS_dlconfig->dmrs_AdditionalPosition; - - /* PDSCH decoding time N_1 for processing capability 1 */ - int N_1; - - if (add_pos_dl == pdsch_dmrs_pos0) - N_1 = pdsch_N_1_capability_1[numerology][1]; - else if (add_pos_dl == pdsch_dmrs_pos1 || add_pos_dl == pdsch_dmrs_pos2) - N_1 = pdsch_N_1_capability_1[numerology][2]; - else - N_1 = pdsch_N_1_capability_1[numerology][3]; - - /* PUSCH preapration time N_2 for processing capability 1 */ - const int N_2 = pusch_N_2_timing_capability_1[numerology][1]; - - /* d_1_1 depending on the number of PDSCH symbols allocated */ - const int d = 0; // TODO number of overlapping symbols of the scheduling PDCCH and the scheduled PDSCH - int d_1_1 = 0; - if (mapping_type_dl == NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA) - if (nb_symb_sch + start_symbol < 7) - d_1_1 = 7 - (nb_symb_sch + start_symbol); - else - d_1_1 = 0; - else // mapping type B - switch (nb_symb_sch){ - case 7: d_1_1 = 0; break; - case 4: d_1_1 = 3; break; - case 2: d_1_1 = 3 + d; break; - default: break; - } - - /* d_2_1 */ - int d_2_1; - if (mapping_type_ul == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB && start_symbol != 0) - d_2_1 = 0; - else - d_2_1 = 1; - - /* d_2_2 */ - const double d_2_2 = pusch_d_2_2_timing_capability_1[numerology][1]; - - /* N_t_1 time duration in msec of N_1 symbols corresponding to a PDSCH reception time - // N_t_2 time duration in msec of N_2 symbols corresponding to a PUSCH preparation time */ - double N_t_1 = (N_1 + d_1_1) * (ofdm_symbol_size + nb_prefix_samples) * tc_factor; - double N_t_2 = (N_2 + d_2_1) * (ofdm_symbol_size + nb_prefix_samples) * tc_factor; - if (N_t_2 < d_2_2) N_t_2 = d_2_2; - - /* Time alignment procedure */ - // N_t_1 + N_t_2 + N_TA_max must be in msec - const double t_subframe = 1.0; // subframe duration of 1 msec - const int ul_tx_timing_adjustment = 1 + (int)ceil(slots_per_subframe*(N_t_1 + N_t_2 + N_TA_max + 0.5)/t_subframe); - - if (ul_time_alignment->apply_ta == 1){ - ul_time_alignment->ta_slot = (nr_slot_rx + ul_tx_timing_adjustment) % slots_per_frame; - if (nr_slot_rx + ul_tx_timing_adjustment > slots_per_frame){ - ul_time_alignment->ta_frame = (frame_rx + 1) % 1024; - } else { - ul_time_alignment->ta_frame = frame_rx; - } - // reset TA flag - ul_time_alignment->apply_ta = 0; - LOG_D(PHY,"Frame %d slot %d -- Starting UL time alignment procedures. TA update will be applied at frame %d slot %d\n", - frame_rx, nr_slot_rx, ul_time_alignment->ta_frame, ul_time_alignment->ta_slot); - } - } return dec; } diff --git a/openair1/SCHED_NR_UE/phy_sch_processing_time.h b/openair1/SCHED_NR_UE/phy_sch_processing_time.h index 81cc4496a26..896c93b9ee4 100644 --- a/openair1/SCHED_NR_UE/phy_sch_processing_time.h +++ b/openair1/SCHED_NR_UE/phy_sch_processing_time.h @@ -50,7 +50,7 @@ // when PDSCH DM-RS position l1 for the additional DM-RS is != 1,2 */ -int8_t pdsch_N_1_capability_1[4][4] = { +static const int8_t pdsch_N_1_capability_1[4][4] = { /* mu A B C */ { 0, 8, 14, 13 }, { 1, 10, 13, 13 }, @@ -69,7 +69,7 @@ int8_t pdsch_N_1_capability_1[4][4] = { // dmrs-DownlinkForPDSCH-MappingTypeA and dmrs-DownlinkForPDSCH-MappingTypeB // mu == 2 is for FR1 only */ -float pdsch_N_1_capability_2[3][2] = { +static const float pdsch_N_1_capability_2[3][2] = { /* mu A */ { 0, 3 }, { 1, 4.5 }, @@ -84,7 +84,7 @@ float pdsch_N_1_capability_2[3][2] = { // carrying the DCI scheduling the PUSCH was transmitted // mu_UL is the SCS of the UL channel with which PUSCH to be transmitted */ -int8_t pusch_N_2_timing_capability_1[4][2] = { +static const int8_t pusch_N_2_timing_capability_1[4][2] = { /* mu N_2 */ { 0, 10 }, { 1, 12 }, @@ -101,7 +101,7 @@ int8_t pusch_N_2_timing_capability_1[4][2] = { // mu_UL is the SCS of the UL channel with which PUSCH to be transmitted // mu == 2 is for FR1 only */ -float pusch_N_2_timing_capability_2[3][2] = { +static const float pusch_N_2_timing_capability_2[3][2] = { /* mu N_2 */ { 0, 5 }, { 1, 5.5 }, @@ -116,7 +116,7 @@ float pusch_N_2_timing_capability_2[3][2] = { // carrying the DCI scheduling the PUSCH was transmitted // mu_UL is the SCS of the UL channel with which PUSCH to be transmitted */ -float pusch_d_2_2_timing_capability_1[4][2] = { +static const float pusch_d_2_2_timing_capability_1[4][2] = { /* mu d_2_2 */ { 0, 1 }, { 1, 2 }, @@ -132,7 +132,7 @@ float pusch_d_2_2_timing_capability_1[4][2] = { // carrying the DCI scheduling the PUSCH was transmitted // mu_UL is the SCS of the UL channel with which PUSCH to be transmitted */ -float pusch_d_2_2_timing_capability_2[4][2] = { +static const float pusch_d_2_2_timing_capability_2[4][2] = { /* mu d_2_2 */ { 0, 3 }, { 1, 5 }, diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c index 12d50065fa8..c19680c6d0c 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c @@ -869,7 +869,6 @@ uint32_t tst_ue_get_SR(module_id_t module_idP,int CC_id,frame_t frameP,uint8_t e *********************************************************************/ void tst_set_sr_config(PHY_VARS_NR_UE *ue, int gNB_id) { - ue->mac_enabled = 1; ue->scheduling_request_config[gNB_id].sr_ConfigIndex = 0; p_nr_ue_get_SR = tst_ue_get_SR; } diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 25063f3141f..2f4b838e2b0 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -380,6 +380,16 @@ typedef struct { } NR_SSB_meas_t; +typedef struct NR_UL_TIME_ALIGNMENT { + /// TA command and TAGID received from the gNB + bool ta_apply; + int ta_command; + int ta_total; + uint32_t tag_id; + int frame; + int slot; +} NR_UL_TIME_ALIGNMENT_t; + /*!\brief Top level UE MAC structure */ typedef struct { NR_UE_L2_STATE_t state; @@ -402,11 +412,12 @@ typedef struct { NR_UE_DL_BWP_t current_DL_BWP; NR_UE_UL_BWP_t current_UL_BWP; + NR_UL_TIME_ALIGNMENT_t ul_time_alignment; - NR_BWP_Downlink_t *DLbwp[MAX_NUM_BWP_UE]; - NR_BWP_Uplink_t *ULbwp[MAX_NUM_BWP_UE]; - NR_ControlResourceSet_t *coreset[MAX_NUM_BWP_UE][FAPI_NR_MAX_CORESET_PER_BWP]; - NR_SearchSpace_t *SSpace[MAX_NUM_BWP_UE][FAPI_NR_MAX_SS]; + NR_BWP_Downlink_t *DLbwp[MAX_NUM_BWP_UE]; + NR_BWP_Uplink_t *ULbwp[MAX_NUM_BWP_UE]; + NR_ControlResourceSet_t *coreset[MAX_NUM_BWP_UE][FAPI_NR_MAX_CORESET_PER_BWP]; + NR_SearchSpace_t *SSpace[MAX_NUM_BWP_UE][FAPI_NR_MAX_SS]; bool phy_config_request_sent; frame_type_t frame_type; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index c8eec75d85c..bcb4eefe536 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -235,11 +235,9 @@ uint8_t get_rsrp_diff_index(int best_rsrp,int current_rsrp); @returns void */ void nr_ue_send_sdu(nr_downlink_indication_t *dl_info, - NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id); void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, - NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id); int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, @@ -333,6 +331,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, void *phy_data); void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot); void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot); +void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment); /* \brief This function schedules the Msg3 transmission @param @@ -367,7 +366,7 @@ random-access procedure @param selected_rar_buffer the output buffer for storing the selected RAR header and RAR payload @returns timing advance or 0xffff if preamble doesn't match */ -int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id); +int nr_ue_process_rar(nr_downlink_indication_t *dl_info, int pdu_id); void nr_ue_contention_resolution(module_id_t module_id, int cc_id, frame_t frame, int slot, NR_PRACH_RESOURCES_t *prach_resources); diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 31c665524ed..c6e13c412bf 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -50,16 +50,10 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) { //LOG_I(MAC, "[MAIN] init UE MAC functions \n"); //init mac here - nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(sizeof(NR_UE_MAC_INST_t),NB_NR_UE_MAC_INST); - nr_ue_mac_inst->first_sync_frame = -1; - nr_ue_mac_inst->sib1_decoded = false; - nr_ue_mac_inst->phy_config_request_sent = false; - nr_ue_mac_inst->state = UE_NOT_SYNC; - memset(&nr_ue_mac_inst->ssb_measurements, 0, sizeof(nr_ue_mac_inst->ssb_measurements)); + nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(sizeof(NR_UE_MAC_INST_t), NB_NR_UE_MAC_INST); - for (int j=0;j<NB_NR_UE_MAC_INST;j++) { - nr_ue_init_mac(j); - } + for (int j = 0; j < NB_NR_UE_MAC_INST; j++) + nr_ue_init_mac(j); if (rrc_inst && rrc_inst->scell_group_config) { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 9542e19514c..37ff36e05f4 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -131,9 +131,8 @@ const initial_pucch_resource_t initial_pucch_resource[16] = { }; -void nr_ue_init_mac(module_id_t module_idP) { - int i; - +void nr_ue_init_mac(module_id_t module_idP) +{ NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); // default values as deined in 38.331 sec 9.2.2 LOG_I(NR_MAC, "[UE%d] Applying default macMainConfig\n", module_idP); @@ -162,7 +161,7 @@ void nr_ue_init_mac(module_id_t module_idP) { // mac->scheduling_info.PathlossChange_db = nr_get_db_dl_PathlossChange(mac->scheduling_info.PathlossChange); // mac->PHR_reporting_active = 0; - for (i = 0; i < NR_MAX_NUM_LCID; i++) { + for (int i = 0; i < NR_MAX_NUM_LCID; i++) { LOG_D(NR_MAC, "[UE%d] Applying default logical channel config for LCGID %d\n", module_idP, i); mac->scheduling_info.Bj[i] = -1; @@ -176,8 +175,16 @@ void nr_ue_init_mac(module_id_t module_idP) { mac->scheduling_info.LCID_status[i] = LCID_EMPTY; mac->scheduling_info.LCID_buffer_remain[i] = 0; - for (int i=0;i<NR_MAX_HARQ_PROCESSES;i++) mac->first_ul_tx[i]=1; + for (int i = 0; i < NR_MAX_HARQ_PROCESSES; i++) + mac->first_ul_tx[i] = 1; } + + mac->first_sync_frame = -1; + mac->sib1_decoded = false; + mac->phy_config_request_sent = false; + mac->state = UE_NOT_SYNC; + memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements)); + memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment)); } NR_BWP_DownlinkCommon_t *get_bwp_downlink_common(NR_UE_MAC_INST_t *mac, NR_BWP_Id_t dl_bwp_id) { @@ -2380,8 +2387,8 @@ uint8_t get_rsrp_diff_index(int best_rsrp,int current_rsrp) { } -void nr_ue_send_sdu(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id){ - +void nr_ue_send_sdu(nr_downlink_indication_t *dl_info, int pdu_id) +{ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN); LOG_D(MAC, "In %s [%d.%d] Handling DLSCH PDU...\n", __FUNCTION__, dl_info->frame, dl_info->slot); @@ -2390,10 +2397,10 @@ void nr_ue_send_sdu(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *u // it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs switch (dl_info->rx_ind->rx_indication_body[pdu_id].pdu_type){ case FAPI_NR_RX_PDU_TYPE_DLSCH: - nr_ue_process_mac_pdu(dl_info, ul_time_alignment, pdu_id); + nr_ue_process_mac_pdu(dl_info, pdu_id); break; case FAPI_NR_RX_PDU_TYPE_RAR: - nr_ue_process_rar(dl_info, ul_time_alignment, pdu_id); + nr_ue_process_rar(dl_info, pdu_id); break; default: break; @@ -3107,8 +3114,8 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, // R: Reserved bit, set to zero. //////////////////////////////// void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, - NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, - int pdu_id){ + int pdu_id) +{ module_id_t module_idP = dl_info->module_id; frame_t frameP = dl_info->frame; @@ -3228,11 +3235,14 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, const int ta = ((NR_MAC_CE_TA *)pduP)[1].TA_COMMAND; const int tag = ((NR_MAC_CE_TA *)pduP)[1].TAGID; - ul_time_alignment->apply_ta = 1; - ul_time_alignment->ta_command = ta; //here + + NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment; ul_time_alignment->ta_total += ta - 31; ul_time_alignment->tag_id = tag; - + ul_time_alignment->ta_command = ta; + ul_time_alignment->frame = frameP; + ul_time_alignment->slot = slot; + ul_time_alignment->ta_apply = true; /* #ifdef DEBUG_HEADER_PARSING LOG_D(MAC, "[UE] CE %d : UE Timing Advance : %d\n", i, pduP[1]); @@ -3515,8 +3525,8 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, // - b buffer // - ulsch power offset // - optimize: mu_pusch, j and table_6_1_2_1_1_2_time_dom_res_alloc_A are already defined in nr_ue_procedures -int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id){ - +int nr_ue_process_rar(nr_downlink_indication_t *dl_info, int pdu_id) +{ module_id_t mod_id = dl_info->module_id; frame_t frame = dl_info->frame; int slot = dl_info->slot; @@ -3601,12 +3611,12 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t #endif // TA command - ul_time_alignment->apply_ta = 1; + 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 = 31 + ta; ul_time_alignment->ta_total = ta; - LOG_W(MAC, "received TA command %d\n", ul_time_alignment->ta_command); - + ul_time_alignment->ta_apply = true; + LOG_W(MAC, "received TA command %d\n", 31 + ta); #ifdef DEBUG_RAR // CSI csi_req = (unsigned char) (rar->UL_GRANT_4 & 0x01); @@ -3674,7 +3684,7 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t mod_id, rar_grant.Msg3_t_alloc, rar_grant.Msg3_f_alloc, - ul_time_alignment->ta_command, + ta_command, rar_grant.mcs, rar_grant.freq_hopping, tpc_command, @@ -3720,10 +3730,7 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t } } else { - ra->t_crnti = 0; - ul_time_alignment->ta_command = (0xffff); - } return ret; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index a3f4d06b1c5..8f379726f71 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1024,6 +1024,8 @@ void nr_ue_dl_scheduler(nr_downlink_indication_t *dl_info) nr_ue_dcireq(&dcireq); //to be replaced with function pointer later *dl_config = dcireq.dl_config_req; + if(mac->ul_time_alignment.ta_apply) + schedule_ta_command(dl_config, &mac->ul_time_alignment); nr_schedule_csirs_reception(mac, rx_frame, rx_slot); nr_schedule_csi_for_im(mac, rx_frame, rx_slot); dcireq.dl_config_req = *dl_config; @@ -1037,6 +1039,8 @@ void nr_ue_dl_scheduler(nr_downlink_indication_t *dl_info) else if (mac->state == UE_PERFORMING_RA) { // this is for Msg2/Msg4 if (mac->ra.ra_state >= WAIT_RAR) { + if(mac->ul_time_alignment.ta_apply) + schedule_ta_command(dl_config, &mac->ul_time_alignment); fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; rel15->num_dci_options = mac->ra.ra_state == WAIT_RAR ? 1 : 2; rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0; @@ -3178,5 +3182,15 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, #endif return num_sdus > 0 ? 1 : 0; +} +void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment) +{ + fapi_nr_ta_command_pdu *ta = &dl_config->dl_config_list[dl_config->number_pdus].ta_command_pdu; + ta->ta_frame = ul_time_alignment->frame; + ta->ta_slot = ul_time_alignment->slot; + ta->ta_command = ul_time_alignment->ta_command; + dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_CONFIG_TA_COMMAND; + dl_config->number_pdus += 1; + ul_time_alignment->ta_apply = false; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index e6f32b14058..bfa34e977ed 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -108,10 +108,8 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP, AssertFatal(timing_advance_cmd < 64, "timing_advance_cmd %d > 63\n", timing_advance_cmd); ((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; - if (gNB->tag->tag_Id != 0) { - tag_id = gNB->tag->tag_Id; - ((NR_MAC_CE_TA *) ce_ptr)->TAGID = tag_id; - } + tag_id = gNB->tag->tag_Id; + ((NR_MAC_CE_TA *) ce_ptr)->TAGID = tag_id; LOG_D(NR_MAC, "NR MAC CE timing advance command = %d (%d) TAG ID = %d\n", timing_advance_cmd, ((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND, tag_id); mac_ce_size = sizeof(NR_MAC_CE_TA); @@ -1191,7 +1189,7 @@ void nr_schedule_ue_spec(module_id_t module_id, T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->transportBlock, TBS)); UE->mac_stats.dl.total_rbs_retx += sched_pdsch->rbSize; } else { /* initial transmission */ - LOG_D(NR_MAC, "[%s] Initial HARQ transmission in %d.%d\n", __FUNCTION__, frame, slot); + LOG_D(NR_MAC, "Initial HARQ transmission in %d.%d\n", frame, slot); uint8_t *buf = (uint8_t *) harq->transportBlock; /* first, write all CEs that might be there */ int written = nr_write_ce_dlsch_pdu(module_id, diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 6aa44194a31..3f44c8c2a61 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -443,9 +443,7 @@ static void copy_dl_tti_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi_ rx_ind->sfn = dl_tti_request->SFN; rx_ind->slot = dl_tti_request->Slot; fill_mib_in_rx_ind(pdu_list, rx_ind, 0, FAPI_NR_RX_PDU_TYPE_SSB); - NR_UL_TIME_ALIGNMENT_t ul_time_alignment; - memset(&ul_time_alignment, 0, sizeof(ul_time_alignment)); - nr_ue_dl_indication(&mac->dl_info, &ul_time_alignment); + nr_ue_dl_indication(&mac->dl_info); } } dl_info->slot = dl_tti_request->Slot; @@ -729,15 +727,12 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request, return; } - - NR_UL_TIME_ALIGNMENT_t ul_time_alignment; - memset(&ul_time_alignment, 0, sizeof(ul_time_alignment)); if (dl_tti_request || tx_data_request || ul_dci_request) { fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, slot); fill_dci_from_dl_config(&mac->dl_info, dl_config); } nr_ue_dl_scheduler(&mac->dl_info); - nr_ue_dl_indication(&mac->dl_info, &ul_time_alignment); + nr_ue_dl_indication(&mac->dl_info); if (pthread_mutex_unlock(&mac->mutex_dl_info)) abort(); @@ -1085,7 +1080,8 @@ void handle_ssb_meas(NR_UE_MAC_INST_t *mac, uint8_t ssb_index, int16_t rsrp_dbm) // L2 Abstraction Layer // Note: sdu should always be processed because data and timing advance updates are transmitted by the UE -int8_t handle_dlsch(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id){ +int8_t handle_dlsch(nr_downlink_indication_t *dl_info, int pdu_id) +{ /* L1 assigns harq_pid, but in emulated L1 mode we need to assign the harq_pid based on the saved global g_harq_pid. Because we are emulating L1, no antenna measurements are conducted to calculate @@ -1097,7 +1093,7 @@ int8_t handle_dlsch(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *u dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.harq_pid, dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.ack_nack); if(dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.ack_nack) - nr_ue_send_sdu(dl_info, ul_time_alignment, pdu_id); + nr_ue_send_sdu(dl_info, pdu_id); return 0; } @@ -1142,8 +1138,8 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info) return 0; } -int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){ - +int nr_ue_dl_indication(nr_downlink_indication_t *dl_info) +{ pthread_mutex_lock(&mac_IF_mutex); uint32_t ret_mask = 0x0; module_id_t module_id = dl_info->module_id; @@ -1193,13 +1189,12 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ if (dl_info->rx_ind != NULL) { - for (int i=0; i<dl_info->rx_ind->number_pdus; ++i) { + for (int i = 0; i < dl_info->rx_ind->number_pdus; ++i) { fapi_nr_rx_indication_body_t rx_indication_body = dl_info->rx_ind->rx_indication_body[i]; - LOG_D(NR_MAC, "In %s sending DL indication to MAC. 1 PDU type %d of %d total number of PDUs \n", - __FUNCTION__, - rx_indication_body.pdu_type, - dl_info->rx_ind->number_pdus); + LOG_D(NR_MAC, "Sending DL indication to MAC. 1 PDU type %d of %d total number of PDUs \n", + rx_indication_body.pdu_type, + dl_info->rx_ind->number_pdus); switch(rx_indication_body.pdu_type){ case FAPI_NR_RX_PDU_TYPE_SSB: @@ -1226,10 +1221,10 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ rx_indication_body.pdsch_pdu.pdu_length)) << FAPI_NR_RX_PDU_TYPE_SIB; break; case FAPI_NR_RX_PDU_TYPE_DLSCH: - ret_mask |= (handle_dlsch(dl_info, ul_time_alignment, i)) << FAPI_NR_RX_PDU_TYPE_DLSCH; + ret_mask |= (handle_dlsch(dl_info, i)) << FAPI_NR_RX_PDU_TYPE_DLSCH; break; case FAPI_NR_RX_PDU_TYPE_RAR: - ret_mask |= (handle_dlsch(dl_info, ul_time_alignment, i)) << FAPI_NR_RX_PDU_TYPE_RAR; + ret_mask |= (handle_dlsch(dl_info, i)) << FAPI_NR_RX_PDU_TYPE_RAR; break; case FAPI_NR_CSIRS_IND: ret_mask |= (handle_csirs_measurements(dl_info->module_id, diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h index 91775794ede..e80459ee5fc 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h @@ -195,7 +195,7 @@ typedef void (nr_ue_synch_request_f)(nr_synch_request_t *synch_request); * -1: Failed to consume bytes. Abort the mission. * Non-negative return values indicate success, and ignored. */ -typedef int (nr_ue_dl_indication_f)(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment); +typedef int (nr_ue_dl_indication_f)(nr_downlink_indication_t *dl_info); /* * Generic type of an application-defined callback to return various @@ -256,7 +256,7 @@ int nr_ue_if_module_kill(uint32_t module_id); /**\brief interface between L1/L2, indicating the downlink related information, like dci_ind and rx_req \param dl_info including dci_ind and rx_request messages*/ -int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment); +int nr_ue_dl_indication(nr_downlink_indication_t *dl_info); int nr_ue_ul_indication(nr_uplink_indication_t *ul_info); -- GitLab