From fc2b7ed5f3a9409999bc0e1911a4239ca35ccb1c Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 14 Feb 2009 17:01:32 +0200 Subject: [PATCH] Add extended driver scan request command: driver_ops::scan2() This can be used to provide support for scanning multiple SSIDs at a time to optimize scan_ssid=1 operations. In addition, Probe Request IEs will be available to scan2() (e.g., for WPS PBC scanning). --- src/drivers/driver.h | 58 ++++++++++++++++++++++++++++++- src/drivers/driver_ndis.c | 3 +- src/drivers/driver_privsep.c | 3 +- src/drivers/driver_test.c | 3 +- wpa_supplicant/scan.c | 12 +++++-- wpa_supplicant/wpa_supplicant_i.h | 13 ++++--- 6 files changed, 81 insertions(+), 11 deletions(-) diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 5927e4962..25a0d9044 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -142,6 +142,46 @@ struct wpa_interface_info { const char *drv_name; }; +#define WPAS_MAX_SCAN_SSIDS 4 + +/** + * struct wpa_driver_scan_params - Scan parameters + * Data for struct wpa_driver_ops::scan2(). + */ +struct wpa_driver_scan_params { + /** + * ssids - SSIDs to scan for + */ + struct wpa_driver_scan_ssid { + /** + * ssid - specific SSID to scan for (ProbeReq) + * %NULL or zero-length SSID is used to indicate active scan + * with broadcast SSID. + */ + const u8 *ssid; + /** + * ssid_len: Length of the SSID in octets + */ + size_t ssid_len; + } ssids[WPAS_MAX_SCAN_SSIDS]; + + /** + * num_ssids - Number of entries in ssids array + * Zero indicates a request for a passive scan. + */ + size_t num_ssids; + + /** + * extra_ies - Extra IE(s) to add into Probe Request or %NULL + */ + const u8 *extra_ies; + + /** + * extra_ies_len - Length of extra_ies in octets + */ + size_t extra_ies_len; +}; + /** * struct wpa_driver_associate_params - Association parameters * Data for struct wpa_driver_ops::associate(). @@ -558,7 +598,7 @@ struct wpa_driver_ops { int (*set_drop_unencrypted)(void *priv, int enabled); /** - * scan - Request the driver to initiate scan + * scan - Request the driver to initiate scan (old version) * @priv: private driver interface data * @ssid: specific SSID to scan for (ProbeReq) or %NULL to scan for * all SSIDs (either active scan with broadcast SSID or passive @@ -570,6 +610,9 @@ struct wpa_driver_ops { * Once the scan results are ready, the driver should report scan * results event for wpa_supplicant which will eventually request the * results with wpa_driver_get_scan_results(). + * + * This function is depracated. New driver wrapper implementations + * should implement support for scan2(). */ int (*scan)(void *priv, const u8 *ssid, size_t ssid_len); @@ -1019,6 +1062,19 @@ struct wpa_driver_ops { * failure */ struct wpa_interface_info * (*get_interfaces)(void *global_priv); + + /** + * scan2 - Request the driver to initiate scan + * @priv: private driver interface data + * @params: Scan parameters + * + * Returns: 0 on success, -1 on failure + * + * Once the scan results are ready, the driver should report scan + * results event for wpa_supplicant which will eventually request the + * results with wpa_driver_get_scan_results2(). + */ + int (*scan2)(void *priv, struct wpa_driver_scan_params *params); }; /* Function to check whether a driver is for wired connections */ diff --git a/src/drivers/driver_ndis.c b/src/drivers/driver_ndis.c index b22109bc7..07fb28227 100644 --- a/src/drivers/driver_ndis.c +++ b/src/drivers/driver_ndis.c @@ -3122,5 +3122,6 @@ const struct wpa_driver_ops wpa_driver_ndis_ops = { NULL /* global_init */, NULL /* global_deinit */, NULL /* init2 */, - wpa_driver_ndis_get_interfaces + wpa_driver_ndis_get_interfaces, + NULL /* scan2 */ }; diff --git a/src/drivers/driver_privsep.c b/src/drivers/driver_privsep.c index 9156dfbd2..abe4303eb 100644 --- a/src/drivers/driver_privsep.c +++ b/src/drivers/driver_privsep.c @@ -800,7 +800,8 @@ struct wpa_driver_ops wpa_driver_privsep_ops = { NULL /* global_init */, NULL /* global_deinit */, NULL /* init2 */, - NULL /* get_interfaces */ + NULL /* get_interfaces */, + NULL /* scan2 */ }; diff --git a/src/drivers/driver_test.c b/src/drivers/driver_test.c index f0d3b43bd..7b92ee4cf 100644 --- a/src/drivers/driver_test.c +++ b/src/drivers/driver_test.c @@ -1317,5 +1317,6 @@ const struct wpa_driver_ops wpa_driver_test_ops = { wpa_driver_test_global_init, wpa_driver_test_global_deinit, wpa_driver_test_init2, - wpa_driver_test_get_interfaces + wpa_driver_test_get_interfaces, + NULL /* scan2 */ }; diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index 67e2282ef..28cfbf92e 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -194,9 +194,17 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) ret = ieee80211_sta_req_scan(wpa_s, ssid ? ssid->ssid : NULL, ssid ? ssid->ssid_len : 0); } else { + struct wpa_driver_scan_params params; + os_memset(¶ms, 0, sizeof(params)); wpa_drv_set_probe_req_ie(wpa_s, extra_ie, extra_ie_len); - ret = wpa_drv_scan(wpa_s, ssid ? ssid->ssid : NULL, - ssid ? ssid->ssid_len : 0); + if (ssid) { + params.ssids[0].ssid = ssid->ssid; + params.ssids[0].ssid_len = ssid->ssid_len; + } + params.num_ssids = 1; + params.extra_ies = extra_ie; + params.extra_ies_len = extra_ie_len; + ret = wpa_drv_scan(wpa_s, ¶ms); } wpabuf_free(wps_ie); diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 1af64d2e2..92ba22f6f 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -495,12 +495,15 @@ static inline int wpa_drv_associate(struct wpa_supplicant *wpa_s, return -1; } -static inline int wpa_drv_scan(struct wpa_supplicant *wpa_s, const u8 *ssid, - size_t ssid_len) +static inline int wpa_drv_scan(struct wpa_supplicant *wpa_s, + struct wpa_driver_scan_params *params) { - if (wpa_s->driver->scan) { - return wpa_s->driver->scan(wpa_s->drv_priv, ssid, ssid_len); - } + if (wpa_s->driver->scan2) + return wpa_s->driver->scan2(wpa_s->drv_priv, params); + if (wpa_s->driver->scan) + return wpa_s->driver->scan(wpa_s->drv_priv, + params->ssids[0].ssid, + params->ssids[0].ssid_len); return -1; }