summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-01-07 10:39:59 +0100
committerAndreas Eversberg <jolly@eversberg.eu>2013-01-07 10:39:59 +0100
commit25c5e8221d94a7a5885d3bcd38d35da86bf17313 (patch)
tree9066ba3693795a5815f3504eb2c7c7ed9f3cb9a6
parentee7fbbda22aedcdd8b6e3a5828fbdafd84571d72 (diff)
mobile: Improved exit of mobile process, reset phone
If mobile phone has started, it is reset after shutdown. This ensures that the phone is not transmitting anymore, especially while shutting down in dedicated mode. Using CTRL+c: 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) Using CTRL+z: The first signal causes initiating of shutdown without detach procedure. A subsequent CTRL+c would exit process immidiately.
-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)) {