Add extended driver scan request command: driver_ops::scan2()
authorJouni Malinen <j@w1.fi>
Sat, 14 Feb 2009 15:01:32 +0000 (17:01 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 14 Feb 2009 15:01:32 +0000 (17:01 +0200)
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
src/drivers/driver_ndis.c
src/drivers/driver_privsep.c
src/drivers/driver_test.c
wpa_supplicant/scan.c
wpa_supplicant/wpa_supplicant_i.h

index 5927e49..25a0d90 100644 (file)
@@ -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 */
index b22109b..07fb282 100644 (file)
@@ -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 */
 };
index 9156dfb..abe4303 100644 (file)
@@ -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 */
 };
 
 
index f0d3b43..7b92ee4 100644 (file)
@@ -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 */
 };
index 67e2282..28cfbf9 100644 (file)
@@ -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(&params, 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, &params);
        }
 
        wpabuf_free(wps_ie);
index 1af64d2..92ba22f 100644 (file)
@@ -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)
-{
-       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;
 }