nl80211/SME: Use reassociation when roaming within the ESS
authorJouni Malinen <j@w1.fi>
Tue, 17 Nov 2009 17:25:05 +0000 (19:25 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 17 Nov 2009 17:25:05 +0000 (19:25 +0200)
src/drivers/driver.h
src/drivers/driver_nl80211.c
wpa_supplicant/events.c
wpa_supplicant/sme.c
wpa_supplicant/wpa_supplicant_i.h

index 89400cd..7365847 100644 (file)
@@ -409,6 +409,14 @@ struct wpa_driver_associate_params {
         * still be allowed for key negotiation.
         */
        int drop_unencrypted;
+
+       /**
+        * prev_bssid - Previously used BSSID in this ESS
+        *
+        * When not %NULL, this is a request to use reassociation instead of
+        * association.
+        */
+       const u8 *prev_bssid;
 };
 
 /**
index 97348ef..ac3f4dd 100644 (file)
@@ -3599,6 +3599,13 @@ static int wpa_driver_nl80211_associate(
 
        NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT);
 
+       if (params->prev_bssid) {
+               wpa_printf(MSG_DEBUG, "  * prev_bssid=" MACSTR,
+                          MAC2STR(params->prev_bssid));
+               NLA_PUT(msg, NL80211_ATTR_PREV_BSSID, ETH_ALEN,
+                       params->prev_bssid);
+       }
+
        ret = send_and_recv_msgs(drv, msg, NULL, NULL);
        msg = NULL;
        if (ret) {
index 896452d..5f55180 100644 (file)
@@ -983,6 +983,11 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
                }
        }
 
+#ifdef CONFIG_SME
+       os_memcpy(wpa_s->sme.prev_bssid, bssid, ETH_ALEN);
+       wpa_s->sme.prev_bssid_set = 1;
+#endif /* CONFIG_SME */
+
        wpa_msg(wpa_s, MSG_INFO, "Associated with " MACSTR, MAC2STR(bssid));
        if (wpa_s->current_ssid) {
                /* When using scanning (ap_scan=1), SIM PC/SC interface can be
index e148595..7b2764c 100644 (file)
@@ -59,6 +59,10 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
        params.ssid = ie + 2;
        params.ssid_len = ie[1];
 
+       if (wpa_s->sme.ssid_len != params.ssid_len ||
+           os_memcmp(wpa_s->sme.ssid, params.ssid, params.ssid_len) != 0)
+               wpa_s->sme.prev_bssid_set = 0;
+
        wpa_s->sme.freq = params.freq;
        os_memcpy(wpa_s->sme.ssid, params.ssid, params.ssid_len);
        wpa_s->sme.ssid_len = params.ssid_len;
@@ -312,6 +316,8 @@ void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data)
 #endif /* CONFIG_IEEE80211R */
        params.mode = ssid->mode;
        params.mgmt_frame_protection = wpa_s->sme.mfp;
+       if (wpa_s->sme.prev_bssid_set)
+               params.prev_bssid = wpa_s->sme.prev_bssid;
 
        wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
                " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid),
@@ -378,6 +384,7 @@ void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
                wpa_msg(wpa_s, MSG_INFO,
                        "Deauth request to the driver failed");
        }
+       wpa_s->sme.prev_bssid_set = 0;
 
        if (wpa_blacklist_add(wpa_s, wpa_s->pending_bssid) == 0) {
                struct wpa_blacklist *b;
index 193baa3..7cd2426 100644 (file)
@@ -407,6 +407,8 @@ struct wpa_supplicant {
                u8 mobility_domain[2];
                u8 *ft_ies;
                size_t ft_ies_len;
+               u8 prev_bssid[ETH_ALEN];
+               int prev_bssid_set;
        } sme;
 #endif /* CONFIG_SME */