From 89f3ea3dd0b0305046b41cecf258d5eae7c365e4 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 19 Jul 2023 18:38:04 +0200 Subject: [PATCH] Wait for F1 Setup Response before unblocking cell The F1 Setup Response contains the cell(s) to activate. Hence, prevent the radio from starting by waiting for the F1 Setup Response before continuing. --- executables/nr-ru.c | 15 +++++++++++--- executables/nr-softmodem.c | 16 ++++++++++----- executables/nr-softmodem.h | 1 + openair2/GNB_APP/gnb_config.c | 20 +++++++++++++++++++ openair2/GNB_APP/gnb_config.h | 1 + .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 8 ++++++-- 6 files changed, 51 insertions(+), 10 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 4a4fa8e7af..0f7c7e57fd 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -95,8 +95,8 @@ extern void nr_phy_config_request(NR_PHY_Config_t *gNB); //extern WORKER_CONF_t get_thread_worker_conf(void); void init_NR_RU(char *); +void start_NR_RU(); void stop_RU(int nb_ru); -void do_ru_sync(RU_t *ru); void configure_ru(int idx, void *arg); void configure_rru(int idx, void *arg); @@ -1398,7 +1398,6 @@ int start_write_thread(RU_t *ru) { void init_RU_proc(RU_t *ru) { int i=0; RU_proc_t *proc; - LOG_I(PHY,"Initializing RU proc %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]); proc = &ru->proc; memset((void *)proc,0,sizeof(RU_proc_t)); proc->ru = ru; @@ -1413,7 +1412,6 @@ void init_RU_proc(RU_t *ru) { pthread_mutex_init( &proc->mutex_emulateRF,NULL); pthread_cond_init( &proc->cond_emulateRF, NULL); - threadCreate( &proc->pthread_FH, ru_thread, (void *)ru, "ru_thread", ru->ru_thread_core, OAI_PRIORITY_RT_MAX ); if(emulate_rf) threadCreate( &proc->pthread_emulateRF, emulatedRF_thread, (void *)proc, "emulateRF", -1, OAI_PRIORITY_RT ); @@ -1421,7 +1419,12 @@ void init_RU_proc(RU_t *ru) { threadCreate( &ru->ru_stats_thread, ru_stats_thread, (void *)ru,"ru_stats", -1, OAI_PRIORITY_RT ); if (get_thread_worker_conf() == WORKER_ENABLE) { } + LOG_I(PHY, "Initialized RU proc %d (%s,%s),\n", ru->idx, NB_functions[ru->function], NB_timing[ru->if_timing]); +} +void start_RU_proc(RU_t *ru) +{ + threadCreate(&ru->proc.pthread_FH, ru_thread, (void *)ru, "ru_thread", ru->ru_thread_core, OAI_PRIORITY_RT_MAX); } @@ -1875,6 +1878,12 @@ void init_NR_RU(char *rf_config_file) { LOG_D(HW,"[nr-softmodem.c] RU threads created\n"); } +void start_NR_RU() +{ + RU_t *ru = RC.ru[0]; + start_RU_proc(ru); +} + void stop_RU(int nb_ru) { for (int inst = 0; inst < nb_ru; inst++) { diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index dfe2193d70..ff5f33e37b 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -289,16 +289,14 @@ void exit_function(const char *file, const char *function, const int line, const } } - - -static int create_gNB_tasks(void) { +static int create_gNB_tasks(ngran_node_t node_type) +{ uint32_t gnb_nb = RC.nb_nr_inst; uint32_t gnb_id_start = 0; uint32_t gnb_id_end = gnb_id_start + gnb_nb; LOG_D(GNB_APP, "%s(gnb_nb:%d)\n", __FUNCTION__, gnb_nb); itti_wait_ready(1); LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__); - ngran_node_t node_type = get_node_type(); RCconfig_NR_L1(); RCconfig_nr_prs(); @@ -634,8 +632,9 @@ int main( int argc, char **argv ) { RCconfig_NR_L1(); // don't create if node doesn't connect to RRC/S1/GTP + const ngran_node_t node_type = get_node_type(); if (NFAPI_MODE != NFAPI_MODE_PNF) { - int ret = create_gNB_tasks(); + int ret = create_gNB_tasks(node_type); AssertFatal(ret == 0, "cannot create ITTI tasks\n"); } @@ -735,6 +734,13 @@ int main( int argc, char **argv ) { wait_nfapi_init("main?"); } + // wait for F1 Setup Response before starting L1 for real + if (NODE_IS_DU(node_type) || NODE_IS_MONOLITHIC(node_type)) + wait_f1_setup_response(); + + if (RC.nb_RU > 0) + start_NR_RU(); + if (RC.nb_nr_L1_inst > 0) { printf("wait RUs\n"); wait_RUs(); diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h index 63a2391826..96b70d0f90 100644 --- a/executables/nr-softmodem.h +++ b/executables/nr-softmodem.h @@ -54,6 +54,7 @@ extern void kill_gNB_proc(int inst); // In nr-ru.c extern void init_NR_RU(char *); extern void init_RU_proc(RU_t *ru); +extern void start_NR_RU(void); extern void stop_RU(int nb_ru); extern void kill_NR_RU_proc(int inst); extern void set_function_spec_param(RU_t *ru); diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index e395c4c866..e996f70c48 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -2039,6 +2039,26 @@ int RC_config_trigger_F1Setup() return 0; } +void wait_f1_setup_response(void) +{ + gNB_MAC_INST *mac = RC.nrmac[0]; + NR_SCHED_LOCK(&mac->sched_lock); + if (mac->f1_config.setup_resp != NULL) { + NR_SCHED_UNLOCK(&mac->sched_lock); + return; + } + + LOG_W(GNB_APP, "waiting for F1 Setup Response before activating radio\n"); + + /* for the moment, we keep it simple and just sleep to periodically check. + * The actual check is protected by a mutex */ + while (mac->f1_config.setup_resp == NULL) { + NR_SCHED_UNLOCK(&mac->sched_lock); + sleep(1); + NR_SCHED_LOCK(&mac->sched_lock); + } + NR_SCHED_UNLOCK(&mac->sched_lock); +} static bool check_plmn_identity(const f1ap_plmn_t *check_plmn, const f1ap_plmn_t *plmn) { return plmn->mcc == check_plmn->mcc && plmn->mnc_digit_length == check_plmn->mnc_digit_length && plmn->mnc == check_plmn->mnc; diff --git a/openair2/GNB_APP/gnb_config.h b/openair2/GNB_APP/gnb_config.h index 9d8a9487cb..55bc913d0f 100644 --- a/openair2/GNB_APP/gnb_config.h +++ b/openair2/GNB_APP/gnb_config.h @@ -104,6 +104,7 @@ void RCconfig_NRRRC(gNB_RRC_INST *rrc); int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i); int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i); int RC_config_trigger_F1Setup(void); +void wait_f1_setup_response(void); int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_update_t *gnb_cu_cfg_update); MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process); ngran_node_t get_node_type(void); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 6b341424b2..c6dfab563a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -58,9 +58,13 @@ void f1_setup_response(const f1ap_setup_resp_t *resp) AssertFatal(cu_cell->num_SI == 0, "handling of CU-provided SIBs: not implemented\n"); - NR_SCHED_UNLOCK(&mac->sched_lock); + mac->f1_config.setup_resp = malloc(sizeof(*mac->f1_config.setup_resp)); + AssertFatal(mac->f1_config.setup_resp != NULL, "out of memory\n"); + *mac->f1_config.setup_resp = *resp; + if (resp->gNB_CU_name) + mac->f1_config.setup_resp->gNB_CU_name = strdup(resp->gNB_CU_name); - /* TODO: handling of pre-operational state? */ + NR_SCHED_UNLOCK(&mac->sched_lock); } void f1_setup_failure(const f1ap_setup_failure_t *failure)