]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Allow driver-based roam to change ESS
authorKrishna Vamsi <vamsin@qti.qualcomm.com>
Fri, 13 Mar 2015 12:29:20 +0000 (17:59 +0530)
committerJouni Malinen <j@w1.fi>
Tue, 24 Mar 2015 19:13:28 +0000 (21:13 +0200)
This extends NL80211_CMD_ROAM event processing to allow the driver to
roam to another ESS (different SSID) when using offloaded BSS selection.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/drivers/driver_nl80211.h
src/drivers/driver_nl80211_event.c
src/drivers/driver_nl80211_scan.c
wpa_supplicant/events.c

index 802589aa7581212a6902f8305a96634828f71b88..64c4665de301b1f73e74fcbe2955b6c67cd31510 100644 (file)
@@ -270,5 +270,6 @@ int wpa_driver_nl80211_sched_scan(void *priv,
 int wpa_driver_nl80211_stop_sched_scan(void *priv);
 struct wpa_scan_results * wpa_driver_nl80211_get_scan_results(void *priv);
 void nl80211_dump_scan(struct wpa_driver_nl80211_data *drv);
+const u8 * nl80211_get_ie(const u8 *ies, size_t ies_len, u8 ie);
 
 #endif /* DRIVER_NL80211_H */
index a5b323026649c99566a4fb8092f20ff2b299faca..8cebfb25616de645d109576f4f3877712ad2f5ac 100644 (file)
@@ -271,6 +271,7 @@ static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
                               struct nlattr *ptk_kek)
 {
        union wpa_event_data event;
+       const u8 *ssid;
        u16 status_code;
 
        if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
@@ -331,6 +332,16 @@ static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
        if (req_ie) {
                event.assoc_info.req_ies = nla_data(req_ie);
                event.assoc_info.req_ies_len = nla_len(req_ie);
+
+               if (cmd == NL80211_CMD_ROAM) {
+                       ssid = nl80211_get_ie(event.assoc_info.req_ies,
+                                             event.assoc_info.req_ies_len,
+                                             WLAN_EID_SSID);
+                       if (ssid && ssid[1] > 0 && ssid[1] <= 32) {
+                               drv->ssid_len = ssid[1];
+                               os_memcpy(drv->ssid, ssid + 2, ssid[1]);
+                       }
+               }
        }
        if (resp_ie) {
                event.assoc_info.resp_ies = nla_data(resp_ie);
index 3911f485f72e436ca8557190d0a920ddf5b17726..9cd3162ff711e405bbe5a92127e495b9f0e253fa 100644 (file)
@@ -433,7 +433,7 @@ int wpa_driver_nl80211_stop_sched_scan(void *priv)
 }
 
 
-static const u8 * nl80211_get_ie(const u8 *ies, size_t ies_len, u8 ie)
+const u8 * nl80211_get_ie(const u8 *ies, size_t ies_len, u8 ie)
 {
        const u8 *end, *pos;
 
index 3adb95427208ad6f429afe4eeb16c0891322607b..b10f583cdc76b2ac5452098a350047e9fcc236f7 100644 (file)
@@ -158,11 +158,32 @@ static void wpa_supplicant_update_current_bss(struct wpa_supplicant *wpa_s)
 static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
 {
        struct wpa_ssid *ssid, *old_ssid;
+       u8 drv_ssid[MAX_SSID_LEN];
+       size_t drv_ssid_len;
        int res;
 
        if (wpa_s->conf->ap_scan == 1 && wpa_s->current_ssid) {
                wpa_supplicant_update_current_bss(wpa_s);
-               return 0;
+
+               if (wpa_s->current_ssid->ssid_len == 0)
+                       return 0; /* current profile still in use */
+               res = wpa_drv_get_ssid(wpa_s, drv_ssid);
+               if (res < 0) {
+                       wpa_msg(wpa_s, MSG_INFO,
+                               "Failed to read SSID from driver");
+                       return 0; /* try to use current profile */
+               }
+               drv_ssid_len = res;
+
+               if (drv_ssid_len == wpa_s->current_ssid->ssid_len &&
+                   os_memcmp(drv_ssid, wpa_s->current_ssid->ssid,
+                             drv_ssid_len) == 0)
+                       return 0; /* current profile still in use */
+
+               wpa_msg(wpa_s, MSG_DEBUG,
+                       "Driver-initiated BSS selection changed the SSID to %s",
+                       wpa_ssid_txt(drv_ssid, drv_ssid_len));
+               /* continue selecting a new network profile */
        }
 
        wpa_dbg(wpa_s, MSG_DEBUG, "Select network based on association "