]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add a reattach command for fast reassociate-back-to-same-BSS
authorPeter Qiu <zqiu@chromium.org>
Thu, 6 Mar 2014 18:06:04 +0000 (10:06 -0800)
committerJouni Malinen <j@w1.fi>
Tue, 11 Mar 2014 17:38:01 +0000 (19:38 +0200)
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 <zqiu@chromium.org>

wpa_supplicant/ctrl_iface.c
wpa_supplicant/dbus/dbus_new.c
wpa_supplicant/dbus/dbus_new_handlers.c
wpa_supplicant/dbus/dbus_new_handlers.h
wpa_supplicant/scan.c
wpa_supplicant/wpa_cli.c
wpa_supplicant/wpa_supplicant_i.h

index 7ef88712c280e07ac639467aa8cec6c97d1f807f..98c4b65541100ecafc882ebad2efd8354315e9d1 100644 (file)
@@ -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;
index f40d4219e5685d729ca27622ec609971f9bf3a4a..5e02956b4cf4803da546047abf622d078a553e58 100644 (file)
@@ -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,
          {
index bfb33d5d235dde119cbae1ab642148d3c062b684..5466d16cd559d4feaea726fd802f7a9a91a7ed09 100644 (file)
@@ -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
index c0669445eb8571f3f371ddb0990e8a242001e3a1..461970d3f0fc2ae2988a0b4fd0c3ad72524d49fa 100644 (file)
@@ -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);
 
index 8e35fcc3cad5324124b910bb08cdde97e86ace56..1d8e8a60958bc326512447de2220dcabeaa50cc7 100644 (file)
@@ -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;
index 63ea1df9361902edd315d52ed16f8d3f0495bdb2..2a9ab7fe014314b76bfbf8df3ed90e7987bb6c63 100644 (file)
@@ -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,
          "<BSSID> = force preauthentication" },
index fd162d72576dea8e52bb5358659c7ddcc2203261..739b11f702b9d296377d5c3c38bd5c27daae0049 100644 (file)
@@ -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;