]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Interworking: Add optional freq argument to INTERWORKING_SELECT
authorJouni Malinen <j@w1.fi>
Sun, 5 Jan 2014 10:25:13 +0000 (12:25 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 7 Jan 2014 08:45:10 +0000 (10:45 +0200)
This can be used to limit which channels are scanned using the specified
list of frequency ranges in the same format that the SCAN command uses.

Signed-hostap: Jouni Malinen <j@w1.fi>

wpa_supplicant/ctrl_iface.c
wpa_supplicant/interworking.c
wpa_supplicant/interworking.h

index 43b3eee4feed58d373ae2c4d1bcd09f9a1918b26..155207a4e35b84180a28ac4865d835605ef80b52 100644 (file)
@@ -4664,7 +4664,68 @@ static int p2p_ctrl_remove_client(struct wpa_supplicant *wpa_s, const char *cmd)
 #endif /* CONFIG_P2P */
 
 
+static int * freq_range_to_channel_list(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 NULL;
+
+       os_memset(&ranges, 0, sizeof(ranges));
+       if (freq_range_list_parse(&ranges, val) < 0)
+               return NULL;
+
+       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);
+       return freqs;
+}
+
+
 #ifdef CONFIG_INTERWORKING
+
+static int ctrl_interworking_select(struct wpa_supplicant *wpa_s, char *param)
+{
+       int auto_sel = 0;
+       int *freqs = NULL;
+
+       if (param) {
+               char *pos;
+
+               auto_sel = os_strstr(param, "auto") != NULL;
+
+               pos = os_strstr(param, "freq=");
+               if (pos) {
+                       freqs = freq_range_to_channel_list(wpa_s, pos + 5);
+                       if (freqs == NULL)
+                               return -1;
+               }
+
+       }
+
+       return interworking_select(wpa_s, auto_sel, freqs);
+}
+
+
 static int ctrl_interworking_connect(struct wpa_supplicant *wpa_s, char *dst)
 {
        u8 bssid[ETH_ALEN];
@@ -5413,37 +5474,12 @@ 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)
+       freqs = freq_range_to_channel_list(wpa_s, val);
+       if (freqs == NULL)
                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;
 
@@ -5847,9 +5883,11 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                        reply_len = -1;
        } else if (os_strcmp(buf, "STOP_FETCH_ANQP") == 0) {
                interworking_stop_fetch_anqp(wpa_s);
-       } else if (os_strncmp(buf, "INTERWORKING_SELECT", 19) == 0) {
-               if (interworking_select(wpa_s, os_strstr(buf + 19, "auto") !=
-                                       NULL) < 0)
+       } else if (os_strcmp(buf, "INTERWORKING_SELECT") == 0) {
+               if (ctrl_interworking_select(wpa_s, NULL) < 0)
+                       reply_len = -1;
+       } else if (os_strncmp(buf, "INTERWORKING_SELECT ", 20) == 0) {
+               if (ctrl_interworking_select(wpa_s, buf + 20) < 0)
                        reply_len = -1;
        } else if (os_strncmp(buf, "INTERWORKING_CONNECT ", 21) == 0) {
                if (ctrl_interworking_connect(wpa_s, buf + 21) < 0)
index 9f8842bbd84507f91caa9cc7b67ed8a87d6101aa..5e7fe5b27b38c23cb5dfeaddc591b8db0d2aa4fb 100644 (file)
@@ -2202,7 +2202,8 @@ static void interworking_scan_res_handler(struct wpa_supplicant *wpa_s,
 }
 
 
-int interworking_select(struct wpa_supplicant *wpa_s, int auto_select)
+int interworking_select(struct wpa_supplicant *wpa_s, int auto_select,
+                       int *freqs)
 {
        interworking_stop_fetch_anqp(wpa_s);
        wpa_s->network_select = 1;
@@ -2214,6 +2215,8 @@ int interworking_select(struct wpa_supplicant *wpa_s, int auto_select)
        wpa_s->scan_res_handler = interworking_scan_res_handler;
        wpa_s->normal_scans = 0;
        wpa_s->scan_req = MANUAL_SCAN_REQ;
+       os_free(wpa_s->manual_scan_freqs);
+       wpa_s->manual_scan_freqs = freqs;
        wpa_s->after_wps = 0;
        wpa_s->known_wps_freq = 0;
        wpa_supplicant_req_scan(wpa_s, 0, 0);
index 4a4af827bf5b864c8fc23348f9c6ddda097f02c9..c8e70938c1e102e4fefb805d9a4c9b1baf88572c 100644 (file)
@@ -22,7 +22,8 @@ int gas_send_request(struct wpa_supplicant *wpa_s, const u8 *dst,
                     const struct wpabuf *query);
 int interworking_fetch_anqp(struct wpa_supplicant *wpa_s);
 void interworking_stop_fetch_anqp(struct wpa_supplicant *wpa_s);
-int interworking_select(struct wpa_supplicant *wpa_s, int auto_select);
+int interworking_select(struct wpa_supplicant *wpa_s, int auto_select,
+                       int *freqs);
 int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss);
 void interworking_start_fetch_anqp(struct wpa_supplicant *wpa_s);
 int interworking_home_sp_cred(struct wpa_supplicant *wpa_s,