summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/host/layer23/src/mobile/app_mobile.c30
-rw-r--r--src/host/layer23/src/mobile/main.c47
-rw-r--r--src/host/layer23/src/mobile/vty_interface.c4
3 files changed, 62 insertions, 19 deletions
diff --git a/src/host/layer23/src/mobile/app_mobile.c b/src/host/layer23/src/mobile/app_mobile.c
index dc57c315..67aba05a 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 312bcd66..8bcecba3 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 4d7f6a27..95653c78 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)) {