Use BSS entries instead of scan results for BSS selection
authorJouni Malinen <j@w1.fi>
Sun, 2 Sep 2012 16:56:57 +0000 (19:56 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 2 Sep 2012 16:56:57 +0000 (19:56 +0300)
This allows the BSS selection functions to be called without having the
scan result data structure. This can be used to skip extra scans in
cases where previous results can be considered fresh.

Signed-hostap: Jouni Malinen <j@w1.fi>

wpa_supplicant/events.c
wpa_supplicant/wps_supplicant.c
wpa_supplicant/wps_supplicant.h

index d9dfb93..ee0ebe2 100644 (file)
@@ -321,7 +321,7 @@ int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
 
 
 #ifndef CONFIG_NO_SCAN_PROCESSING
-static int wpa_supplicant_match_privacy(struct wpa_scan_res *bss,
+static int wpa_supplicant_match_privacy(struct wpa_bss *bss,
                                        struct wpa_ssid *ssid)
 {
        int i, privacy = 0;
@@ -358,7 +358,7 @@ static int wpa_supplicant_match_privacy(struct wpa_scan_res *bss,
 
 static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
                                         struct wpa_ssid *ssid,
-                                        struct wpa_scan_res *bss)
+                                        struct wpa_bss *bss)
 {
        struct wpa_ie_data ie;
        int proto_match = 0;
@@ -376,7 +376,7 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
                  ssid->wep_key_len[ssid->wep_tx_keyidx] > 0) ||
                 (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA));
 
-       rsn_ie = wpa_scan_get_ie(bss, WLAN_EID_RSN);
+       rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
        while ((ssid->proto & WPA_PROTO_RSN) && rsn_ie) {
                proto_match++;
 
@@ -431,7 +431,7 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
                return 1;
        }
 
-       wpa_ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
+       wpa_ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
        while ((ssid->proto & WPA_PROTO_WPA) && wpa_ie) {
                proto_match++;
 
@@ -533,7 +533,7 @@ static int ht_supported(const struct hostapd_hw_modes *mode)
 }
 
 
-static int rate_match(struct wpa_supplicant *wpa_s, struct wpa_scan_res *bss)
+static int rate_match(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
 {
        const struct hostapd_hw_modes *mode = NULL, *modes;
        const u8 scan_ie[2] = { WLAN_EID_SUPP_RATES, WLAN_EID_EXT_SUPP_RATES };
@@ -571,7 +571,7 @@ static int rate_match(struct wpa_supplicant *wpa_s, struct wpa_scan_res *bss)
                return 0;
 
        for (i = 0; i < (int) sizeof(scan_ie); i++) {
-               rate_ie = wpa_scan_get_ie(bss, scan_ie[i]);
+               rate_ie = wpa_bss_get_ie(bss, scan_ie[i]);
                if (rate_ie == NULL)
                        continue;
 
@@ -625,31 +625,26 @@ static int rate_match(struct wpa_supplicant *wpa_s, struct wpa_scan_res *bss)
 
 
 static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
-                                           int i, struct wpa_scan_res *bss,
+                                           int i, struct wpa_bss *bss,
                                            struct wpa_ssid *group)
 {
-       const u8 *ssid_;
-       u8 wpa_ie_len, rsn_ie_len, ssid_len;
+       u8 wpa_ie_len, rsn_ie_len;
        int wpa;
        struct wpa_blacklist *e;
        const u8 *ie;
        struct wpa_ssid *ssid;
 
-       ie = wpa_scan_get_ie(bss, WLAN_EID_SSID);
-       ssid_ = ie ? ie + 2 : (u8 *) "";
-       ssid_len = ie ? ie[1] : 0;
-
-       ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
+       ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
        wpa_ie_len = ie ? ie[1] : 0;
 
-       ie = wpa_scan_get_ie(bss, WLAN_EID_RSN);
+       ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
        rsn_ie_len = ie ? ie[1] : 0;
 
        wpa_dbg(wpa_s, MSG_DEBUG, "%d: " MACSTR " ssid='%s' "
                "wpa_ie_len=%u rsn_ie_len=%u caps=0x%x level=%d%s",
-               i, MAC2STR(bss->bssid), wpa_ssid_txt(ssid_, ssid_len),
+               i, MAC2STR(bss->bssid), wpa_ssid_txt(bss->ssid, bss->ssid_len),
                wpa_ie_len, rsn_ie_len, bss->caps, bss->level,
-               wpa_scan_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE) ? " wps" : "");
+               wpa_bss_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE) ? " wps" : "");
 
        e = wpa_blacklist_get(wpa_s, bss->bssid);
        if (e) {
@@ -672,7 +667,7 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
                }
        }
 
