From 0f44ec8eba8a2b01e9c443308a72a2fd3208f7cf Mon Sep 17 00:00:00 2001 From: Peter Qiu Date: Thu, 6 Mar 2014 10:06:04 -0800 Subject: [PATCH] Add a reattach command for fast reassociate-back-to-same-BSS Add "reattach" command to perform single-channel single-ssid scan instead of full scan when trying to reconnect to the currently "connected" network (assuming old scan results are not current enough to skip the scan completely). This allows the scan result to come back in much faster time. In ath9k, the scan took around 12 seconds with full background scan, and only 0.1 second with the single-channel single-ssid scan. Thus, take much less time for the client to re-establish connection with the currently "connected" network. Signed-hostap: Peter Qiu --- wpa_supplicant/ctrl_iface.c | 8 +++++++ wpa_supplicant/dbus/dbus_new.c | 6 +++++ wpa_supplicant/dbus/dbus_new_handlers.c | 23 +++++++++++++++++++ wpa_supplicant/dbus/dbus_new_handlers.h | 3 +++ wpa_supplicant/scan.c | 30 +++++++++++++++++++++++++ wpa_supplicant/wpa_cli.c | 9 ++++++++ wpa_supplicant/wpa_supplicant_i.h | 1 + 7 files changed, 80 insertions(+) diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 7ef88712c..98c4b6554 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -5963,6 +5963,14 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, reply_len = -1; else wpas_request_connection(wpa_s); + } else if (os_strcmp(buf, "REATTACH") == 0) { + if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED || + !wpa_s->current_ssid) + reply_len = -1; + else { + wpa_s->reattach = 1; + wpas_request_connection(wpa_s); + } } else if (os_strcmp(buf, "RECONNECT") == 0) { if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) reply_len = -1; diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c index f40d4219e..5e02956b4 100644 --- a/wpa_supplicant/dbus/dbus_new.c +++ b/wpa_supplicant/dbus/dbus_new.c @@ -2462,6 +2462,12 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = { END_ARGS } }, + { "Reattach", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) &wpas_dbus_handler_reattach, + { + END_ARGS + } + }, { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, (WPADBusMethodHandler) &wpas_dbus_handler_remove_network, { diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index bfb33d5d2..5466d16cd 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -1486,6 +1486,29 @@ DBusMessage * wpas_dbus_handler_reassociate(DBusMessage *message, } +/** + * wpas_dbus_handler_reattach - Reattach to current AP + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: NotConnected DBus error message if not connected + * or NULL otherwise. + * + * Handler function for "Reattach" method call of network interface. + */ +DBusMessage * wpas_dbus_handler_reattach(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + if (wpa_s->current_ssid != NULL) { + wpa_s->reattach = 1; + wpas_request_connection(wpa_s); + return NULL; + } + + return dbus_message_new_error(message, WPAS_DBUS_ERROR_NOT_CONNECTED, + "This interface is not connected"); +} + + /** * wpas_dbus_handler_remove_network - Remove a configured network * @message: Pointer to incoming dbus message diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h index c0669445e..461970d3f 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.h +++ b/wpa_supplicant/dbus/dbus_new_handlers.h @@ -101,6 +101,9 @@ DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message, DBusMessage * wpas_dbus_handler_reassociate(DBusMessage *message, struct wpa_supplicant *wpa_s); +DBusMessage * wpas_dbus_handler_reattach(DBusMessage *message, + struct wpa_supplicant *wpa_s); + DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message, struct wpa_supplicant *wpa_s); diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index 8e35fcc3c..1d8e8a609 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -665,6 +665,36 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) * wildcard SSID. */ ssid = NULL; + } else if (wpa_s->reattach && wpa_s->current_ssid != NULL) { + /* + * Perform single-channel single-SSID scan for + * reassociate-to-same-BSS operation. + */ + /* Setup SSID */ + ssid = wpa_s->current_ssid; + wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID", + ssid->ssid, ssid->ssid_len); + params.ssids[0].ssid = ssid->ssid; + params.ssids[0].ssid_len = ssid->ssid_len; + params.num_ssids = 1; + + /* + * Allocate memory for frequency array, allocate one extra + * slot for the zero-terminator. + */ + params.freqs = os_malloc(sizeof(int) * 2); + if (params.freqs == NULL) { + wpa_dbg(wpa_s, MSG_ERROR, "Memory allocation failed"); + return; + } + params.freqs[0] = wpa_s->assoc_freq; + params.freqs[1] = 0; + + /* + * Reset the reattach flag so that we fall back to full scan if + * this scan fails. + */ + wpa_s->reattach = 0; } else { struct wpa_ssid *start = ssid, *tssid; int freqs_set = 0; diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 63ea1df93..2a9ab7fe0 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -676,6 +676,12 @@ static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc, } +static int wpa_cli_cmd_reattach(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + return wpa_ctrl_command(ctrl, "REATTACH"); +} + + static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc, char *argv[]) { @@ -2510,6 +2516,9 @@ static struct wpa_cli_cmd wpa_cli_commands[] = { { "reassociate", wpa_cli_cmd_reassociate, NULL, cli_cmd_flag_none, "= force reassociation" }, + { "reattach", wpa_cli_cmd_reattach, NULL, + cli_cmd_flag_none, + "= force reassociation back to the same BSS" }, { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss, cli_cmd_flag_none, " = force preauthentication" }, diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index fd162d725..739b11f70 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -594,6 +594,7 @@ struct wpa_supplicant { u8 pending_eapol_rx_src[ETH_ALEN]; unsigned int last_eapol_matches_bssid:1; unsigned int eap_expected_failure:1; + unsigned int reattach:1; /* reassociation to the same BSS requested */ struct ibss_rsn *ibss_rsn;