X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=wpa_supplicant%2Fbgscan_learn.c;h=a320cc43068c96f6bde1354af5954dad164de807;hb=b84ce655d31a2236734c788fd3292c10d5d9f0b1;hp=ee79511cbdf742ded5b41da99d56230c52d4f68a;hpb=174fa7898e008a9e76757b8afda16707c4c7ec15;p=mech_eap.git diff --git a/wpa_supplicant/bgscan_learn.c b/wpa_supplicant/bgscan_learn.c index ee79511..a320cc4 100644 --- a/wpa_supplicant/bgscan_learn.c +++ b/wpa_supplicant/bgscan_learn.c @@ -2,14 +2,8 @@ * WPA Supplicant - background scan and roaming module: learn * Copyright (c) 2009-2010, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ #include "includes.h" @@ -40,7 +34,7 @@ struct bgscan_learn_data { int signal_threshold; int short_interval; /* use if signal < threshold */ int long_interval; /* use if signal > threshold */ - struct os_time last_bgscan; + struct os_reltime last_bgscan; char *fname; struct dl_list bss; int *supp_freqs; @@ -81,7 +75,7 @@ static void bgscan_learn_add_neighbor(struct bgscan_learn_bss *bss, if (bssid_in_array(bss->neigh, bss->num_neigh, bssid)) return; - n = os_realloc(bss->neigh, (bss->num_neigh + 1) * ETH_ALEN); + n = os_realloc_array(bss->neigh, bss->num_neigh + 1, ETH_ALEN); if (n == NULL) return; @@ -225,7 +219,7 @@ static int * bgscan_learn_get_freqs(struct bgscan_learn_data *data, dl_list_for_each(bss, &data->bss, struct bgscan_learn_bss, list) { if (in_array(freqs, bss->freq)) continue; - n = os_realloc(freqs, (*count + 2) * sizeof(int)); + n = os_realloc_array(freqs, *count + 2, sizeof(int)); if (n == NULL) return freqs; freqs = n; @@ -246,15 +240,15 @@ static int * bgscan_learn_get_probe_freq(struct bgscan_learn_data *data, if (data->supp_freqs == NULL) return freqs; - idx = data->probe_idx + 1; - while (idx != data->probe_idx) { - if (data->supp_freqs[idx] == 0) - idx = 0; + idx = data->probe_idx; + do { if (!in_array(freqs, data->supp_freqs[idx])) { wpa_printf(MSG_DEBUG, "bgscan learn: Probe new freq " "%u", data->supp_freqs[idx]); - data->probe_idx = idx; - n = os_realloc(freqs, (count + 2) * sizeof(int)); + data->probe_idx = idx + 1; + if (data->supp_freqs[data->probe_idx] == 0) + data->probe_idx = 0; + n = os_realloc_array(freqs, count + 2, sizeof(int)); if (n == NULL) return freqs; freqs = n; @@ -265,7 +259,9 @@ static int * bgscan_learn_get_probe_freq(struct bgscan_learn_data *data, } idx++; - } + if (data->supp_freqs[idx] == 0) + idx = 0; + } while (idx != data->probe_idx); return freqs; } @@ -298,7 +294,7 @@ static void bgscan_learn_timeout(void *eloop_ctx, void *timeout_ctx) int ret; ret = os_snprintf(pos, msg + sizeof(msg) - pos, " %d", freqs[i]); - if (ret < 0 || ret >= msg + sizeof(msg) - pos) + if (os_snprintf_error(msg + sizeof(msg) - pos, ret)) break; pos += ret; } @@ -314,7 +310,7 @@ static void bgscan_learn_timeout(void *eloop_ctx, void *timeout_ctx) eloop_register_timeout(data->scan_interval, 0, bgscan_learn_timeout, data, NULL); } else - os_get_time(&data->last_bgscan); + os_get_reltime(&data->last_bgscan); os_free(freqs); } @@ -355,20 +351,22 @@ static int bgscan_learn_get_params(struct bgscan_learn_data *data, static int * bgscan_learn_get_supp_freqs(struct wpa_supplicant *wpa_s) { struct hostapd_hw_modes *modes; - u16 num_modes, flags; int i, j, *freqs = NULL, *n; size_t count = 0; - modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, &flags); - if (!modes) + modes = wpa_s->hw.modes; + if (modes == NULL) return NULL; - for (i = 0; i < num_modes; i++) { + for (i = 0; i < wpa_s->hw.num_modes; i++) { for (j = 0; j < modes[i].num_channels; j++) { if (modes[i].channels[j].flag & HOSTAPD_CHAN_DISABLED) continue; - n = os_realloc(freqs, (count + 2) * sizeof(int)); - if (!n) + /* some hw modes (e.g. 11b & 11g) contain same freqs */ + if (in_array(freqs, modes[i].channels[j].freq)) + continue; + n = os_realloc_array(freqs, count + 2, sizeof(int)); + if (n == NULL) continue; freqs = n; @@ -376,10 +374,7 @@ static int * bgscan_learn_get_supp_freqs(struct wpa_supplicant *wpa_s) count++; freqs[count] = 0; } - os_free(modes[i].channels); - os_free(modes[i].rates); } - os_free(modes); return freqs; } @@ -426,6 +421,14 @@ static void * bgscan_learn_init(struct wpa_supplicant *wpa_s, data->supp_freqs = bgscan_learn_get_supp_freqs(wpa_s); data->scan_interval = data->short_interval; + if (data->signal_threshold) { + /* Poll for signal info to set initial scan interval */ + struct wpa_signal_info siginfo; + if (wpa_drv_signal_poll(wpa_s, &siginfo) == 0 && + siginfo.current_signal >= data->signal_threshold) + data->scan_interval = data->long_interval; + } + eloop_register_timeout(data->scan_interval, 0, bgscan_learn_timeout, data, NULL); @@ -435,7 +438,7 @@ static void * bgscan_learn_init(struct wpa_supplicant *wpa_s, * us skip an immediate new scan in cases where the current signal * level is below the bgscan threshold. */ - os_get_time(&data->last_bgscan); + os_get_reltime(&data->last_bgscan); return data; } @@ -562,7 +565,7 @@ static void bgscan_learn_notify_signal_change(void *priv, int above, { struct bgscan_learn_data *data = priv; int scan = 0; - struct os_time now; + struct os_reltime now; if (data->short_interval == data->long_interval || data->signal_threshold == 0) @@ -576,7 +579,7 @@ static void bgscan_learn_notify_signal_change(void *priv, int above, wpa_printf(MSG_DEBUG, "bgscan learn: Start using short bgscan " "interval"); data->scan_interval = data->short_interval; - os_get_time(&now); + os_get_reltime(&now); if (now.sec > data->last_bgscan.sec + 1) scan = 1; } else if (data->scan_interval == data->short_interval && above) { @@ -591,7 +594,7 @@ static void bgscan_learn_notify_signal_change(void *priv, int above, * Signal dropped further 4 dB. Request a new scan if we have * not yet scanned in a while. */ - os_get_time(&now); + os_get_reltime(&now); if (now.sec > data->last_bgscan.sec + 10) scan = 1; }