-       if (ssid_len == 0) {
+       if (bss->ssid_len == 0) {
                wpa_dbg(wpa_s, MSG_DEBUG, "   skip - SSID not known");
                return NULL;
        }
@@ -722,8 +717,8 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
                        check_ssid = 0;
 
                if (check_ssid &&
-                   (ssid_len != ssid->ssid_len ||
-                    os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) {
+                   (bss->ssid_len != ssid->ssid_len ||
+                    os_memcmp(bss->ssid, ssid->ssid, bss->ssid_len) != 0)) {
                        wpa_dbg(wpa_s, MSG_DEBUG, "   skip - SSID mismatch");
                        continue;
                }
@@ -789,32 +784,24 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
 
 static struct wpa_bss *
 wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s,
-                         struct wpa_scan_results *scan_res,
                          struct wpa_ssid *group,
                          struct wpa_ssid **selected_ssid)
 {
-       size_t i;
+       unsigned int i;
 
        wpa_dbg(wpa_s, MSG_DEBUG, "Selecting BSS from priority group %d",
                group->priority);
 
-       for (i = 0; i < scan_res->num; i++) {
-               struct wpa_scan_res *bss = scan_res->res[i];
-               const u8 *ie, *ssid;
-               u8 ssid_len;
-
+       for (i = 0; i < wpa_s->last_scan_res_used; i++) {
+               struct wpa_bss *bss = wpa_s->last_scan_res[i];
                *selected_ssid = wpa_scan_res_match(wpa_s, i, bss, group);
                if (!*selected_ssid)
                        continue;
-
-               ie = wpa_scan_get_ie(bss, WLAN_EID_SSID);
-               ssid = ie ? ie + 2 : (u8 *) "";
-               ssid_len = ie ? ie[1] : 0;
-
                wpa_dbg(wpa_s, MSG_DEBUG, "   selected BSS " MACSTR
                        " ssid='%s'",
-                       MAC2STR(bss->bssid), wpa_ssid_txt(ssid, ssid_len));
-               return wpa_bss_get(wpa_s, bss->bssid, ssid, ssid_len);
+                       MAC2STR(bss->bssid),
+                       wpa_ssid_txt(bss->ssid, bss->ssid_len));
+               return bss;
        }
 
        return NULL;
@@ -823,16 +810,19 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s,
 
 static struct wpa_bss *
 wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
-                           struct wpa_scan_results *scan_res,
                            struct wpa_ssid **selected_ssid)
 {
        struct wpa_bss *selected = NULL;
        int prio;
 
+       if (wpa_s->last_scan_res == NULL ||
+           wpa_s->last_scan_res_used == 0)
+               return NULL; /* no scan results from last update */
+
        while (selected == NULL) {
                for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
                        selected = wpa_supplicant_select_bss(
-                               wpa_s, scan_res, wpa_s->conf->pssid[prio],
+                               wpa_s, wpa_s->conf->pssid[prio],
                                selected_ssid);
                        if (selected)
                                break;
@@ -1158,10 +1148,10 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
 
        wpas_wps_update_ap_info(wpa_s, scan_res);
 
-       selected = wpa_supplicant_pick_network(wpa_s, scan_res, &ssid);
-
        wpa_scan_results_free(scan_res);
 
+       selected = wpa_supplicant_pick_network(wpa_s, &ssid);
+
        if (selected) {
                int skip;
                skip = !wpa_supplicant_need_to_roam(wpa_s, selected, ssid);
index 23966b8..130f3ab 100644 (file)
@@ -1270,14 +1270,14 @@ void wpas_wps_deinit(struct wpa_supplicant *wpa_s)
 
 
 int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,
-                           struct wpa_ssid *ssid, struct wpa_scan_res *bss)
+                           struct wpa_ssid *ssid, struct wpa_bss *bss)
 {
        struct wpabuf *wps_ie;
 
        if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS))
                return -1;
 
-       wps_ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
+       wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
        if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
                if (!wps_ie) {
                        wpa_printf(MSG_DEBUG, "   skip - non-WPS AP");
@@ -1339,19 +1339,19 @@ int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,
 
 int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s,
                              struct wpa_ssid *ssid,
-                             struct wpa_scan_res *bss)
+                             struct wpa_bss *bss)
 {
        struct wpabuf *wps_ie = NULL;
        int ret = 0;
 
        if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
-               wps_ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
+               wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
                if (wps_ie && wps_is_selected_pbc_registrar(wps_ie)) {
                        /* allow wildcard SSID for WPS PBC */
                        ret = 1;
                }
        } else if (eap_is_wps_pin_enrollee(&ssid->eap)) {
-               wps_ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
+               wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
                if (wps_ie &&
                    (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1) ||
                     wpa_s->scan_runs >= WPS_PIN_SCAN_IGNORE_SEL_REG)) {
@@ -1373,7 +1373,7 @@ int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s,
                        ret = 0;
                if (bss->beacon_ie_len) {
                        struct wpabuf *bcn_wps;
-                       bcn_wps = wpa_scan_get_vendor_ie_multi_beacon(
+                       bcn_wps = wpa_bss_get_vendor_ie_multi_beacon(
                                bss, WPS_IE_VENDOR_TYPE);
                        if (bcn_wps == NULL) {
                                wpa_printf(MSG_DEBUG, "WPS: Mandatory WPS IE "
index 36f1e02..d5eb3b6 100644 (file)
@@ -40,9 +40,9 @@ int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type,
 int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid,
                       const char *pin, struct wps_new_ap_settings *settings);
 int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,
-                           struct wpa_ssid *ssid, struct wpa_scan_res *bss);
+                           struct wpa_ssid *ssid, struct wpa_bss *bss);
 int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s,
-                             struct wpa_ssid *ssid, struct wpa_scan_res *bss);
+                             struct wpa_ssid *ssid, struct wpa_bss *bss);
 int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s,
                              struct wpa_bss *selected, struct wpa_ssid *ssid);
 void wpas_wps_notify_scan_results(struct wpa_supplicant *wpa_s);