aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant/ctrl_iface.c
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2013-12-25 18:04:52 (GMT)
committerJouni Malinen <j@w1.fi>2013-12-26 14:55:44 (GMT)
commitfee5234284345f7c27db7e726ed729b7317ee5b8 (patch)
tree28da81b9d62f8b2141a99fa238e9e649ccfdc837 /wpa_supplicant/ctrl_iface.c
parent98eda9c26d8ed4f8fd8449da9cdc359418253df7 (diff)
downloadhostap-fee5234284345f7c27db7e726ed729b7317ee5b8.zip
hostap-fee5234284345f7c27db7e726ed729b7317ee5b8.tar.gz
hostap-fee5234284345f7c27db7e726ed729b7317ee5b8.tar.bz2
Allow channel list to be specified for SCAN command
The new freq=<frequency ranges> parameter to the SCAN command can be used to request a scan to be performed on the specified set of channels instead of on all channels. For example, "wpa_cli scan freq=2400-2500,5180" would scan channels 1-14 and 36. Only the channels that the driver indicates as enabled and that are within the specified ranges are included in the request. Signed-hostap: Jouni Malinen <j@w1.fi>
Diffstat (limited to 'wpa_supplicant/ctrl_iface.c')
-rw-r--r--wpa_supplicant/ctrl_iface.c120
1 files changed, 90 insertions, 30 deletions
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 4051fbc..e424c6f 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -5213,6 +5213,92 @@ static void wpas_ctrl_eapol_response(void *eloop_ctx, void *timeout_ctx)
}
+static int set_scan_freqs(struct wpa_supplicant *wpa_s, char *val)
+{
+ struct wpa_freq_range_list ranges;
+ int *freqs = NULL;
+ struct hostapd_hw_modes *mode;
+ u16 i;
+
+ if (wpa_s->hw.modes == NULL)
+ return -1;
+
+ os_memset(&ranges, 0, sizeof(ranges));
+ if (freq_range_list_parse(&ranges, val) < 0)
+ return -1;
+
+ for (i = 0; i < wpa_s->hw.num_modes; i++) {
+ int j;
+
+ mode = &wpa_s->hw.modes[i];
+ for (j = 0; j < mode->num_channels; j++) {
+ unsigned int freq;
+
+ if (mode->channels[j].flag & HOSTAPD_CHAN_DISABLED)
+ continue;
+
+ freq = mode->channels[j].freq;
+ if (!freq_range_list_includes(&ranges, freq))
+ continue;
+
+ int_array_add_unique(&freqs, freq);
+ }
+ }
+
+ os_free(ranges.range);
+ os_free(wpa_s->manual_scan_freqs);
+ wpa_s->manual_scan_freqs = freqs;
+
+ return 0;
+}
+
+
+static void wpas_ctrl_scan(struct wpa_supplicant *wpa_s, char *params,
+ char *reply, int reply_size, int *reply_len)
+{
+ char *pos;
+
+ if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+ *reply_len = -1;
+ return;
+ }
+
+ if (params) {
+ if (os_strncasecmp(params, "TYPE=ONLY", 9) == 0)
+ wpa_s->scan_res_handler = scan_only_handler;
+
+ pos = os_strstr(params, "freq=");
+ if (pos && set_scan_freqs(wpa_s, pos + 5) < 0) {
+ *reply_len = -1;
+ return;
+ }
+ } else {
+ os_free(wpa_s->manual_scan_freqs);
+ wpa_s->manual_scan_freqs = NULL;
+ if (wpa_s->scan_res_handler == scan_only_handler)
+ wpa_s->scan_res_handler = NULL;
+ }
+
+ if (!wpa_s->sched_scanning && !wpa_s->scanning &&
+ ((wpa_s->wpa_state <= WPA_SCANNING) ||
+ (wpa_s->wpa_state == WPA_COMPLETED))) {
+ wpa_s->normal_scans = 0;
+ wpa_s->scan_req = MANUAL_SCAN_REQ;
+ wpa_s->after_wps = 0;
+ wpa_s->known_wps_freq = 0;
+ wpa_supplicant_req_scan(wpa_s, 0, 0);
+ } else if (wpa_s->sched_scanning) {
+ wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to allow requested full scan to proceed");
+ wpa_supplicant_cancel_sched_scan(wpa_s);
+ wpa_s->scan_req = MANUAL_SCAN_REQ;
+ wpa_supplicant_req_scan(wpa_s, 0, 0);
+ } else {
+ wpa_printf(MSG_DEBUG, "Ongoing scan action - reject new request");
+ *reply_len = os_snprintf(reply, reply_size, "FAIL-BUSY\n");
+ }
+}
+
+
char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
char *buf, size_t *resp_len)
{
@@ -5591,36 +5677,10 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
wpa_supplicant_cancel_scan(wpa_s);
wpa_supplicant_deauthenticate(wpa_s,
WLAN_REASON_DEAUTH_LEAVING);
- } else if (os_strcmp(buf, "SCAN") == 0 ||
- os_strncmp(buf, "SCAN ", 5) == 0) {
- if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
- reply_len = -1;
- else {
- if (os_strlen(buf) > 4 &&
- os_strncasecmp(buf + 5, "TYPE=ONLY", 9) == 0)
- wpa_s->scan_res_handler = scan_only_handler;
- if (!wpa_s->sched_scanning && !wpa_s->scanning &&
- ((wpa_s->wpa_state <= WPA_SCANNING) ||
- (wpa_s->wpa_state == WPA_COMPLETED))) {
- wpa_s->normal_scans = 0;
- wpa_s->scan_req = MANUAL_SCAN_REQ;
- wpa_s->after_wps = 0;
- wpa_s->known_wps_freq = 0;
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- } else if (wpa_s->sched_scanning) {
- wpa_printf(MSG_DEBUG, "Stop ongoing "
- "sched_scan to allow requested "
- "full scan to proceed");
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_s->scan_req = MANUAL_SCAN_REQ;
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- } else {
- wpa_printf(MSG_DEBUG, "Ongoing scan action - "
- "reject new request");
- reply_len = os_snprintf(reply, reply_size,
- "FAIL-BUSY\n");
- }
- }
+ } else if (os_strcmp(buf, "SCAN") == 0) {
+ wpas_ctrl_scan(wpa_s, NULL, reply, reply_size, &reply_len);
+ } else if (os_strncmp(buf, "SCAN ", 5) == 0) {
+ wpas_ctrl_scan(wpa_s, buf + 5, reply, reply_size, &reply_len);
} else if (os_strcmp(buf, "SCAN_RESULTS") == 0) {
reply_len = wpa_supplicant_ctrl_iface_scan_results(
wpa_s, reply, reply_size);