]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add band option (2.4 vs. 5) for filtering scans
authorJouni Malinen <jouni@qca.qualcomm.com>
Fri, 9 Mar 2012 05:28:13 +0000 (21:28 -0800)
committerJouni Malinen <j@w1.fi>
Sat, 18 May 2013 09:17:10 +0000 (12:17 +0300)
This can be used to implement filtering of channels for scan and based
on that, for connection, purposes.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

wpa_supplicant/scan.c
wpa_supplicant/wpa_supplicant_i.h

index 16e0bd7cb6e530ee4159151f79a3555b6b9c329d..bdd6815e3ebca431b99f284c2ad820c611af25f7 100644 (file)
@@ -522,6 +522,63 @@ static int shared_vif_oper_freq(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;
@@ -747,6 +804,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);
 
        /* See if user specified frequencies. If so, scan only those. */
        if (wpa_s->conf->freq_list && !params.freqs) {
@@ -1120,6 +1178,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);
index d29318ec45ea6302a30cb14a8063799e43ca7866..f4e6faff507f0b1715bc5eea1bf5775030438a3f 100644 (file)
@@ -353,6 +353,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;