Do not continually reschedule specific scans to help finding hidden SSIDs

In situations where the driver does background scanning and sends a
steady stream of scan results, wpa_supplicant would continually
reschedule the scan.  This resulted in specific SSID scans never
happening for a hidden AP, and the supplicant never connecting to the AP
because it never got found.  Instead, if there's an already scheduled
scan, and a request comes in to reschedule it, and there are enabled
scan_ssid=1 network blocks, let the scan happen anyway so the hidden
SSID has a chance to be found.
This commit is contained in:
Dan Williams 2008-06-03 11:37:48 +03:00 committed by Jouni Malinen
parent 8479707beb
commit 7e1488494e
5 changed files with 93 additions and 0 deletions

View file

@ -315,6 +315,25 @@ int eloop_cancel_timeout(eloop_timeout_handler handler,
} }
int eloop_is_timeout_registered(eloop_timeout_handler handler,
void *eloop_data, void *user_data)
{
struct eloop_timeout *tmp;
tmp = eloop.timeout;
while (tmp != NULL) {
if (tmp->handler == handler &&
tmp->eloop_data == eloop_data &&
tmp->user_data == user_data)
return 1;
tmp = tmp->next;
}
return 0;
}
#ifndef CONFIG_NATIVE_WINDOWS #ifndef CONFIG_NATIVE_WINDOWS
static void eloop_handle_alarm(int sig) static void eloop_handle_alarm(int sig)
{ {

View file

@ -206,6 +206,19 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs,
int eloop_cancel_timeout(eloop_timeout_handler handler, int eloop_cancel_timeout(eloop_timeout_handler handler,
void *eloop_data, void *user_data); void *eloop_data, void *user_data);
/**
* eloop_is_timeout_registered - Check if a timeout is already registered
* @handler: Matching callback function
* @eloop_data: Matching eloop_data
* @user_data: Matching user_data
* Returns: 1 if the timeout is registered, 0 if the timeout is not registered
*
* Determine if a matching <handler,eloop_data,user_data> timeout is registered
* with eloop_register_timeout().
*/
int eloop_is_timeout_registered(eloop_timeout_handler handler,
void *eloop_data, void *user_data);
/** /**
* eloop_register_signal - Register handler for signals * eloop_register_signal - Register handler for signals
* @sig: Signal number (e.g., SIGHUP) * @sig: Signal number (e.g., SIGHUP)

View file

@ -197,6 +197,26 @@ int eloop_cancel_timeout(void (*handler)(void *eloop_ctx, void *sock_ctx),
} }
int eloop_is_timeout_registered(void (*handler)(void *eloop_ctx,
void *timeout_ctx),
void *eloop_data, void *user_data)
{
struct eloop_timeout *tmp;
tmp = eloop.timeout;
while (tmp != NULL) {
if (tmp->handler == handler &&
tmp->eloop_data == eloop_data &&
tmp->user_data == user_data)
return 1;
tmp = tmp->next;
}
return 0;
}
/* TODO: replace with suitable signal handler */ /* TODO: replace with suitable signal handler */
#if 0 #if 0
static void eloop_handle_signal(int sig) static void eloop_handle_signal(int sig)

View file

@ -320,6 +320,25 @@ int eloop_cancel_timeout(eloop_timeout_handler handler,
} }
int eloop_is_timeout_registered(eloop_timeout_handler handler,
void *eloop_data, void *user_data)
{
struct eloop_timeout *tmp;
tmp = eloop.timeout;
while (tmp != NULL) {
if (tmp->handler == handler &&
tmp->eloop_data == eloop_data &&
tmp->user_data == user_data)
return 1;
tmp = tmp->next;
}
return 0;
}
/* TODO: replace with suitable signal handler */ /* TODO: replace with suitable signal handler */
#if 0 #if 0
static void eloop_handle_signal(int sig) static void eloop_handle_signal(int sig)

View file

@ -172,6 +172,28 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
*/ */
void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec) void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
{ {
/* If there's at least one network that should be specifically scanned
* then don't cancel the scan and reschedule. Some drivers do
* background scanning which generates frequent scan results, and that
* causes the specific SSID scan to get continually pushed back and
* never happen, which causes hidden APs to never get probe-scanned.
*/
if (eloop_is_timeout_registered(wpa_supplicant_scan, wpa_s, NULL) &&
wpa_s->conf->ap_scan == 1) {
struct wpa_ssid *ssid = wpa_s->conf->ssid;
while (ssid) {
if (!ssid->disabled && ssid->scan_ssid)
break;
ssid = ssid->next;
}
if (ssid) {
wpa_msg(wpa_s, MSG_DEBUG, "Not rescheduling scan to "
"ensure that specific SSID scans occur");
return;
}
}
wpa_msg(wpa_s, MSG_DEBUG, "Setting scan request: %d sec %d usec", wpa_msg(wpa_s, MSG_DEBUG, "Setting scan request: %d sec %d usec",
sec, usec); sec, usec);
eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL); eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);