From 384886ce48607772793db6598dc21faba633df0b Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 24 Mar 2026 14:01:21 +0100 Subject: [PATCH] Ensure trx_stop is called before trx_end Make sure the radio libs are stopped before `end()` call. This allows for a cleaner exit under most circumstances. Some libraries like zmq_radio don't exit cleanly without it. --- executables/nr-softmodem.c | 23 +++++++++++++++++------ executables/nr-ue-ru.c | 8 ++++++++ executables/nr-ue-ru.h | 1 + executables/nr-uesoftmodem.c | 3 +++ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 1198e5bd02..aa33fc5f5d 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -131,13 +131,18 @@ void exit_function(const char *file, const char *function, const int line, const printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); } - oai_exit = 1; - if (RC.ru == NULL) exit(-1); // likely init not completed, prevent crash or hang, exit now... for (ru_id=0; ru_idrfdevice.trx_end_func) { + if (RC.ru[ru_id] == NULL) { + continue; + } + if (RC.ru[ru_id]->ifdevice.trx_stop_func) { + RC.ru[ru_id]->ifdevice.trx_stop_func(&RC.ru[ru_id]->ifdevice); + RC.ru[ru_id]->ifdevice.trx_stop_func = NULL; + } + if (RC.ru[ru_id]->rfdevice.trx_end_func) { if (RC.ru[ru_id]->rfdevice.trx_get_stats_func) { RC.ru[ru_id]->rfdevice.trx_get_stats_func(&RC.ru[ru_id]->rfdevice); RC.ru[ru_id]->rfdevice.trx_get_stats_func = NULL; @@ -146,6 +151,10 @@ void exit_function(const char *file, const char *function, const int line, const RC.ru[ru_id]->rfdevice.trx_end_func = NULL; } + if (RC.ru[ru_id]->ifdevice.trx_stop_func) { + RC.ru[ru_id]->ifdevice.trx_stop_func(&RC.ru[ru_id]->ifdevice); + RC.ru[ru_id]->ifdevice.trx_stop_func = NULL; + } if (RC.ru[ru_id] && RC.ru[ru_id]->ifdevice.trx_end_func) { if (RC.ru[ru_id]->ifdevice.trx_get_stats_func) { RC.ru[ru_id]->ifdevice.trx_get_stats_func(&RC.ru[ru_id]->ifdevice); @@ -156,6 +165,8 @@ void exit_function(const char *file, const char *function, const int line, const } } + oai_exit = 1; + if (assert) { abort(); } else { @@ -358,9 +369,6 @@ int stop_L1(module_id_t gnb_id) if (RC.nb_nr_L1_inst > 0) stop_gNB(RC.nb_nr_L1_inst); - if (RC.nb_RU > 0) - stop_RU(RC.nb_RU); - /* stop trx devices, multiple carrier currently not supported by RU */ if (ru->rfdevice.trx_get_stats_func) { ru->rfdevice.trx_get_stats_func(&ru->rfdevice); @@ -378,6 +386,9 @@ int stop_L1(module_id_t gnb_id) LOG_I(GNB_APP, "turned off RU ifdevice\n"); } + if (RC.nb_RU > 0) + stop_RU(RC.nb_RU); + /* release memory used by the RU/gNB threads (incomplete), after all * threads have been stopped (they partially use the same memory) */ for (int inst = 0; inst < RC.nb_RU; inst++) { diff --git a/executables/nr-ue-ru.c b/executables/nr-ue-ru.c index 52b234a137..1b0817478e 100644 --- a/executables/nr-ue-ru.c +++ b/executables/nr-ue-ru.c @@ -352,6 +352,14 @@ void nrue_ru_start(void) } } +void nrue_ru_stop(void) +{ + for (int ru_id = 0; ru_id < nrue_ru_count; ru_id++) { + if (openair0_dev[ru_id].trx_stop_func) + openair0_dev[ru_id].trx_stop_func(&openair0_dev[ru_id]); + } +} + void nrue_ru_end(void) { for (int ru_id = 0; ru_id < nrue_ru_count; ru_id++) { diff --git a/executables/nr-ue-ru.h b/executables/nr-ue-ru.h index 2bbd2dea89..7d0836c050 100644 --- a/executables/nr-ue-ru.h +++ b/executables/nr-ue-ru.h @@ -22,6 +22,7 @@ void nrue_set_ru_params(configmodule_interface_t *cfg); void nrue_init_openair0(void); void nrue_ru_start(void); +void nrue_ru_stop(void); void nrue_ru_end(void); void nrue_ru_set_freq(PHY_VARS_NR_UE *UE, uint64_t ul_carrier, uint64_t dl_carrier, int freq_offset); int nrue_ru_adjust_rx_gain(PHY_VARS_NR_UE *UE, int gain_change); diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 2069da4c00..7997f72ef5 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -112,6 +112,7 @@ void exit_function(const char *file, const char *function, const int line, const oai_exit = 1; + nrue_ru_stop(); nrue_ru_end(); if (assert) { @@ -457,6 +458,8 @@ int main(int argc, char **argv) LOG_W(NR_PHY, "Returned from ITTI signal handler\n"); oai_exit = 1; + nrue_ru_stop(); + if (PHY_vars_UE_g && PHY_vars_UE_g[0]) { for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { PHY_VARS_NR_UE *phy_vars = PHY_vars_UE_g[0][CC_id];