aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2012-03-08 21:28:13 -0800
committerArik Nemtsov <arik@wizery.com>2012-08-02 13:03:59 +0300
commit0ba677aae8a22b907e8fe6a15ba7b56a9f0ca240 (patch)
tree698e3bd4b913132f382961f1078c1e206453cb28
parentbe201aff6bffa92d639d7a7a070d47be33cddd6c (diff)
downloadexternal_wpa_supplicant_8_ti-0ba677aae8a22b907e8fe6a15ba7b56a9f0ca240.zip
external_wpa_supplicant_8_ti-0ba677aae8a22b907e8fe6a15ba7b56a9f0ca240.tar.gz
external_wpa_supplicant_8_ti-0ba677aae8a22b907e8fe6a15ba7b56a9f0ca240.tar.bz2
Android: Implement SETBAND for scan requests
This provides partial SETBAND driver command implementation by converting the request into a filter for which channels are scanned by wpa_supplicant.
-rw-r--r--wpa_supplicant/ctrl_iface.c21
-rw-r--r--wpa_supplicant/scan.c60
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h2
3 files changed, 82 insertions, 1 deletions
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 21d7e8a..af5f9bf 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -4071,7 +4071,26 @@ static int wpa_supplicant_driver_cmd(struct wpa_supplicant *wpa_s, char *cmd,
ret = pno_start(wpa_s);
else if (os_strcasecmp(cmd, "BGSCAN-STOP") == 0)
ret = pno_stop(wpa_s);
- else
+ else if (os_strncasecmp(cmd, "SETBAND ", 8) == 0) {
+ int val = atoi(cmd + 8);
+ /*
+ * Use driver_cmd for drivers that support it, but ignore the
+ * return value since scan requests from wpa_supplicant will
+ * provide a list of channels to scan for based on the SETBAND
+ * setting.
+ */
+ wpa_printf(MSG_DEBUG, "SETBAND: %d", val);
+ wpa_drv_driver_cmd(wpa_s, cmd, buf, buflen);
+ ret = 0;
+ if (val == 0)
+ wpa_s->setband = WPA_SETBAND_AUTO;
+ else if (val == 1)
+ wpa_s->setband = WPA_SETBAND_5G;
+ else if (val == 2)
+ wpa_s->setband = WPA_SETBAND_2G;
+ else
+ ret = -1;
+ } else
ret = wpa_drv_driver_cmd(wpa_s, cmd, buf, buflen);
if (ret == 0)
ret = sprintf(buf, "%s\n", "OK");
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 0430385..ef3f26e 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -415,6 +415,63 @@ wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s,
}
+static struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes,
+ u16 num_modes,
+ enum hostapd_hw_mode mode)
+{
+ u16 i;
+
+ for (i = 0; i < num_modes; i++) {
+ if (modes[i].mode == mode)
+ return &modes[i];
+ }
+
+ return NULL;
+}
+
+
+static void wpa_setband_scan_freqs_list(struct wpa_supplicant *wpa_s,
+ enum hostapd_hw_mode band,
+ struct wpa_driver_scan_params *params)
+{
+ /* Include only supported channels for the specified band */
+ struct hostapd_hw_modes *mode;
+ int count, i;
+
+ mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, band);
+ if (mode == NULL) {
+ /* No channels supported in this band - use empty list */
+ params->freqs = os_zalloc(sizeof(int));
+ return;
+ }
+
+ params->freqs = os_zalloc((mode->num_channels + 1) * sizeof(int));
+ if (params->freqs == NULL)
+ return;
+ for (count = 0, i = 0; i < mode->num_channels; i++) {
+ if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED)
+ continue;
+ params->freqs[count++] = mode->channels[i].freq;
+ }
+}
+
+
+static void wpa_setband_scan_freqs(struct wpa_supplicant *wpa_s,
+ struct wpa_driver_scan_params *params)
+{
+ if (wpa_s->hw.modes == NULL)
+ return; /* unknown what channels the driver supports */
+ if (params->freqs)
+ return; /* already using a limited channel set */
+ if (wpa_s->setband == WPA_SETBAND_5G)
+ wpa_setband_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A,
+ params);
+ else if (wpa_s->setband == WPA_SETBAND_2G)
+ wpa_setband_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G,
+ params);
+}
+
+
static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
@@ -647,6 +704,7 @@ ssid_list_set:
} else
os_free(wpa_s->next_scan_freqs);
wpa_s->next_scan_freqs = NULL;
+ wpa_setband_scan_freqs(wpa_s, &params);
params.filter_ssids = wpa_supplicant_build_filter_ssids(
wpa_s->conf, &params.num_filter_ssids);
@@ -910,6 +968,8 @@ start_scan:
scan:
+ wpa_setband_scan_freqs(wpa_s, scan_params);
+
if (wpa_s->sched_scan_intervals_supported) {
wpa_dbg(wpa_s, MSG_DEBUG, "Starting sched scan: "
" short interval %d long_interval %d"
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 02b3a99..5132ca3 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -312,6 +312,8 @@ struct wpa_supplicant {
u8 *bssid_filter;
size_t bssid_filter_count;
+ enum { WPA_SETBAND_AUTO, WPA_SETBAND_5G, WPA_SETBAND_2G } setband;
+
/* previous scan was wildcard when interleaving between
* wildcard scans and specific SSID scan when max_ssids=1 */
int prev_scan_wildcard;