diff --git a/src/host/layer23/src/mobile/app_mobile.c b/src/host/layer23/src/mobile/app_mobile.c index dc57c3158..67aba05ab 100644 --- a/src/host/layer23/src/mobile/app_mobile.c +++ b/src/host/layer23/src/mobile/app_mobile.c @@ -93,6 +93,13 @@ int mobile_signal_cb(unsigned int subsys, unsigned int signal, ms = signal_data; set = &ms->settings; + /* waiting for reset after shutdown */ + if (ms->shutdown == 2) { + printf("MS '%s' has been resetted\n", ms->name); + ms->shutdown = 3; + break; + } + if (ms->started) break; @@ -129,6 +136,10 @@ int mobile_exit(struct osmocom_ms *ms, int force) { struct gsm48_mmlayer *mm = &ms->mmlayer; + /* if shutdown is already performed */ + if (ms->shutdown >= 2) + return 0; + if (!force && ms->started) { struct msgb *nmsg; @@ -151,7 +162,12 @@ int mobile_exit(struct osmocom_ms *ms, int force) gsm_sim_exit(ms); lapdm_channel_exit(&ms->lapdm_channel); - ms->shutdown = 2; /* being down */ + if (ms->started) { + ms->shutdown = 2; /* being down, wait for reset */ + l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL); + } else { + ms->shutdown = 3; /* being down */ + } vty_notify(ms, NULL); vty_notify(ms, "Power off!\n"); printf("Power off! (MS %s)\n", ms->name); @@ -241,7 +257,7 @@ struct osmocom_ms *mobile_new(char *name) gsm_support_init(ms); gsm_settings_init(ms); - ms->shutdown = 2; /* being down */ + ms->shutdown = 3; /* being down */ if (mncc_recv_app) { char name[32]; @@ -292,10 +308,14 @@ int global_signal_cb(unsigned int subsys, unsigned int signal, switch (signal) { case S_GLOBAL_SHUTDOWN: + /* force to exit, if signalled */ + if (signal_data && *((uint8_t *)signal_data)) + quit = 1; + llist_for_each_entry_safe(ms, ms2, &ms_list, entity) mobile_delete(ms, quit); - /* if second signal is received, force to exit */ + /* quit, after all MS processes are gone */ quit = 1; break; } @@ -309,9 +329,9 @@ int l23_app_work(int *_quit) int work = 0; llist_for_each_entry_safe(ms, ms2, &ms_list, entity) { - if (ms->shutdown != 2) + if (ms->shutdown != 3) work |= mobile_work(ms); - if (ms->shutdown == 2) { + if (ms->shutdown == 3) { if (ms->l2_wq.bfd.fd > -1) { layer2_close(ms); ms->l2_wq.bfd.fd = -1; diff --git a/src/host/layer23/src/mobile/main.c b/src/host/layer23/src/mobile/main.c index 312bcd664..8bcecba3d 100644 --- a/src/host/layer23/src/mobile/main.c +++ b/src/host/layer23/src/mobile/main.c @@ -153,25 +153,38 @@ static void handle_options(int argc, char **argv) void sighandler(int sigset) { + static uint8_t _quit = 1, count_int = 0; + if (sigset == SIGHUP || sigset == SIGPIPE) return; - fprintf(stderr, "Signal %d received.\n", sigset); + fprintf(stderr, "\nSignal %d received.\n", sigset); switch (sigset) { case SIGINT: - /* If another signal is received afterwards, the program - * is terminated without finishing shutdown process. + /* The first signal causes initiating of shutdown with detach + * procedure. The second signal causes initiating of shutdown + * without detach procedure. The third signal will exit process + * immidiately. (in case it hangs) */ - signal(SIGINT, SIG_DFL); - signal(SIGHUP, SIG_DFL); - signal(SIGTERM, SIG_DFL); - signal(SIGPIPE, SIG_DFL); - signal(SIGABRT, SIG_DFL); - signal(SIGUSR1, SIG_DFL); - signal(SIGUSR2, SIG_DFL); - - osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL); + if (count_int == 0) { + fprintf(stderr, "Performing shutdown with clean " + "detach, if possible...\n"); + osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, + NULL); + count_int = 1; + break; + } + if (count_int == 2) { + fprintf(stderr, "Unclean exit, please turn off phone " + "to be sure it is not transmitting!\n"); + exit(0); + } + /* fall through */ + case SIGTSTP: + count_int = 2; + fprintf(stderr, "Performing shutdown without detach...\n"); + osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, &_quit); break; case SIGABRT: /* in case of abort, we want to obtain a talloc report @@ -240,6 +253,7 @@ int main(int argc, char **argv) exit(rc); signal(SIGINT, sighandler); + signal(SIGTSTP, sighandler); signal(SIGHUP, sighandler); signal(SIGTERM, sighandler); signal(SIGPIPE, sighandler); @@ -267,5 +281,14 @@ int main(int argc, char **argv) talloc_free(config_dir); talloc_report_full(l23_ctx, stderr); + signal(SIGINT, SIG_DFL); + signal(SIGTSTP, SIG_DFL); + signal(SIGHUP, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGPIPE, SIG_DFL); + signal(SIGABRT, SIG_DFL); + signal(SIGUSR1, SIG_DFL); + signal(SIGUSR2, SIG_DFL); + return 0; } diff --git a/src/host/layer23/src/mobile/vty_interface.c b/src/host/layer23/src/mobile/vty_interface.c index 4d7f6a274..95653c78f 100644 --- a/src/host/layer23/src/mobile/vty_interface.c +++ b/src/host/layer23/src/mobile/vty_interface.c @@ -2607,11 +2607,11 @@ DEFUN(cfg_no_shutdown, cfg_ms_no_shutdown_cmd, "no shutdown", struct osmocom_ms *ms = vty->index, *tmp; int rc; - if (ms->shutdown != 2) + if (ms->shutdown != 3) return CMD_SUCCESS; llist_for_each_entry(tmp, &ms_list, entity) { - if (tmp->shutdown == 2) + if (tmp->shutdown == 3) continue; if (!strcmp(ms->settings.layer2_socket_path, tmp->settings.layer2_socket_path)) {