Do not store raw scan results
authorJouni Malinen <j@w1.fi>
Sat, 2 Jan 2010 14:41:38 +0000 (16:41 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 2 Jan 2010 14:41:38 +0000 (16:41 +0200)
Use scan results to update the BSS table and to select the BSS for
connection, but do not store the results for longer time.

wpa_supplicant/bss.h
wpa_supplicant/events.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h
wpa_supplicant/wpas_glue.c
wpa_supplicant/wps_supplicant.h

index 2242222..d6e0613 100644 (file)
@@ -15,6 +15,8 @@
 #ifndef BSS_H
 #define BSS_H
 
+struct wpa_scan_res;
+
 #define WPA_BSS_QUAL_INVALID           BIT(0)
 #define WPA_BSS_NOISE_INVALID          BIT(1)
 #define WPA_BSS_LEVEL_INVALID          BIT(2)
index 9e675dd..7a9b557 100644 (file)
@@ -392,6 +392,7 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
 
 static struct wpa_bss *
 wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s,
+                             struct wpa_scan_results *scan_res,
                              struct wpa_ssid *group,
                              struct wpa_ssid **selected_ssid)
 {
@@ -402,10 +403,10 @@ wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s,
        const u8 *ie;
 
        wpa_printf(MSG_DEBUG, "Try to find WPA-enabled AP");
-       for (i = 0; i < wpa_s->scan_res->num; i++) {
+       for (i = 0; i < scan_res->num; i++) {
                const u8 *ssid_;
                u8 wpa_ie_len, rsn_ie_len, ssid_len;
-               bss = wpa_s->scan_res->res[i];
+               bss = scan_res->res[i];
 
                ie = wpa_scan_get_ie(bss, WLAN_EID_SSID);
                ssid_ = ie ? ie + 2 : (u8 *) "";
@@ -487,6 +488,7 @@ wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s,
 
 static struct wpa_bss *
 wpa_supplicant_select_bss_non_wpa(struct wpa_supplicant *wpa_s,
+                                 struct wpa_scan_results *scan_res,
                                  struct wpa_ssid *group,
                                  struct wpa_ssid **selected_ssid)
 {
@@ -497,10 +499,10 @@ wpa_supplicant_select_bss_non_wpa(struct wpa_supplicant *wpa_s,
        const u8 *ie;
 
        wpa_printf(MSG_DEBUG, "Try to find non-WPA AP");
-       for (i = 0; i < wpa_s->scan_res->num; i++) {
+       for (i = 0; i < scan_res->num; i++) {
                const u8 *ssid_;
                u8 wpa_ie_len, rsn_ie_len, ssid_len;
-               bss = wpa_s->scan_res->res[i];
+               bss = scan_res->res[i];
 
                ie = wpa_scan_get_ie(bss, WLAN_EID_SSID);
                ssid_ = ie ? ie + 2 : (u8 *) "";
@@ -612,7 +614,9 @@ wpa_supplicant_select_bss_non_wpa(struct wpa_supplicant *wpa_s,
 
 
 static struct wpa_bss *
-wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group,
+wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s,
+                         struct wpa_scan_results *scan_res,
+                         struct wpa_ssid *group,
                          struct wpa_ssid **selected_ssid)
 {
        struct wpa_bss *selected;
@@ -621,18 +625,21 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group,
                   group->priority);
 
        /* First, try to find WPA-enabled AP */
-       selected = wpa_supplicant_select_bss_wpa(wpa_s, group, selected_ssid);
+       selected = wpa_supplicant_select_bss_wpa(wpa_s, scan_res, group,
+                                                selected_ssid);
        if (selected)
                return selected;
 
        /* If no WPA-enabled AP found, try to find non-WPA AP, if configuration
         * allows this. */
-       return wpa_supplicant_select_bss_non_wpa(wpa_s, group, selected_ssid);
+       return wpa_supplicant_select_bss_non_wpa(wpa_s, scan_res, group,
+                                                selected_ssid);
 }
 
 
 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;
@@ -641,7 +648,7 @@ wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
        while (selected == NULL) {
                for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
                        selected = wpa_supplicant_select_bss(
-                               wpa_s, wpa_s->conf->pssid[prio],
+                               wpa_s, scan_res, wpa_s->conf->pssid[prio],
                                selected_ssid);
                        if (selected)
                                break;
@@ -736,19 +743,21 @@ wpa_supplicant_pick_new_network(struct wpa_supplicant *wpa_s)
 }
 
 
+/* TODO: move the rsn_preauth_scan_result*() to be called from notify.c based
+ * on BSS added and BSS changed events */
 static void wpa_supplicant_rsn_preauth_scan_results(
-       struct wpa_supplicant *wpa_s)
+       struct wpa_supplicant *wpa_s, struct wpa_scan_results *scan_res)
 {
        int i;
 
        if (rsn_preauth_scan_results(wpa_s->wpa) < 0)
                return;
 
-       for (i = wpa_s->scan_res->num - 1; i >= 0; i--) {
+       for (i = scan_res->num - 1; i >= 0; i--) {
                const u8 *ssid, *rsn;
                struct wpa_scan_res *r;
 
-               r = wpa_s->scan_res->res[i];
+               r = scan_res->res[i];
 
                ssid = wpa_scan_get_ie(r, WLAN_EID_SSID);
                if (ssid == NULL)
@@ -769,11 +778,14 @@ static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
 {
        struct wpa_bss *selected;
        struct wpa_ssid *ssid = NULL;
+       struct wpa_scan_results *scan_res;
 
        wpa_supplicant_notify_scanning(wpa_s, 0);
 
-       if (wpa_supplicant_get_scan_results(wpa_s, data ? &data->scan_info :
-                                           NULL, 1) < 0) {
+       scan_res = wpa_supplicant_get_scan_results(wpa_s,
+                                                  data ? &data->scan_info :
+                                                  NULL, 1);
+       if (scan_res == NULL) {
                if (wpa_s->conf->ap_scan == 2)
                        return;
                wpa_printf(MSG_DEBUG, "Failed to get scan results - try "
@@ -787,7 +799,7 @@ static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
         * and there were no results.
         */
        if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1 &&
-           wpa_s->scan_res->num == 0) {
+           scan_res->num == 0) {
                wpa_msg(wpa_s, MSG_DEBUG, "Cached scan results are "
                        "empty - not posting");
        } else {
@@ -798,20 +810,27 @@ static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
 
        wpas_notify_scan_done(wpa_s, 1);
 
-       if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s)))
+       if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s))) {
+               wpa_scan_results_free(scan_res);
                return;
+       }
 
        if (wpa_s->disconnected) {
                wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
+               wpa_scan_results_free(scan_res);
                return;
        }
 
-       if (bgscan_notify_scan(wpa_s) == 1)
+       if (bgscan_notify_scan(wpa_s) == 1) {
+               wpa_scan_results_free(scan_res);
                return;
+       }
+
+       wpa_supplicant_rsn_preauth_scan_results(wpa_s, scan_res);
 
-       wpa_supplicant_rsn_preauth_scan_results(wpa_s);
+       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) {
                wpa_supplicant_connect(wpa_s, selected, ssid);
        } else {
index 428a783..8a38b26 100644 (file)
@@ -400,8 +400,6 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
        wpa_s->wpa = NULL;
        wpa_blacklist_clear(wpa_s);
 
-       wpa_scan_results_free(wpa_s->scan_res);
-       wpa_s->scan_res = NULL;
        wpa_bss_deinit(wpa_s);
 
        wpa_supplicant_cancel_scan(wpa_s);
@@ -1569,33 +1567,47 @@ int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
  * @wpa_s: Pointer to wpa_supplicant data
  * @info: Information about what was scanned or %NULL if not available
  * @new_scan: Whether a new scan was performed
- * Returns: 0 on success, -1 on failure
+ * Returns: Scan results, %NULL on failure
  *
  * This function request the current scan results from the driver and updates
- * the local BSS list wpa_s->bss.
+ * the local BSS list wpa_s->bss. The caller is responsible for freeing the
+ * results with wpa_scan_results_free().
  */
-int wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
-                                   struct scan_info *info, int new_scan)
+struct wpa_scan_results *
+wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
+                               struct scan_info *info, int new_scan)
 {
+       struct wpa_scan_results *scan_res;
        size_t i;
 
-       wpa_scan_results_free(wpa_s->scan_res);
        if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
-               wpa_s->scan_res = ieee80211_sta_get_scan_results(wpa_s);
+               scan_res = ieee80211_sta_get_scan_results(wpa_s);
        else
-               wpa_s->scan_res = wpa_drv_get_scan_results2(wpa_s);
-       if (wpa_s->scan_res == NULL) {
+               scan_res = wpa_drv_get_scan_results2(wpa_s);
+       if (scan_res == NULL) {
                wpa_printf(MSG_DEBUG, "Failed to get scan results");
-               return -1;
+               return NULL;
        }
 
-       wpa_scan_sort_results(wpa_s->scan_res);
+       wpa_scan_sort_results(scan_res);
 
        wpa_bss_update_start(wpa_s);
-       for (i = 0; i < wpa_s->scan_res->num; i++)
-               wpa_bss_update_scan_res(wpa_s, wpa_s->scan_res->res[i]);
+       for (i = 0; i < scan_res->num; i++)
+               wpa_bss_update_scan_res(wpa_s, scan_res->res[i]);
        wpa_bss_update_end(wpa_s, info, new_scan);
 
+       return scan_res;
+}
+
+
+int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s)
+{
+       struct wpa_scan_results *scan_res;
+       scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
+       if (scan_res == NULL)
+               return -1;
+       wpa_scan_results_free(scan_res);
+
        return 0;
 }
 
index 3292ab9..707fac4 100644 (file)
@@ -28,8 +28,6 @@ extern const char *wpa_supplicant_full_license4;
 extern const char *wpa_supplicant_full_license5;
 #endif /* CONFIG_NO_STDOUT_DEBUG */
 
-struct wpa_scan_result;
-struct wpa_scan_res;
 struct wpa_sm;
 struct wpa_supplicant;
 struct ibss_rsn;
@@ -345,7 +343,6 @@ struct wpa_supplicant {
                                          */
 #define WILDCARD_SSID_SCAN ((struct wpa_ssid *) 1)
 
-       struct wpa_scan_results *scan_res;
        struct dl_list bss; /* struct wpa_bss::list */
        struct dl_list bss_id; /* struct wpa_bss::list_id */
        size_t num_bss;
@@ -446,8 +443,10 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
 void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
                                       struct wpa_ssid *ssid);
 void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s);
-int wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
-                                   struct scan_info *info, int new_scan);
+struct wpa_scan_results *
+wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
+                               struct scan_info *info, int new_scan);
+int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s);
 void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr);
 void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
                                     int sec, int usec);
index b8a867d..dad73b7 100644 (file)
@@ -343,9 +343,8 @@ static int wpa_supplicant_get_beacon_ie(void *ctx)
 
        /* No WPA/RSN IE found in the cached scan results. Try to get updated
         * scan results from the driver. */
-       if (wpa_supplicant_get_scan_results(wpa_s, NULL, 0) < 0) {
+       if (wpa_supplicant_update_scan_results(wpa_s) < 0)
                return -1;
-       }
 
        return wpa_get_beacon_ie(wpa_s);
 }
index 80e44c5..85da8be 100644 (file)
@@ -21,6 +21,7 @@
 #include "wps/wps_defs.h"
 
 struct wpa_bss;
+struct wpa_scan_res;
 
 struct wps_new_ap_settings {
        const char *ssid_hex;