aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant/bss.c
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2012-09-02 16:53:15 (GMT)
committerJouni Malinen <j@w1.fi>2012-09-02 16:53:15 (GMT)
commita297201df15656dbb0f37e90f3410d9e8102c6fd (patch)
treec6dbce69f4937897cefb035d4b0ffd9991a1c75a /wpa_supplicant/bss.c
parent20ed5e40ba95440a1946cf2dffad3047fb620582 (diff)
downloadhostap-a297201df15656dbb0f37e90f3410d9e8102c6fd.zip
hostap-a297201df15656dbb0f37e90f3410d9e8102c6fd.tar.gz
hostap-a297201df15656dbb0f37e90f3410d9e8102c6fd.tar.bz2
Maintain list of BSS entries in last scan result order
This allows last results to be used even after they have been freed since the information is copied to the BSS entries anyway and this new array provides the order in which scan results were processed. Signed-hostap: Jouni Malinen <j@w1.fi>
Diffstat (limited to 'wpa_supplicant/bss.c')
-rw-r--r--wpa_supplicant/bss.c66
1 files changed, 61 insertions, 5 deletions
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index 580a82a..434fb08 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -38,6 +38,19 @@
static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
const char *reason)
{
+ if (wpa_s->last_scan_res) {
+ unsigned int i;
+ for (i = 0; i < wpa_s->last_scan_res_used; i++) {
+ if (wpa_s->last_scan_res[i] == bss) {
+ os_memmove(&wpa_s->last_scan_res[i],
+ &wpa_s->last_scan_res[i + 1],
+ (wpa_s->last_scan_res_used - i - 1)
+ * sizeof(struct wpa_bss *));
+ wpa_s->last_scan_res_used--;
+ break;
+ }
+ }
+ }
dl_list_del(&bss->list);
dl_list_del(&bss->list_id);
wpa_s->num_bss--;
@@ -169,15 +182,15 @@ static int wpa_bss_remove_oldest(struct wpa_supplicant *wpa_s)
}
-static void wpa_bss_add(struct wpa_supplicant *wpa_s,
- const u8 *ssid, size_t ssid_len,
- struct wpa_scan_res *res)
+static struct wpa_bss * wpa_bss_add(struct wpa_supplicant *wpa_s,
+ const u8 *ssid, size_t ssid_len,
+ struct wpa_scan_res *res)
{
struct wpa_bss *bss;
bss = os_zalloc(sizeof(*bss) + res->ie_len + res->beacon_ie_len);
if (bss == NULL)
- return;
+ return NULL;
bss->id = wpa_s->bss_next_id++;
bss->last_update_idx = wpa_s->bss_update_idx;
wpa_bss_copy_res(bss, res);
@@ -201,6 +214,7 @@ static void wpa_bss_add(struct wpa_supplicant *wpa_s,
"not get here!", (int) wpa_s->num_bss);
wpa_s->conf->bss_max_count = wpa_s->num_bss;
}
+ return bss;
}
@@ -376,6 +390,7 @@ void wpa_bss_update_start(struct wpa_supplicant *wpa_s)
wpa_s->bss_update_idx++;
wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Start scan result update %u",
wpa_s->bss_update_idx);
+ wpa_s->last_scan_res_used = 0;
}
@@ -418,9 +433,28 @@ void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s,
* (to save memory) */
bss = wpa_bss_get(wpa_s, res->bssid, ssid + 2, ssid[1]);
if (bss == NULL)
- wpa_bss_add(wpa_s, ssid + 2, ssid[1], res);
+ bss = wpa_bss_add(wpa_s, ssid + 2, ssid[1], res);
else
wpa_bss_update(wpa_s, bss, res);
+
+ if (bss == NULL)
+ return;
+ if (wpa_s->last_scan_res_used >= wpa_s->last_scan_res_size) {
+ struct wpa_bss **n;
+ unsigned int siz;
+ if (wpa_s->last_scan_res_size == 0)
+ siz = 32;
+ else
+ siz = wpa_s->last_scan_res_size * 2;
+ n = os_realloc_array(wpa_s->last_scan_res, siz,
+ sizeof(struct wpa_bss *));
+ if (n == NULL)
+ return;
+ wpa_s->last_scan_res = n;
+ wpa_s->last_scan_res_size = siz;
+ }
+
+ wpa_s->last_scan_res[wpa_s->last_scan_res_used++] = bss;
}
@@ -470,9 +504,26 @@ void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info,
{
struct wpa_bss *bss, *n;
+ wpa_s->last_scan_full = 0;
+ os_get_time(&wpa_s->last_scan);
if (!new_scan)
return; /* do not expire entries without new scan */
+ if (info && !info->aborted && !info->freqs) {
+ size_t i;
+ if (info->num_ssids == 0) {
+ wpa_s->last_scan_full = 1;
+ } else {
+ for (i = 0; i < info->num_ssids; i++) {
+ if (info->ssids[i].ssid == NULL ||
+ info->ssids[i].ssid_len == 0) {
+ wpa_s->last_scan_full = 1;
+ break;
+ }
+ }
+ }
+ }
+
dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) {
if (wpa_bss_in_use(wpa_s, bss))
continue;
@@ -485,6 +536,11 @@ void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info,
wpa_bss_remove(wpa_s, bss, "no match in scan");
}
}
+
+ wpa_printf(MSG_DEBUG, "BSS: last_scan_res_used=%u/%u "
+ "last_scan_full=%d",
+ wpa_s->last_scan_res_used, wpa_s->last_scan_res_size,
+ wpa_s->last_scan_full);
}