summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2012-03-08 21:28:13 -0800
committerJouni Malinen <j@w1.fi>2012-11-21 17:56:47 +0200
commitb046d1c924b6c25dd8a23ded757ac07f9dd8c05a (patch)
treec8a4f49c927a3bf12ffd870b73cde0ecffdc9e1d
parent44b8eb43a58d0015b3537f90f1bd736a39be759e (diff)
downloadhostap-android.tar.gz
Android: Implement SETBAND for scan requestsandroid
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 bb57accfe..0a51f6b7f 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -4645,7 +4645,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 525a63221..4c47756e3 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -435,6 +435,63 @@ static struct wpabuf * 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;
@@ -666,6 +723,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);
@@ -963,6 +1021,8 @@ scan:
wpa_s->sched_scan_interval);
}
+ wpa_setband_scan_freqs(wpa_s, scan_params);
+
ret = wpa_supplicant_start_sched_scan(wpa_s, scan_params,
wpa_s->sched_scan_interval);
wpabuf_free(extra_ie);
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 5e7702836..7eac6704f 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -333,6 +333,8 @@ struct wpa_supplicant {
struct wpa_ssid_value *disallow_aps_ssid;
size_t disallow_aps_ssid_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;