diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 075789e12b..38d0026c17 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -157,6 +157,7 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, ue->mac_enabled = 1; ue->if_inst = nr_ue_if_module_init(0); ue->dci_thres = 0; + ue->target_Nid_cell = -1; // initialize all signal buffers init_nr_ue_signal(ue, nb_connected_gNB); @@ -413,7 +414,11 @@ static void UE_synch(void *arg) { */ } - LOG_W(PHY, "Starting sync detection\n"); + if (UE->target_Nid_cell != -1) { + LOG_W(NR_PHY, "Starting re-sync detection for target Nid_cell %i\n", UE->target_Nid_cell); + } else { + LOG_W(NR_PHY, "Starting sync detection\n"); + } switch (sync_mode) { /* @@ -597,6 +602,17 @@ void UE_processing(nr_rxtx_thread_data_t *rxtxD) { nr_phy_data_t phy_data = {0}; if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa) { + + // Start synchronization with a target gNB + if (UE->synch_request.received_synch_request == 1 && UE->target_Nid_cell == -1) { + UE->is_synchronized = 0; + UE->target_Nid_cell = UE->synch_request.synch_req.target_Nid_cell; + clean_UE_ulsch(UE, proc->gNB_id); + } else if (UE->synch_request.received_synch_request == 1 && UE->target_Nid_cell != -1) { + UE->synch_request.received_synch_request = 0; + UE->target_Nid_cell = -1; + } + /* send tick to RLC and PDCP every ms */ if (proc->nr_slot_rx % UE->frame_parms.slots_per_subframe == 0) { void nr_rlc_tick(int frame, int subframe); @@ -815,13 +831,13 @@ void *UE_thread(void *arg) { if (!UE->is_synchronized) { readFrame(UE, ×tamp, false); - notifiedFIFO_elt_t *Msg=newNotifiedFIFO_elt(sizeof(syncData_t),0,&nf,UE_synch); - syncData_t *syncMsg=(syncData_t *)NotifiedFifoData(Msg); - syncMsg->UE=UE; + notifiedFIFO_elt_t *Msg = newNotifiedFIFO_elt(sizeof(syncData_t), 0, &nf, UE_synch); + syncData_t *syncMsg = (syncData_t *)NotifiedFifoData(Msg); + syncMsg->UE = UE; memset(&syncMsg->proc, 0, sizeof(syncMsg->proc)); pushTpool(&(get_nrUE_params()->Tpool), Msg); - trashed_frames=0; - syncRunning=true; + trashed_frames = 0; + syncRunning = true; continue; } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index eb6e160ec3..5cef04f195 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -211,6 +211,11 @@ int create_tasks_nrue(uint32_t ue_nb) { } itti_wait_ready(0); + + // Thread to update the RRC timers (in msec) at UE + pthread_t timers_update; + threadCreate(&timers_update, nr_rrc_timers_update, NULL, "nr_rrc_timer_update", -1, OAI_PRIORITY_RT_LOW); + return 0; } 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 94bf1b02dc..d429bf43ba 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 @@ -654,6 +654,10 @@ typedef struct } fapi_nr_prach_config_t; +typedef struct { + uint16_t target_Nid_cell; +} fapi_nr_synch_request_t; + typedef struct { uint32_t config_mask; diff --git a/openair1/PHY/NR_REFSIG/pss_nr.h b/openair1/PHY/NR_REFSIG/pss_nr.h index 3b0e87109e..c5bc4f880e 100644 --- a/openair1/PHY/NR_REFSIG/pss_nr.h +++ b/openair1/PHY/NR_REFSIG/pss_nr.h @@ -126,12 +126,7 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue); void free_context_pss_nr(void); int set_pss_nr(int ofdm_symbol_size); int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change); -int pss_search_time_nr(c16_t **rxdata, ///rx data in time domain - NR_DL_FRAME_PARMS *frame_parms, - int fo_flag, - int is, - int *eNB_id, - int *f_off); +int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, int is); #endif #undef EXTERN diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 1904bed457..061eede6dd 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -300,11 +300,11 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, /* time samples in buffer rxdata are used as input of FFT -> FFT results are stored in the frequency buffer rxdataF */ /* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */ - for(int i=0; i<4;i++) + for (int i = 0; i < NR_N_SYMBOLS_SSB; i++) nr_slot_fep_init_sync(ue, proc, i, - is*fp->samples_per_frame+ue->ssb_offset, + is * fp->samples_per_frame + ue->ssb_offset, false, rxdataF); @@ -522,6 +522,10 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, } + if (ue->target_Nid_cell != -1) { + return ret; + } + // if stand alone and sync on ssb do sib1 detection as part of initial sync if (sa==1 && ret==0) { nr_ue_dlsch_init(phy_data.dlsch, 1, ue->max_ldpc_iterations); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 7432c82aac..0d6c334c45 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -251,6 +251,8 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, NR_DL_FRAME_PARMS *frame_parms, uint8_t Nl); +int8_t clean_UE_ulsch(PHY_VARS_NR_UE *UE, uint8_t gNB_id); + void nr_dlsch_unscrambling(int16_t* llr, uint32_t size, uint8_t q, @@ -313,7 +315,7 @@ int dump_ue_stats(PHY_VARS_NR_UE *phy_vars_ue, UE_nr_rxtx_proc_t *proc, char* bu @param mode current running mode */ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, - PHY_VARS_NR_UE *phy_vars_ue, + PHY_VARS_NR_UE *phy_vars_ue, int n_frames, int sa); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 9d0982689b..fc22a954fe 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -662,3 +662,15 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, //////////////////////////////////////////////////// return 0; } + +int8_t clean_UE_ulsch(PHY_VARS_NR_UE *UE, uint8_t gNB_id) +{ + for (int harq_pid = 0; harq_pid < NR_MAX_ULSCH_HARQ_PROCESSES; harq_pid++) { + NR_UL_UE_HARQ_t *ul_harq_process = &UE->ul_harq_processes[harq_pid]; + ul_harq_process->tx_status = NEW_TRANSMISSION_HARQ; + ul_harq_process->status = SCH_IDLE; + ul_harq_process->round = 0; + ul_harq_process->first_tx = 1; + } + return 0; +} diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index fbb4a8a625..50f6fa2f34 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -555,12 +555,8 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change) #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PSS_SEARCH_TIME_NR, VCD_FUNCTION_IN); - synchro_position = pss_search_time_nr(rxdata, - frame_parms, - fo_flag, - is, - (int *)&PHY_vars_UE->common_vars.eNb_id, - (int *)&PHY_vars_UE->common_vars.freq_offset); + + synchro_position = pss_search_time_nr(rxdata, PHY_vars_UE, fo_flag, is); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PSS_SEARCH_TIME_NR, VCD_FUNCTION_OUT); @@ -605,7 +601,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change) * * NAME : pss_search_time_nr * -* PARAMETERS : received buffer +* PARAMETERS : received buffer in time domain * frame parameters * * RETURN : position of detected pss @@ -651,17 +647,15 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change) * *********************************************************************/ -int pss_search_time_nr(c16_t **rxdata, ///rx data in time domain - NR_DL_FRAME_PARMS *frame_parms, - int fo_flag, - int is, - int *eNB_id, - int *f_off) +int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, int is) { + NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + int *eNB_id = (int *)&ue->common_vars.eNb_id; + int *f_off = (int *)&ue->common_vars.freq_offset; unsigned int n, ar, peak_position, pss_source; int64_t peak_value; - int64_t avg[NUMBER_PSS_SEQUENCE]={0}; - double ffo_est=0; + int64_t avg[NUMBER_PSS_SEQUENCE] = {0}; + double ffo_est = 0; // performing the correlation on a frame length plus one symbol for the first of the two frame // to take into account the possibility of PSS in between the two frames @@ -692,7 +686,14 @@ int pss_search_time_nr(c16_t **rxdata, ///rx data in time domain /* This is required by SIMD (single instruction Multiple Data) Extensions of Intel processors. */ /* Correlation computation is based on a a dot product which is realized thank to SIMS extensions */ - for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) { + uint16_t pss_index_start = 0; + uint16_t pss_index_end = NUMBER_PSS_SEQUENCE; + if (ue->target_Nid_cell != -1) { + pss_index_start = GET_NID2(ue->target_Nid_cell); + pss_index_end = pss_index_start + 1; + } + + for (int pss_index = pss_index_start; pss_index < pss_index_end; pss_index++) { for (n = 0; n < length; n += 8) { // int64_t pss_corr_ue=0; @@ -748,10 +749,10 @@ int pss_search_time_nr(c16_t **rxdata, ///rx data in time domain } // computing absolute value of frequency offset - *f_off = ffo_est*frame_parms->subcarrier_spacing; + *f_off = ffo_est*frame_parms->subcarrier_spacing; - for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) - avg[pss_index]/=(length/4); + for (int pss_index = pss_index_start; pss_index < pss_index_end; pss_index++) + avg[pss_index] /= (length / 4); *eNB_id = pss_source; @@ -776,6 +777,6 @@ int pss_search_time_nr(c16_t **rxdata, ///rx data in time domain #endif - return(peak_position); + return peak_position; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c index 3056315999..cdb45fc9c1 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c @@ -511,9 +511,15 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, /* cosinus cos(x + y) = cos(x)cos(y) - sin(x)sin(y) */ /* sinus sin(x + y) = sin(x)cos(y) + cos(x)sin(y) */ - for (Nid1 = 0 ; Nid1 < N_ID_1_NUMBER; Nid1++) { // all possible Nid1 values - for (phase=0; phase < PHASE_HYPOTHESIS_NUMBER; phase++) { // phase offset between PSS and SSS + uint16_t Nid1_start = 0; + uint16_t Nid1_end = N_ID_1_NUMBER; + if (ue->target_Nid_cell != -1) { + Nid1_start = GET_NID1(ue->target_Nid_cell); + Nid1_end = Nid1_start + 1; + } + for (Nid1 = Nid1_start; Nid1 < Nid1_end; Nid1++) { // all possible Nid1 values + for (phase = 0; phase < PHASE_HYPOTHESIS_NUMBER; phase++) { // phase offset between PSS and SSS metric = 0; metric_re = 0; @@ -523,7 +529,6 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, // This is the inner product using one particular value of each unknown parameter for (i=0; i < LENGTH_SSS_NR; i++) { - metric_re += d[i]*(((phase_re_nr[phase]*sss[2*i])>>SCALING_METRIC_SSS_NR) - ((phase_im_nr[phase]*sss[2*i+1])>>SCALING_METRIC_SSS_NR)); #if 0 diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 79e75ee325..9ba7233770 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -400,6 +400,8 @@ typedef struct { int if_freq_off; /// \brief Indicator that UE is synchronized to a gNB int is_synchronized; + /// \brief Target gNB Nid_cell when UE is resynchronizing + int target_Nid_cell; /// \brief Indicator that UE lost frame synchronization int lost_sync; /// Data structure for UE process scheduling @@ -440,6 +442,7 @@ typedef struct { nr_ue_if_module_t *if_inst; fapi_nr_config_request_t nrUE_config; + nr_synch_request_t synch_request; NR_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_gNB_MAX]; NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_gNB_MAX]; diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index b64be34f6e..255ecf17ca 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -548,3 +548,11 @@ int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config) memcpy(nrUE_config,&phy_config->config_req,sizeof(fapi_nr_config_request_t)); return 0; } + +void nr_ue_synch_request(nr_synch_request_t *synch_request) +{ + fapi_nr_synch_request_t *synch_req = &PHY_vars_UE_g[synch_request->Mod_id][synch_request->CC_id]->synch_request.synch_req; + memcpy(synch_req, &synch_request->synch_req, sizeof(fapi_nr_synch_request_t)); + PHY_vars_UE_g[synch_request->Mod_id][synch_request->CC_id]->synch_request.received_synch_request = 1; +} + diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.h b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.h index a0b0b805af..d83c014fa6 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.h +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.h @@ -47,6 +47,10 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response \param scheduled_response including transmission config(dl_config, ul_config) and data transmission (tx_req)*/ int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config); +/**\brief NR UE FAPI message to schedule a synchronization with target gNB + \param synch_request including target_Nid_cell*/ +void nr_ue_synch_request(nr_synch_request_t *synch_request); + void update_harq_status(module_id_t module_id, uint8_t harq_pid, uint8_t ack_nack); #endif diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 26ec99b80e..b2c9ac5a33 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -120,6 +120,10 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, return 0; } +int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { + return 0; +} + int nr_derive_key(int alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t **out) { diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index d72bf2ed4f..629b7316b0 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -106,6 +106,10 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, return 0; } +int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { + return 0; +} + int nr_derive_key(int alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t **out) { diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 60b8eaca89..a13b8f37fa 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -116,6 +116,10 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, return 0; } +int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { + return 0; +} + int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t module_idP, int CC_idP, int UE_id, diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 8ab321b9e1..bd08153aff 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -752,8 +752,8 @@ int nr_rrc_mac_config_req_ue(module_id_t module_id, config_control_ue(mac); // Setup the SSB to Rach Occasions mapping according to the config build_ssb_to_ro_map(mac); - } - else if (cell_group_config != NULL ){ + + } else if (cell_group_config != NULL) { LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n"); mac->cg = cell_group_config; if (cell_group_config->spCellConfig) @@ -772,20 +772,38 @@ int nr_rrc_mac_config_req_ue(module_id_t module_id, configure_current_BWP(mac, NULL, cell_group_config); config_control_ue(mac); - if (get_softmodem_params()->nsa) { - if (cell_group_config->spCellConfig && cell_group_config->spCellConfig->reconfigurationWithSync) { - if (cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated) { - ra->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink; - } - mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon; - int num_slots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; - if (mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols > 0) { - num_slots++; - } - mac->ul_config_request = calloc(num_slots, sizeof(*mac->ul_config_request)); - config_common_ue(mac,module_id,cc_idP); - mac->crnti = cell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity; - LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti); + if (cell_group_config->spCellConfig && cell_group_config->spCellConfig->reconfigurationWithSync) { + LOG_A(NR_MAC, "Received the reconfigurationWithSync in %s\n", __FUNCTION__); + if (cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated) { + ra->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink; + } + mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon; + if (mac->scc_SIB) { + free(mac->scc_SIB); + mac->scc_SIB = NULL; + } + int num_slots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; + if (mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols > 0) { + num_slots++; + } + mac->state = UE_NOT_SYNC; + mac->ra.ra_state = RA_UE_IDLE; + mac->physCellId = *mac->scc->physCellId; + if (!get_softmodem_params()->emulate_l1) { + mac->synch_request.Mod_id = module_id; + mac->synch_request.CC_id = cc_idP; + mac->synch_request.synch_req.target_Nid_cell = mac->physCellId; + mac->if_module->synch_request(&mac->synch_request); + } + mac->ul_config_request = calloc(num_slots, sizeof(*mac->ul_config_request)); + config_common_ue(mac, module_id, cc_idP); + mac->crnti = cell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity; + LOG_I(MAC, "Configuring CRNTI %x\n", mac->crnti); + + nr_ue_init_mac(module_id); + if (!get_softmodem_params()->emulate_l1) { + mac->if_module->phy_config_request(&mac->phy_config); + mac->phy_config_request_sent = true; } // Setup the SSB to Rach Occasions mapping according to the config diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index e3f4247bd6..b1af5393a1 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -446,6 +446,7 @@ typedef struct { /// Interface module instances nr_ue_if_module_t *if_module; nr_phy_config_t phy_config; + nr_synch_request_t synch_request; /// BSR report flag management uint8_t BSR_reporting_active; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 6015fe27bc..9776003e3f 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -371,7 +371,7 @@ void nr_ue_contention_resolution(module_id_t module_id, int cc_id, frame_t frame 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(module_id_t mod_id, frame_t frame, int slot); +void nr_ra_succeeded(const module_id_t mod_id, const uint8_t gNB_index, const frame_t frame, const int slot); void nr_get_RA_window(NR_UE_MAC_INST_t *mac); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index c5800cfe14..ec9179e636 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -886,7 +886,7 @@ uint8_t nr_ue_get_rach(module_id_t mod_id, if(ra->cfra) { // Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213) - nr_ra_succeeded(mod_id, frame, nr_slot_tx); + nr_ra_succeeded(mod_id, gNB_id, frame, nr_slot_tx); } } else if (ra->RA_window_cnt == 0 && !ra->RA_RAPID_found) { @@ -1001,13 +1001,14 @@ void nr_ue_contention_resolution(module_id_t module_id, int cc_id, frame_t frame // 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){ - +void nr_ra_succeeded(const module_id_t mod_id, const uint8_t gNB_index, const frame_t frame, const int slot) +{ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); RA_config_t *ra = &mac->ra; if (ra->cfra) { LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CF-RA: RAR successfully received.\n", mod_id, frame, slot); + nr_rrc_RA_succeeded(mod_id, gNB_index); mac->state = UE_CONNECTED; ra->RA_window_cnt = -1; } else { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index e5b246f5c1..45b6a56978 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -269,7 +269,7 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl uint8_t bwp_id = mac->current_DL_BWP.bwp_id; //NR_ServingCellConfig_t *scd = mac->scg->spCellConfig->spCellConfigDedicated; NR_BWP_DownlinkDedicated_t *bwpd = (bwp_id>0) ? mac->DLbwp[bwp_id-1]->bwp_Dedicated : (mac->cg ? mac->cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL); - NR_BWP_DownlinkCommon_t *bwp_Common = (bwp_id>0) ? mac->DLbwp[bwp_id-1]->bwp_Common : &mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP; + NR_BWP_DownlinkCommon_t *bwp_Common = get_bwp_downlink_common(mac, bwp_id); LOG_D(NR_MAC, "[DCI_CONFIG] ra_rnti %p (%x) crnti %p (%x) t_crnti %p (%x)\n", &ra->ra_rnti, ra->ra_rnti, &mac->crnti, mac->crnti, &ra->t_crnti, ra->t_crnti); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 4190331a3e..af1faf19eb 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -686,7 +686,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr /* dmrs symbol positions*/ dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config, NR_DL_DCI_FORMAT_1_0, - (get_softmodem_params()->nsa) ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position, + mac->scc ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position, dlsch_config_pdu_1_0->number_symbols, dlsch_config_pdu_1_0->start_symbol, tda_info.mapping_type, @@ -2421,6 +2421,7 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, switch(dci_format) { case NR_DL_DCI_FORMAT_1_0: + switch(rnti_type) { case NR_RNTI_RA: // Freq domain assignment @@ -3256,7 +3257,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, } if ( (ra->RA_active == 1) && ra_success) { - nr_ra_succeeded(module_idP, frameP, slot); + nr_ra_succeeded(module_idP, gNB_index, frameP, slot); } else if (!ra_success){ // TODO: Handle failure of RA procedure @ MAC layer // nr_ra_failed(module_idP, CC_id, prach_resources, frameP, slot); // prach_resources is a PHY structure diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index deeb4a181a..b0d181f3da 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -495,7 +495,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, #ifdef DEBUG_MSG3 LOG_D(NR_MAC, "In %s BWP assignment (BWP (start %d, size %d) \n", __FUNCTION__, pusch_config_pdu->bwp_start, pusch_config_pdu->bwp_size); - #endif +#endif // MCS pusch_config_pdu->mcs_index = rar_grant->mcs; @@ -1399,6 +1399,8 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac, uint8_t is_Msg3, frame_t curren case 3: delta = 6; break; + default: + AssertFatal(1 == 0, "Invalid numerology %i\n", mu); } AssertFatal((k2 + delta) >= DURATION_RX_TO_TX, diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 38ae19c72a..2f2a3fd577 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -650,7 +650,58 @@ bool nr_mac_update_cellgroup(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupCon exit(1); } + nr_mac_update_RA(nrmac, rnti, CellGroup); process_CellGroup(CellGroup, &UE->UE_sched_ctrl); return true; } + +bool nr_mac_update_RA(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup) +{ + // Checking for free RA process + NR_COMMON_channels_t *cc = &nrmac->common_channels[0]; + uint8_t ra_index = 0; + for (; ra_index < NR_NB_RA_PROC_MAX; ra_index++) { + if ((cc->ra[ra_index].state == RA_IDLE) && (!cc->ra[ra_index].cfra)) + break; + } + if (ra_index == NR_NB_RA_PROC_MAX) { + LOG_E(NR_MAC, "%s() %s:%d RA processes are not available for CFRA RNTI :%x\n", __FUNCTION__, __FILE__, __LINE__, rnti); + return -1; + } + + NR_RA_t *ra = &cc->ra[ra_index]; + if (CellGroup->spCellConfig && CellGroup->spCellConfig->reconfigurationWithSync + && CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated != NULL) { + if (CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra != NULL) { + ra->cfra = true; + ra->rnti = rnti; + ra->CellGroup = CellGroup; + struct NR_CFRA *cfra = CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra; + uint8_t num_preamble = cfra->resources.choice.ssb->ssb_ResourceList.list.count; + ra->preambles.num_preambles = num_preamble; + ra->preambles.preamble_list = (uint8_t *)malloc(num_preamble * sizeof(uint8_t)); + for (int i = 0; i < cc->num_active_ssb; i++) { + for (int j = 0; j < num_preamble; j++) { + if (cc->ssb_index[i] == cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ssb) { + // One dedicated preamble for each beam + ra->preambles.preamble_list[i] = cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ra_PreambleIndex; + break; + } + } + } + } + } else { + ra->cfra = false; + ra->rnti = 0; + if (ra->preambles.preamble_list == NULL) { + ra->preambles.num_preambles = MAX_NUM_NR_PRACH_PREAMBLES; + ra->preambles.preamble_list = (uint8_t *)malloc(MAX_NUM_NR_PRACH_PREAMBLES * sizeof(uint8_t)); + for (int i = 0; i < MAX_NUM_NR_PRACH_PREAMBLES; i++) + ra->preambles.preamble_list[i] = i; + } + } + LOG_I(NR_MAC, "Added new %s process for UE RNTI %04x with initial CellGroup\n", ra->cfra ? "CFRA" : "CBRA", rnti); + + return true; +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 2729ccc00a..587575241f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1375,10 +1375,18 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra nr_get_Msg3alloc(module_idP, CC_id, scc, slotP, frameP, ra, nr_mac->tdd_beam_association); nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]); - if(ra->cfra) { + if (ra->cfra) { + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[module_idP]->UE_info, ra->rnti); + if (UE) { + const NR_ServingCellConfig_t *servingCellConfig = UE->CellGroup ? UE->CellGroup->spCellConfig->spCellConfigDedicated : NULL; + uint32_t delay_ms = servingCellConfig && servingCellConfig->downlinkBWP_ToAddModList ? NR_RRC_SETUP_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_SETUP_DELAY_MS; + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + sched_ctrl->rrc_processing_timer = (delay_ms << ra->DL_BWP.scs); + } LOG_D(NR_MAC, "Frame %d, Subframe %d: Setting RA-Msg3 reception (CFRA) for SFN.Slot %d.%d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot); + } else { + LOG_D(NR_MAC, "Frame %d, Subframe %d: Setting RA-Msg3 reception (CBRA) for SFN.Slot %d.%d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot); } - else LOG_D(NR_MAC, "Frame %d, Subframe %d: Setting RA-Msg3 reception (CBRA) for SFN.Slot %d.%d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot); T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(ra->RA_rnti), T_INT(frameP), T_INT(slotP), T_INT(0), T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length)); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 6ded61a220..a51ebf7149 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -478,14 +478,29 @@ void abort_nr_ul_harq(NR_UE_info_t *UE, int8_t harq_pid) sched_ctrl->sched_ul_bytes = 0; } +bool get_UE_waiting_CFRA_msg3(const gNB_MAC_INST *gNB_mac, const int CC_id, const frame_t frame, const sub_frame_t slot) +{ + bool UE_waiting_CFRA_msg3 = false; + for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { + const NR_RA_t *ra = &gNB_mac->common_channels[CC_id].ra[i]; + if (ra->cfra == true && ra->state == WAIT_Msg3 && frame == ra->Msg3_frame && slot == ra->Msg3_slot) { + UE_waiting_CFRA_msg3 = true; + break; + } + } + return UE_waiting_CFRA_msg3; +} + void handle_nr_ul_harq(const int CC_idP, module_id_t mod_id, frame_t frame, sub_frame_t slot, const nfapi_nr_crc_t *crc_pdu) { - NR_UE_info_t* UE = find_nr_UE(&RC.nrmac[mod_id]->UE_info, crc_pdu->rnti); - if (!UE) { + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[mod_id]->UE_info, crc_pdu->rnti); + bool UE_waiting_CFRA_msg3 = get_UE_waiting_CFRA_msg3(RC.nrmac[mod_id], CC_idP, frame, slot); + + if (!UE || UE_waiting_CFRA_msg3 == true) { LOG_W(NR_MAC, "handle harq for rnti %04x, in RA process\n", crc_pdu->rnti); for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) { NR_RA_t *ra = &RC.nrmac[mod_id]->common_channels[CC_idP].ra[i]; @@ -568,9 +583,12 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, LOG_D(NR_MAC, "rx_sdu for rnti %04x\n", current_rnti); const int target_snrx10 = gNB_mac->pusch_target_snrx10; const int pusch_failure_thres = gNB_mac->pusch_failure_thres; - - NR_UE_info_t* UE = find_nr_UE(&gNB_mac->UE_info, current_rnti); - if (UE) { + + NR_UE_info_t *UE = find_nr_UE(&gNB_mac->UE_info, current_rnti); + bool UE_waiting_CFRA_msg3 = get_UE_waiting_CFRA_msg3(gNB_mac, CC_idP, frameP, slotP); + + if (UE && UE_waiting_CFRA_msg3 == false) { + NR_UE_sched_ctrl_t *UE_scheduling_control = &UE->UE_sched_ctrl; const int8_t harq_pid = UE_scheduling_control->feedback_ul_harq.head; @@ -698,17 +716,19 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, continue; } - NR_UE_info_t *UE = add_new_nr_ue(gNB_mac, ra->rnti, ra->CellGroup); - if (!UE) { - LOG_W(NR_MAC, "Random Access %i discarded at state %i (TC_RNTI %04x RNTI %04x): max number of users achieved!\n", i, ra->state,ra->rnti,current_rnti); + NR_UE_info_t *UE_msg3_stage = UE ? UE : add_new_nr_ue(gNB_mac, ra->rnti, ra->CellGroup); + if (!UE_msg3_stage) { + LOG_W(NR_MAC, "Random Access %i discarded at state %i (TC_RNTI %04x RNTI %04x): max number of users achieved!\n", i, ra->state, ra->rnti, current_rnti); + + nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); return; } - UE->UE_beam_index = ra->beam_id; + UE_msg3_stage->UE_beam_index = ra->beam_id; // re-initialize ta update variables after RA procedure completion - UE->UE_sched_ctrl.ta_frame = frameP; + UE_msg3_stage->UE_sched_ctrl.ta_frame = frameP; LOG_D(NR_MAC, "reset RA state information for RA-RNTI 0x%04x/index %d\n", @@ -722,18 +742,23 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, current_rnti, ra->rnti); - NR_UE_sched_ctrl_t *UE_scheduling_control = &UE->UE_sched_ctrl; + NR_UE_sched_ctrl_t *UE_scheduling_control = &UE_msg3_stage->UE_sched_ctrl; - UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30); + UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10, ul_cqi, 30); if (timing_advance != 0xffff) UE_scheduling_control->ta_update = timing_advance; UE_scheduling_control->raw_rssi = rssi; UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640; - LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n",UE->rnti,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update); - if(ra->cfra) { - + LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n", UE_msg3_stage->rnti, UE_scheduling_control->tpc0, UE_scheduling_control->ta_update); + if (ra->cfra) { LOG_A(NR_MAC, "(rnti 0x%04x) CFRA procedure succeeded!\n", ra->rnti); - UE->ra_timer = 0; + nr_mac_gNB_rrc_ul_failure_reset(gnb_mod_idP, frameP, slotP, ra->rnti); + reset_dl_harq_list(UE_scheduling_control); + reset_ul_harq_list(UE_scheduling_control); + UE_scheduling_control->pusch_consecutive_dtx_cnt = 0; + UE_scheduling_control->ul_failure = 0; + UE_msg3_stage->ra_timer = 0; + nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); process_CellGroup(ra->CellGroup, UE_scheduling_control); @@ -751,7 +776,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, memcpy(ra->cont_res_id, &sduP[1], sizeof(uint8_t) * 6); // harq_pid set a non valid value because it is not used in this call // the function is only called to decode the contention resolution sub-header - if (nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP, -1) == 0) { + if (nr_process_mac_pdu(gnb_mod_idP, UE_msg3_stage, CC_idP, frameP, slotP, sduP, sdu_lenP, -1) == 0) { if (ra->state == Msg3_dcch_dtch) { // Check if the UE identified by C-RNTI still exists at the gNB diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index fe880785aa..3ad1597213 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -58,6 +58,7 @@ void nr_mac_config_sib1(gNB_MAC_INST *nrmac, NR_BCCH_DL_SCH_Message_t *sib1); bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup); bool nr_mac_prepare_ra_nsa_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup); bool nr_mac_update_cellgroup(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup); +bool nr_mac_update_RA(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup); void clear_nr_nfapi_information(gNB_MAC_INST * gNB, int CC_idP, diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 87d8527eb9..5ddd59fcc1 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -1239,6 +1239,7 @@ nr_ue_if_module_t *nr_ue_if_module_init(uint32_t module_id){ nr_ue_if_module_inst[module_id]->current_frame = 0; nr_ue_if_module_inst[module_id]->current_slot = 0; nr_ue_if_module_inst[module_id]->phy_config_request = nr_ue_phy_config_request; + nr_ue_if_module_inst[module_id]->synch_request = nr_ue_synch_request; if (get_softmodem_params()->emulate_l1) nr_ue_if_module_inst[module_id]->scheduled_response = nr_ue_scheduled_response_stub; else diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h index e3adfe7d53..91775794ed 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h @@ -151,6 +151,16 @@ typedef struct { } nr_phy_config_t; +typedef struct { + /// module id + uint8_t Mod_id; + /// component carrier id + uint8_t CC_id; + /// Flag signaling that synch_request was received + uint8_t received_synch_request; + /// NR UE FAPI message + fapi_nr_synch_request_t synch_req; +} nr_synch_request_t; /* * Generic type of an application-defined callback to return various @@ -171,6 +181,12 @@ typedef int8_t (nr_ue_scheduled_response_f)(nr_scheduled_response_t *scheduled_r */ typedef int8_t (nr_ue_phy_config_request_f)(nr_phy_config_t *phy_config); +/* + * Generic type of an application-defined callback to return various + * types of data to the application. + */ +typedef void (nr_ue_synch_request_f)(nr_synch_request_t *synch_request); + /* * Generic type of an application-defined callback to return various @@ -196,6 +212,7 @@ typedef int (nr_ue_dcireq_f)(nr_dcireq_t *ul_info); typedef struct nr_ue_if_module_s { nr_ue_scheduled_response_f *scheduled_response; nr_ue_phy_config_request_f *phy_config_request; + nr_ue_synch_request_f *synch_request; nr_ue_dl_indication_f *dl_indication; nr_ue_ul_indication_f *ul_indication; //nr_ue_dcireq_f *dcireq; diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index c67069e975..f3997fcdbe 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -185,3 +185,13 @@ rrc_data_req_nr_ue( return true; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. } + +int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) +{ + if (NR_UE_rrc_inst[mod_id].Info[gNB_index].T304_active == 1) { + LOG_W(NR_RRC, "T304 was stoped with value %i\n", NR_UE_rrc_inst[mod_id].Info[gNB_index].T304_cnt); + NR_UE_rrc_inst[mod_id].Info[gNB_index].T304_active = 0; + NR_UE_rrc_inst[mod_id].Info[gNB_index].T304_cnt = 0; + } + return 0; +} \ No newline at end of file diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index ecbaeea17e..6ee8c762fc 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1286,10 +1286,38 @@ nr_rrc_ue_process_masterCellGroup( xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig); } - if( cellGroupConfig->spCellConfig != NULL && cellGroupConfig->spCellConfig->reconfigurationWithSync != NULL){ - //TODO (perform Reconfiguration with sync according to 5.3.5.5.2) - //TODO (resume all suspended radio bearers and resume SCG transmission for all radio bearers, if suspended) - // NSA procedures + // TS 38.331 - Section 5.3.5.5.2 Reconfiguration with sync + if (cellGroupConfig->spCellConfig != NULL && cellGroupConfig->spCellConfig->reconfigurationWithSync != NULL) { + + LOG_A(NR_RRC, "Received the reconfigurationWithSync in %s\n", __FUNCTION__); + + NR_ReconfigurationWithSync_t *reconfigurationWithSync = cellGroupConfig->spCellConfig->reconfigurationWithSync; + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T304_active = 1; + switch (reconfigurationWithSync->t304) { + case NR_ReconfigurationWithSync__t304_ms100: + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T304_cnt = 100; + break; + case NR_ReconfigurationWithSync__t304_ms150: + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T304_cnt = 150; + break; + case NR_ReconfigurationWithSync__t304_ms200: + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T304_cnt = 200; + break; + case NR_ReconfigurationWithSync__t304_ms500: + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T304_cnt = 500; + break; + case NR_ReconfigurationWithSync__t304_ms1000: + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T304_cnt = 1000; + break; + case NR_ReconfigurationWithSync__t304_ms2000: + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T304_cnt = 2000; + break; + case NR_ReconfigurationWithSync__t304_ms10000: + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T304_cnt = 10000; + break; + default: + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T304_cnt = 50; + } } if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config == NULL){ @@ -2862,3 +2890,29 @@ void process_lte_nsa_msg(nsa_msg_t *msg, int msg_len) LOG_E(NR_RRC, "No NSA Message Found\n"); } } + +void *nr_rrc_timers_update() { + + while (1) { + + for (int mod_id = 0; mod_id < NB_NR_UE_INST; mod_id++) { + for (int i = 0; i < NB_SIG_CNX_UE; i++) { + NR_UE_RRC_INFO *timers = &NR_UE_rrc_inst[mod_id].Info[i]; + + // T304 + if (timers->T304_active == 1) { + if ((timers->T304_cnt % 100) == 0) { + LOG_W(NR_RRC, "T304: %u\n", timers->T304_cnt); + } + if (timers->T304_cnt == 1) { + timers->T304_active = 0; + } + timers->T304_cnt--; + } + + } + } + + usleep(1000); + } +} diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 510fbff230..2739c7ccf8 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -156,10 +156,15 @@ rrc_data_req_nr_ue( const pdcp_transmission_mode_t modeP ); +int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index); + /**\brief RRC UE task. \param void *args_p Pointer on arguments to start the task. */ void *rrc_nrue_task(void *args_p); +/**\brief RRC timers update at UE. */ +void *nr_rrc_timers_update(); + /**\brief RRC NSA UE task. \param void *args_p Pointer on arguments to start the task. */ void *recv_msgs_from_lte_ue(void *args_p);