[PATCH v2] don't continually reschedule specific scans

Dan Williams dcbw at redhat.com
Mon Jun 2 14:06:29 EDT 2008


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.


diff --git a/src/utils/eloop.c b/src/utils/eloop.c
index f988e94..7507894 100644
--- a/src/utils/eloop.c
+++ b/src/utils/eloop.c
@@ -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
 static void eloop_handle_alarm(int sig)
 {
diff --git a/src/utils/eloop.h b/src/utils/eloop.h
index 4dd2871..cf83f38 100644
--- a/src/utils/eloop.h
+++ b/src/utils/eloop.h
@@ -207,6 +207,19 @@ int eloop_cancel_timeout(eloop_timeout_handler handler,
 			 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
  * @sig: Signal number (e.g., SIGHUP)
  * @handler: Callback function to be called when the signal is received
diff --git a/src/utils/eloop_none.c b/src/utils/eloop_none.c
index 6943109..c6bc02a 100644
--- a/src/utils/eloop_none.c
+++ b/src/utils/eloop_none.c
@@ -197,6 +197,25 @@ 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 */
 #if 0
 static void eloop_handle_signal(int sig)
diff --git a/src/utils/eloop_win.c b/src/utils/eloop_win.c
index 73f0eaf..6e24e83 100644
--- a/src/utils/eloop_win.c
+++ b/src/utils/eloop_win.c
@@ -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 */
 #if 0
 static void eloop_handle_signal(int sig)
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index b046d90..c19d01d 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -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)
 {
+	/* 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",
 		sec, usec);
 	eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);



More information about the HostAP mailing list