Browse Source

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).
Jouni Malinen 16 years ago
parent
commit
fc2b7ed5f3

+ 57 - 1
src/drivers/driver.h

@@ -142,6 +142,46 @@ struct wpa_interface_info {
 	const char *drv_name;
 	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
  * struct wpa_driver_associate_params - Association parameters
  * Data for struct wpa_driver_ops::associate().
  * Data for struct wpa_driver_ops::associate().
@@ -558,7 +598,7 @@ struct wpa_driver_ops {
 	int (*set_drop_unencrypted)(void *priv, int enabled);
 	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
 	 * @priv: private driver interface data
 	 * @ssid: specific SSID to scan for (ProbeReq) or %NULL to scan for
 	 * @ssid: specific SSID to scan for (ProbeReq) or %NULL to scan for
 	 *	all SSIDs (either active scan with broadcast SSID or passive
 	 *	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
 	 * Once the scan results are ready, the driver should report scan
 	 * results event for wpa_supplicant which will eventually request the
 	 * results event for wpa_supplicant which will eventually request the
 	 * results with wpa_driver_get_scan_results().
 	 * 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);
 	int (*scan)(void *priv, const u8 *ssid, size_t ssid_len);
 
 
@@ -1019,6 +1062,19 @@ struct wpa_driver_ops {
 	 * failure
 	 * failure
 	 */
 	 */
 	struct wpa_interface_info * (*get_interfaces)(void *global_priv);
 	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 */
 /* Function to check whether a driver is for wired connections */

+ 2 - 1
src/drivers/driver_ndis.c

@@ -3122,5 +3122,6 @@ const struct wpa_driver_ops wpa_driver_ndis_ops = {
 	NULL /* global_init */,
 	NULL /* global_init */,
 	NULL /* global_deinit */,
 	NULL /* global_deinit */,
 	NULL /* init2 */,
 	NULL /* init2 */,
-	wpa_driver_ndis_get_interfaces
+	wpa_driver_ndis_get_interfaces,
+	NULL /* scan2 */
 };
 };

+ 2 - 1
src/drivers/driver_privsep.c

@@ -800,7 +800,8 @@ struct wpa_driver_ops wpa_driver_privsep_ops = {
 	NULL /* global_init */,
 	NULL /* global_init */,
 	NULL /* global_deinit */,
 	NULL /* global_deinit */,
 	NULL /* init2 */,
 	NULL /* init2 */,
-	NULL /* get_interfaces */
+	NULL /* get_interfaces */,
+	NULL /* scan2 */
 };
 };
 
 
 
 

+ 2 - 1
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_init,
 	wpa_driver_test_global_deinit,
 	wpa_driver_test_global_deinit,
 	wpa_driver_test_init2,
 	wpa_driver_test_init2,
-	wpa_driver_test_get_interfaces
+	wpa_driver_test_get_interfaces,
+	NULL /* scan2 */
 };
 };

+ 10 - 2
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,
 		ret = ieee80211_sta_req_scan(wpa_s, ssid ? ssid->ssid : NULL,
 					     ssid ? ssid->ssid_len : 0);
 					     ssid ? ssid->ssid_len : 0);
 	} else {
 	} else {
+		struct wpa_driver_scan_params params;
+		os_memset(&params, 0, sizeof(params));
 		wpa_drv_set_probe_req_ie(wpa_s, extra_ie, extra_ie_len);
 		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, &params);
 	}
 	}
 
 
 	wpabuf_free(wps_ie);
 	wpabuf_free(wps_ie);

+ 9 - 6
wpa_supplicant/wpa_supplicant_i.h

@@ -495,12 +495,15 @@ static inline int wpa_drv_associate(struct wpa_supplicant *wpa_s,
 	return -1;
 	return -1;
 }
 }
 
 
-static inline int wpa_drv_scan(struct wpa_supplicant *wpa_s, const u8 *ssid,
-			       size_t ssid_len)
-{
-	if (wpa_s->driver->scan) {
-		return wpa_s->driver->scan(wpa_s->drv_priv, ssid, ssid_len);
-	}
+static inline int wpa_drv_scan(struct wpa_supplicant *wpa_s,
+			       struct wpa_driver_scan_params *params)
+{
+	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;
 	return -1;
 }
 }