aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2010-02-27 16:46:02 (GMT)
committerJouni Malinen <j@w1.fi>2010-02-27 16:46:02 (GMT)
commit207ef3fb12b713e9432d0eca81d0632c124ee271 (patch)
treeb41a27b6d443e24d88e7b250a6075cc45c8083ad /wpa_supplicant
parentbe8be6717d0fc9568b436826453ed8541a017f5b (diff)
downloadhostap-207ef3fb12b713e9432d0eca81d0632c124ee271.zip
hostap-207ef3fb12b713e9432d0eca81d0632c124ee271.tar.gz
hostap-207ef3fb12b713e9432d0eca81d0632c124ee271.tar.bz2
Add suspend/resume notifications
wpa_supplicant can now be notified of suspend/resume events, e.g., from pm-action scripts. This allows wpa_supplicant to clear information that may become invalid during a suspend operation.
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/ctrl_iface.c10
-rw-r--r--wpa_supplicant/driver_i.h12
-rwxr-xr-xwpa_supplicant/examples/60_wpa_supplicant17
-rw-r--r--wpa_supplicant/notify.c38
-rw-r--r--wpa_supplicant/notify.h4
-rw-r--r--wpa_supplicant/scan.c4
-rw-r--r--wpa_supplicant/wpa_cli.c16
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h3
8 files changed, 100 insertions, 4 deletions
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 7242e5c..33a1d94 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -1,6 +1,6 @@
/*
* WPA Supplicant / Control interface (shared code for all backends)
- * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -1812,6 +1812,10 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
reply_size);
#endif /* CONFIG_AP */
+ } else if (os_strcmp(buf, "SUSPEND") == 0) {
+ wpas_notify_suspend(wpa_s->global);
+ } else if (os_strcmp(buf, "RESUME") == 0) {
+ wpas_notify_resume(wpa_s->global);
} else {
os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
reply_len = 16;
@@ -2038,6 +2042,10 @@ char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
global, reply, reply_size);
} else if (os_strcmp(buf, "TERMINATE") == 0) {
wpa_supplicant_terminate_proc(global);
+ } else if (os_strcmp(buf, "SUSPEND") == 0) {
+ wpas_notify_suspend(global);
+ } else if (os_strcmp(buf, "RESUME") == 0) {
+ wpas_notify_resume(global);
} else {
os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
reply_len = 16;
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index bd31253..7f64c4c 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -456,4 +456,16 @@ static inline int wpa_drv_deinit_ap(struct wpa_supplicant *wpa_s)
return 0;
}
+static inline void wpa_drv_suspend(struct wpa_supplicant *wpa_s)
+{
+ if (wpa_s->driver->suspend)
+ wpa_s->driver->suspend(wpa_s->drv_priv);
+}
+
+static inline void wpa_drv_resume(struct wpa_supplicant *wpa_s)
+{
+ if (wpa_s->driver->resume)
+ wpa_s->driver->resume(wpa_s->drv_priv);
+}
+
#endif /* DRIVER_I_H */
diff --git a/wpa_supplicant/examples/60_wpa_supplicant b/wpa_supplicant/examples/60_wpa_supplicant
new file mode 100755
index 0000000..f570ad3
--- /dev/null
+++ b/wpa_supplicant/examples/60_wpa_supplicant
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# /etc/pm/sleep.d/60_wpa_supplicant
+# Action script to notify wpa_supplicant of pm-action events.
+
+PATH=/sbin:/usr/sbin:/bin:/usr/bin
+
+WPACLI=wpa_cli
+
+case "$1" in
+ suspend|hibernate)
+ $WPACLI suspend
+ ;;
+ resume|thaw)
+ $WPACLI resume
+ ;;
+esac
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 6a55cdc..ac65b4f 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -1,6 +1,6 @@
/*
* wpa_supplicant - Event notifications
- * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -22,6 +22,8 @@
#include "dbus/dbus_common.h"
#include "dbus/dbus_old.h"
#include "dbus/dbus_new.h"
+#include "driver_i.h"
+#include "scan.h"
#include "notify.h"
int wpas_notify_supplicant_initialized(struct wpa_global *global)
@@ -301,3 +303,37 @@ void wpas_notify_debug_show_keys_changed(struct wpa_global *global)
{
wpas_dbus_signal_debug_show_keys_changed(global);
}
+
+
+void wpas_notify_suspend(struct wpa_global *global)
+{
+ struct wpa_supplicant *wpa_s;
+
+ os_get_time(&global->suspend_time);
+ wpa_printf(MSG_DEBUG, "System suspend notification");
+ for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
+ wpa_drv_suspend(wpa_s);
+}
+
+
+void wpas_notify_resume(struct wpa_global *global)
+{
+ struct os_time now;
+ int slept;
+ struct wpa_supplicant *wpa_s;
+
+ if (global->suspend_time.sec == 0)
+ slept = -1;
+ else {
+ os_get_time(&now);
+ slept = now.sec - global->suspend_time.sec;
+ }
+ wpa_printf(MSG_DEBUG, "System resume notification (slept %d seconds)",
+ slept);
+
+ for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
+ wpa_drv_resume(wpa_s);
+ if (wpa_s->wpa_state == WPA_DISCONNECTED)
+ wpa_supplicant_req_scan(wpa_s, 0, 100000);
+ }
+}
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 7b1febe..2e70bdb 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -1,6 +1,6 @@
/*
* wpa_supplicant - Event notifications
- * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -75,5 +75,7 @@ void wpas_notify_blob_removed(struct wpa_supplicant *wpa_s, const char *name);
void wpas_notify_debug_level_changed(struct wpa_global *global);
void wpas_notify_debug_timestamp_changed(struct wpa_global *global);
void wpas_notify_debug_show_keys_changed(struct wpa_global *global);
+void wpas_notify_suspend(struct wpa_global *global);
+void wpas_notify_resume(struct wpa_global *global);
#endif /* NOTIFY_H */
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 56f062f..9c61690 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -216,6 +216,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
#endif /* CONFIG_WPS */
struct wpa_driver_scan_params params;
size_t max_ssids;
+ enum wpa_states prev_state;
if (wpa_s->disconnected && !wpa_s->scan_req) {
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
@@ -271,6 +272,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
os_memset(&params, 0, sizeof(params));
+ prev_state = wpa_s->wpa_state;
if (wpa_s->wpa_state == WPA_DISCONNECTED ||
wpa_s->wpa_state == WPA_INACTIVE)
wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
@@ -368,6 +370,8 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
if (ret) {
wpa_printf(MSG_WARNING, "Failed to initiate AP scan.");
+ if (prev_state != wpa_s->wpa_state)
+ wpa_supplicant_set_state(wpa_s, prev_state);
wpa_supplicant_req_scan(wpa_s, 10, 0);
} else
wpa_s->scan_runs++;
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index d3b9e1f..518afa0 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -1403,6 +1403,18 @@ static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
#endif /* CONFIG_AP */
+static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+ return wpa_ctrl_command(ctrl, "SUSPEND");
+}
+
+
+static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+ return wpa_ctrl_command(ctrl, "RESUME");
+}
+
+
enum wpa_cli_cmd_flags {
cli_cmd_flag_none = 0x00,
cli_cmd_flag_sensitive = 0x01
@@ -1597,6 +1609,10 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
cli_cmd_flag_none,
"= get information about all associated stations (AP)" },
#endif /* CONFIG_AP */
+ { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
+ "= notification of suspend/hibernate" },
+ { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
+ "= notification of resume/thaw" },
{ NULL, NULL, cli_cmd_flag_none, NULL }
};
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index c96fd3b..bc56517 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1,6 +1,6 @@
/*
* wpa_supplicant - Internal definitions
- * Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -194,6 +194,7 @@ struct wpa_global {
struct wpas_dbus_priv *dbus;
void **drv_priv;
size_t drv_count;
+ struct os_time suspend_time;
};