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).
This commit is contained in:
Jouni Malinen 2009-02-14 17:01:32 +02:00
parent 362f781e1c
commit fc2b7ed5f3
6 changed files with 81 additions and 11 deletions

View file

@ -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 */

View file

@ -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 */
}; };

View file

@ -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 */
}; };

View file

@ -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 */
}; };

View 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, 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, if (ssid) {
ssid ? ssid->ssid_len : 0); 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);

View file

@ -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, static inline int wpa_drv_scan(struct wpa_supplicant *wpa_s,
size_t ssid_len) struct wpa_driver_scan_params *params)
{ {
if (wpa_s->driver->scan) { if (wpa_s->driver->scan2)
return wpa_s->driver->scan(wpa_s->drv_priv, ssid, ssid_len); 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;
} }