Commit 89f3ea3d authored by Robert Schmidt's avatar Robert Schmidt

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.
parent aaae82d7
...@@ -95,8 +95,8 @@ extern void nr_phy_config_request(NR_PHY_Config_t *gNB); ...@@ -95,8 +95,8 @@ extern void nr_phy_config_request(NR_PHY_Config_t *gNB);
//extern WORKER_CONF_t get_thread_worker_conf(void); //extern WORKER_CONF_t get_thread_worker_conf(void);
void init_NR_RU(char *); void init_NR_RU(char *);
void start_NR_RU();
void stop_RU(int nb_ru); void stop_RU(int nb_ru);
void do_ru_sync(RU_t *ru);
void configure_ru(int idx, void *arg); void configure_ru(int idx, void *arg);
void configure_rru(int idx, void *arg); void configure_rru(int idx, void *arg);
...@@ -1398,7 +1398,6 @@ int start_write_thread(RU_t *ru) { ...@@ -1398,7 +1398,6 @@ int start_write_thread(RU_t *ru) {
void init_RU_proc(RU_t *ru) { void init_RU_proc(RU_t *ru) {
int i=0; int i=0;
RU_proc_t *proc; 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; proc = &ru->proc;
memset((void *)proc,0,sizeof(RU_proc_t)); memset((void *)proc,0,sizeof(RU_proc_t));
proc->ru = ru; proc->ru = ru;
...@@ -1413,7 +1412,6 @@ void init_RU_proc(RU_t *ru) { ...@@ -1413,7 +1412,6 @@ void init_RU_proc(RU_t *ru) {
pthread_mutex_init( &proc->mutex_emulateRF,NULL); pthread_mutex_init( &proc->mutex_emulateRF,NULL);
pthread_cond_init( &proc->cond_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) if(emulate_rf)
threadCreate( &proc->pthread_emulateRF, emulatedRF_thread, (void *)proc, "emulateRF", -1, OAI_PRIORITY_RT ); threadCreate( &proc->pthread_emulateRF, emulatedRF_thread, (void *)proc, "emulateRF", -1, OAI_PRIORITY_RT );
...@@ -1421,7 +1419,12 @@ void init_RU_proc(RU_t *ru) { ...@@ -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 ); threadCreate( &ru->ru_stats_thread, ru_stats_thread, (void *)ru,"ru_stats", -1, OAI_PRIORITY_RT );
if (get_thread_worker_conf() == WORKER_ENABLE) { 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) { ...@@ -1875,6 +1878,12 @@ void init_NR_RU(char *rf_config_file) {
LOG_D(HW,"[nr-softmodem.c] RU threads created\n"); 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) { void stop_RU(int nb_ru) {
for (int inst = 0; inst < nb_ru; inst++) { for (int inst = 0; inst < nb_ru; inst++) {
......
...@@ -289,16 +289,14 @@ void exit_function(const char *file, const char *function, const int line, const ...@@ -289,16 +289,14 @@ void exit_function(const char *file, const char *function, const int line, const
} }
} }
static int create_gNB_tasks(ngran_node_t node_type)
{
static int create_gNB_tasks(void) {
uint32_t gnb_nb = RC.nb_nr_inst; uint32_t gnb_nb = RC.nb_nr_inst;
uint32_t gnb_id_start = 0; uint32_t gnb_id_start = 0;
uint32_t gnb_id_end = gnb_id_start + gnb_nb; uint32_t gnb_id_end = gnb_id_start + gnb_nb;
LOG_D(GNB_APP, "%s(gnb_nb:%d)\n", __FUNCTION__, gnb_nb); LOG_D(GNB_APP, "%s(gnb_nb:%d)\n", __FUNCTION__, gnb_nb);
itti_wait_ready(1); itti_wait_ready(1);
LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__); LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__);
ngran_node_t node_type = get_node_type();
RCconfig_NR_L1(); RCconfig_NR_L1();
RCconfig_nr_prs(); RCconfig_nr_prs();
...@@ -634,8 +632,9 @@ int main( int argc, char **argv ) { ...@@ -634,8 +632,9 @@ int main( int argc, char **argv ) {
RCconfig_NR_L1(); RCconfig_NR_L1();
// don't create if node doesn't connect to RRC/S1/GTP // 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) { 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"); AssertFatal(ret == 0, "cannot create ITTI tasks\n");
} }
...@@ -735,6 +734,13 @@ int main( int argc, char **argv ) { ...@@ -735,6 +734,13 @@ int main( int argc, char **argv ) {
wait_nfapi_init("main?"); 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) { if (RC.nb_nr_L1_inst > 0) {
printf("wait RUs\n"); printf("wait RUs\n");
wait_RUs(); wait_RUs();
......
...@@ -54,6 +54,7 @@ extern void kill_gNB_proc(int inst); ...@@ -54,6 +54,7 @@ extern void kill_gNB_proc(int inst);
// In nr-ru.c // In nr-ru.c
extern void init_NR_RU(char *); extern void init_NR_RU(char *);
extern void init_RU_proc(RU_t *ru); extern void init_RU_proc(RU_t *ru);
extern void start_NR_RU(void);
extern void stop_RU(int nb_ru); extern void stop_RU(int nb_ru);
extern void kill_NR_RU_proc(int inst); extern void kill_NR_RU_proc(int inst);
extern void set_function_spec_param(RU_t *ru); extern void set_function_spec_param(RU_t *ru);
......
...@@ -2039,6 +2039,26 @@ int RC_config_trigger_F1Setup() ...@@ -2039,6 +2039,26 @@ int RC_config_trigger_F1Setup()
return 0; 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) 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; return plmn->mcc == check_plmn->mcc && plmn->mnc_digit_length == check_plmn->mnc_digit_length && plmn->mnc == check_plmn->mnc;
......
...@@ -104,6 +104,7 @@ void RCconfig_NRRRC(gNB_RRC_INST *rrc); ...@@ -104,6 +104,7 @@ void RCconfig_NRRRC(gNB_RRC_INST *rrc);
int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i); int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i);
int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i); int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i);
int RC_config_trigger_F1Setup(void); 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); 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); MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process);
ngran_node_t get_node_type(void); ngran_node_t get_node_type(void);
......
...@@ -58,9 +58,13 @@ void f1_setup_response(const f1ap_setup_resp_t *resp) ...@@ -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"); 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) void f1_setup_failure(const f1ap_setup_failure_t *failure)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment