Patchwork [2/7] Automatic Scanning support added

login
register
mail settings
Submitter Bondar, Alexander
Date April 23, 2012, 12:20 p.m.
Message ID <60035555E48905429C8B264861CA6BB40DBAB1@HASMSX103.ger.corp.intel.com>
Download mbox | patch
Permalink /patch/154414/
State Superseded
Headers show

Comments

Bondar, Alexander - April 23, 2012, 12:20 p.m.
Hi Tomasz,

> diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index
> 1c3b9eb..584f74e 100644
> --- a/wpa_supplicant/events.c
> +++ b/wpa_supplicant/events.c
> @@ -41,6 +41,7 @@
>  #include "gas_query.h"
>  #include "p2p_supplicant.h"
>  #include "bgscan.h"
> +#include "autoscan.h"
>  #include "ap.h"
>  #include "bss.h"
>  #include "scan.h"
> @@ -1086,6 +1087,11 @@ static int
> _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
>  		return 0;
>  	}
> 
> +	if (autoscan_notify_scan(wpa_s, scan_res)) {
> +		wpa_scan_results_free(scan_res);
> +		return 0;
> +	}
> +
>  	if (wpa_s->disconnected) {
>  		wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
>  		wpa_scan_results_free(scan_res);



Regarding this snippet, I'd suggest to do it slightly different - trigger scan only if candidate not found:


> diff --git a/wpa_supplicant/wpa_supplicant_i.h
> b/wpa_supplicant/wpa_supplicant_i.h
> index 9698c68..cb84bb6 100644
> --- a/wpa_supplicant/wpa_supplicant_i.h
> +++ b/wpa_supplicant/wpa_supplicant_i.h
> @@ -484,6 +484,10 @@ struct wpa_supplicant {
>  	const struct bgscan_ops *bgscan;
>  	void *bgscan_priv;
> 
> +	const struct autoscan_ops *autoscan;
> +	struct wpa_driver_scan_params *autoscan_params;
> +	void *autoscan_priv;
> +
>  	struct wpa_ssid *connect_without_scan;
> 
>  	int after_wps;

Regarding the autoscan_params, I have implemented additional method to let other modules to request scan 
specifying scan parameters (see attached).

Best.
---------------------------------------------------------------------
Intel Israel (74) Limited

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
This new method intended to serve scan use cases allowing a caller to
specify scan parameters while verifying scan conditions. It also may renew
scan parameters with additional parameters that may be relevant for all
use cases. For example, adding WPS and P2P IEs. The caller of this method
may specify frequencies and SSIDs list to scan.
This method is mostly derived from wpa_supplicant_scan() that does validate
scan candidation and add IEs but does not allow the caller to specify scan
parameters.

Change-Id: I2b9369d4338fef69cd3deb459a725688e1fa70cd
Signed-off-by: Alexander Bondar <alexander.bondar@intel.com>
---
 wpa_supplicant/scan.c |  119 ++++++++++++++++++++++++++++---------------------
 wpa_supplicant/scan.h |    2 +
 2 files changed, 70 insertions(+), 51 deletions(-)

diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index eec5c7b..d1ed4f4 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -425,32 +425,29 @@ wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s,
        return extra_ie;
 }

-
-static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
+int wpa_supplicant_req_scan_spec(struct wpa_supplicant *wpa_s,
+                                       struct wpa_driver_scan_params *params)
 {
-       struct wpa_supplicant *wpa_s = eloop_ctx;
-       struct wpa_ssid *ssid;
        int scan_req = 0, ret;
        struct wpabuf *extra_ie;
-       struct wpa_driver_scan_params params;
-       size_t max_ssids;
        enum wpa_states prev_state;
+       struct wpa_ssid *ssid;

        if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
                wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - interface disabled");
-               return;
+               return 0;
        }

        if (wpa_s->disconnected && !wpa_s->scan_req) {
                wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
-               return;
+               return 0;
        }

        if (!wpa_supplicant_enabled_networks(wpa_s->conf) &&
            !wpa_s->scan_req) {
                wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks - do not scan");
                wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
-               return;
+               return 0;
        }

        if (wpa_s->conf->ap_scan != 0 &&
@@ -463,7 +460,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)

        if (wpa_s->conf->ap_scan == 0) {
                wpa_supplicant_gen_assoc_event(wpa_s);
-               return;
+               return 0;
        }

 #ifdef CONFIG_P2P
@@ -476,28 +473,10 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
                        wpa_dbg(wpa_s, MSG_DEBUG, "Do not request scan while "
                                "P2P operation is in progress");
                }
-               return;
+               return 0;
        }
 #endif /* CONFIG_P2P */

-       if (wpa_s->conf->ap_scan == 2)
-               max_ssids = 1;
-       else {
-               max_ssids = wpa_s->max_scan_ssids;
-               if (max_ssids > WPAS_MAX_SCAN_SSIDS)
-                       max_ssids = WPAS_MAX_SCAN_SSIDS;
-       }
-
-       scan_req = wpa_s->scan_req;
-       wpa_s->scan_req = 0;
-
-       os_memset(&params, 0, sizeof(params));
-
-       prev_state = wpa_s->wpa_state;
-       if (wpa_s->wpa_state == WPA_DISCONNECTED ||
-           wpa_s->wpa_state == WPA_INACTIVE)
-               wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
-
        if (scan_req != 2 && wpa_s->connect_without_scan) {
                for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
                        if (ssid == wpa_s->connect_without_scan)
@@ -508,10 +487,62 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
                        wpa_printf(MSG_DEBUG, "Start a pre-selected network "
                                   "without scan step");
                        wpa_supplicant_associate(wpa_s, NULL, ssid);
-                       return;
+                       return 0;
                }
        }

+        if (scan_req != 2 && wpa_s->conf->ap_scan == 2) {
+               wpa_s->connect_without_scan = NULL;
+               wpa_s->prev_scan_wildcard = 0;
+               wpa_supplicant_assoc_try(wpa_s, ssid);
+               return 0;
+        }
+
+        prev_state = wpa_s->wpa_state;
+       if (wpa_s->wpa_state == WPA_DISCONNECTED ||
+           wpa_s->wpa_state == WPA_INACTIVE)
+               wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
+
+       wpa_s->scan_req = 0;
+
+        wpa_supplicant_optimize_freqs(wpa_s, params);
+       extra_ie = wpa_supplicant_extra_ies(wpa_s, params);
+
+        if (extra_ie) {
+               params->extra_ies = wpabuf_head(extra_ie);
+               params->extra_ies_len = wpabuf_len(extra_ie);
+       }
+
+       if (params->freqs)
+               int_array_sort_unique(params->freqs);
+
+       ret = wpa_supplicant_trigger_scan(wpa_s, params);
+       if (ret && prev_state != wpa_s->wpa_state)
+               wpa_supplicant_set_state(wpa_s, prev_state);
+
+       wpabuf_free(extra_ie);
+
+       return ret;
+}
+
+static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
+{
+       struct wpa_supplicant *wpa_s = eloop_ctx;
+       struct wpa_ssid *ssid;
+       struct wpa_driver_scan_params params;
+       size_t max_ssids;
+       int ret;
+
+       if (wpa_s->conf->ap_scan == 2)
+               max_ssids = 1;
+       else {
+               max_ssids = wpa_s->max_scan_ssids;
+               if (max_ssids > WPAS_MAX_SCAN_SSIDS)
+                       max_ssids = WPAS_MAX_SCAN_SSIDS;
+       }
+
+        os_memset(&params, 0, sizeof(params));
+
 #ifdef CONFIG_P2P
        if ((wpa_s->p2p_in_provisioning || wpa_s->show_group_started) &&
            wpa_s->go_params) {
@@ -536,12 +567,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
                }
        }

-       if (scan_req != 2 && wpa_s->conf->ap_scan == 2) {
-               wpa_s->connect_without_scan = NULL;
-               wpa_s->prev_scan_wildcard = 0;
-               wpa_supplicant_assoc_try(wpa_s, ssid);
-               return;
-       } else if (wpa_s->conf->ap_scan == 2) {
+       if (wpa_s->scan_req == 2 && wpa_s->conf->ap_scan == 2) {
                /*
                 * User-initiated scan request in ap_scan == 2; scan with
                 * wildcard SSID.
@@ -584,7 +610,6 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
                        }
                        freqs_set = 1;
                }
-               int_array_sort_unique(params.freqs);
        }

        if (ssid && max_ssids == 1) {
@@ -623,9 +648,6 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
 ssid_list_set:
 #endif /* CONFIG_P2P */

-       wpa_supplicant_optimize_freqs(wpa_s, &params);
-       extra_ie = wpa_supplicant_extra_ies(wpa_s, &params);
-
        if (params.freqs == NULL && wpa_s->next_scan_freqs) {
                wpa_dbg(wpa_s, MSG_DEBUG, "Optimize scan based on previously "
                        "generated frequency list");
@@ -636,10 +658,6 @@ ssid_list_set:

        params.filter_ssids = wpa_supplicant_build_filter_ssids(
                wpa_s->conf, &params.num_filter_ssids);
-       if (extra_ie) {
-               params.extra_ies = wpabuf_head(extra_ie);
-               params.extra_ies_len = wpabuf_len(extra_ie);
-       }

 #ifdef CONFIG_P2P
        if (wpa_s->p2p_in_provisioning ||
@@ -652,18 +670,17 @@ ssid_list_set:
        }
 #endif /* CONFIG_P2P */

-       ret = wpa_supplicant_trigger_scan(wpa_s, &params);
-
-       wpabuf_free(extra_ie);
-       os_free(params.freqs);
-       os_free(params.filter_ssids);

+       ret = wpa_supplicant_req_scan_spec(wpa_s, &params);
        if (ret) {
                wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate AP scan");
-               if (prev_state != wpa_s->wpa_state)
-                       wpa_supplicant_set_state(wpa_s, prev_state);
                wpa_supplicant_req_scan(wpa_s, 1, 0);
        }
+
+       if (params.freqs)
+               os_free(params.freqs);
+       if (params.filter_ssids)
+               os_free(params.filter_ssids);
 }


diff --git a/wpa_supplicant/scan.h b/wpa_supplicant/scan.h
index 8c83a42..435a587 100644
--- a/wpa_supplicant/scan.h
+++ b/wpa_supplicant/scan.h
@@ -11,6 +11,8 @@

 int wpa_supplicant_enabled_networks(struct wpa_config *conf);
 void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec);
+int wpa_supplicant_req_scan_spec(struct wpa_supplicant *wpa_s,
+                               struct wpa_driver_scan_params *params);
 int wpa_supplicant_delayed_sched_scan(struct wpa_supplicant *wpa_s,
                                      int sec, int usec);
 int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s);
--
1.7.1
Tomasz Bursztyka - April 23, 2012, 12:54 p.m.
Hi Alexander,

> Regarding this snippet, I'd suggest to do it slightly different - trigger scan only if candidate not found:
>
> diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
> index 8fdc544..ca5f415 100644
> --- a/wpa_supplicant/events.c
> +++ b/wpa_supplicant/events.c
> @@ -1135,9 +1135,10 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
>                                  return 0;
>                          }
>   #endif /* CONFIG_P2P */
> -                       if (wpa_supplicant_req_sched_scan(wpa_s))
> -                               wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
> -                                                           timeout_usec);
> +                        if (autoscan_notify_scan(wpa_s, scan_res)) {
> +                               wpa_scan_results_free(scan_res);
> +                               return 0;
> +                        }
>                  }
>          }
>          return 0;
The scan is already triggered if no candidate has been selected. See 
wpa_supplicant_pick_network()/wpa_supplicant_pick_new_network() above in 
events.c  so I don't see why you do that.
Calling autoscan_notify_scan() does not trigger a scan (and anyway here 
you are creating a bug: scan_res has been freed already and not set to 
null, so if the autoscan module eventually touches it, it will 
definitely crash.)
autoscan_notify_scan() is necessary to set up the new scan interval and 
the scan parameters (if any), that's why is it called before any network 
selection is done prior to the results and prior to any scan. Check my 
second version of the patchset, I think it solves what you requested 
(being able to manipulate scan parameters in autoscan module).

Br,

Tomasz

Patch

diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 8fdc544..ca5f415 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1135,9 +1135,10 @@  static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
                                return 0;
                        }
 #endif /* CONFIG_P2P */
-                       if (wpa_supplicant_req_sched_scan(wpa_s))
-                               wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
-                                                           timeout_usec);
+                        if (autoscan_notify_scan(wpa_s, scan_res)) {
+                               wpa_scan_results_free(scan_res);
+                               return 0;
+                        }
                }
        }
        return 0;