Browse Source

dbus: Add D-Bus methods to flush the BSS cache

Add an "Interface.FlushBSS" method to the new D-Bus API and a "flush"
method to the old API. Both take an age parameter that is a threshold
(in seconds) for selecting entries to evict. Setting this parameter
to zero flushes all entries from the cache.

This mechanism is useful for a connection manager to clear state at
startup and on resume (where the age parameter may be used to hold
onto recent/valid data).
Sam Leffler 14 years ago
parent
commit
2b65b30da8

+ 24 - 6
wpa_supplicant/bss.c

@@ -421,9 +421,8 @@ void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info,
 }
 
 
-static void wpa_bss_timeout(void *eloop_ctx, void *timeout_ctx)
+void wpa_bss_flush_by_age(struct wpa_supplicant *wpa_s, int age)
 {
-	struct wpa_supplicant *wpa_s = eloop_ctx;
 	struct wpa_bss *bss, *n;
 	struct os_time t;
 
@@ -431,7 +430,7 @@ static void wpa_bss_timeout(void *eloop_ctx, void *timeout_ctx)
 		return;
 
 	os_get_time(&t);
-	t.sec -= WPA_BSS_EXPIRATION_AGE;
+	t.sec -= age;
 
 	dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) {
 		if (wpa_bss_in_use(wpa_s, bss))
@@ -444,6 +443,14 @@ static void wpa_bss_timeout(void *eloop_ctx, void *timeout_ctx)
 		} else
 			break;
 	}
+}
+
+
+static void wpa_bss_timeout(void *eloop_ctx, void *timeout_ctx)
+{
+	struct wpa_supplicant *wpa_s = eloop_ctx;
+
+	wpa_bss_flush_by_age(wpa_s, WPA_BSS_EXPIRATION_AGE);
 	eloop_register_timeout(WPA_BSS_EXPIRATION_PERIOD, 0,
 			       wpa_bss_timeout, wpa_s, NULL);
 }
@@ -459,14 +466,25 @@ int wpa_bss_init(struct wpa_supplicant *wpa_s)
 }
 
 
-void wpa_bss_deinit(struct wpa_supplicant *wpa_s)
+void wpa_bss_flush(struct wpa_supplicant *wpa_s)
 {
 	struct wpa_bss *bss, *n;
-	eloop_cancel_timeout(wpa_bss_timeout, wpa_s, NULL);
+
 	if (wpa_s->bss.next == NULL)
 		return; /* BSS table not yet initialized */
-	dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list)
+
+	dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) {
+		if (wpa_bss_in_use(wpa_s, bss))
+			continue;
 		wpa_bss_remove(wpa_s, bss);
+	}
+}
+
+
+void wpa_bss_deinit(struct wpa_supplicant *wpa_s)
+{
+	eloop_cancel_timeout(wpa_bss_timeout, wpa_s, NULL);
+	wpa_bss_flush(wpa_s);
 }
 
 

+ 2 - 0
wpa_supplicant/bss.h

@@ -78,6 +78,8 @@ void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info,
 			int new_scan);
 int wpa_bss_init(struct wpa_supplicant *wpa_s);
 void wpa_bss_deinit(struct wpa_supplicant *wpa_s);
+void wpa_bss_flush(struct wpa_supplicant *wpa_s);
+void wpa_bss_flush_by_age(struct wpa_supplicant *wpa_s, int age);
 struct wpa_bss * wpa_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid,
 			     const u8 *ssid, size_t ssid_len);
 struct wpa_bss * wpa_bss_get_bssid(struct wpa_supplicant *wpa_s,

+ 7 - 0
wpa_supplicant/dbus/dbus_new.c

@@ -1352,6 +1352,13 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
 	  }
 	},
 #endif /* CONFIG_WPS */
+	{ "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  (WPADBusMethodHandler) &wpas_dbus_handler_flush_bss,
+	  {
+		  { "age", "u", ARG_IN },
+		  END_ARGS
+	  }
+	},
 	{ NULL, NULL, NULL, { END_ARGS } }
 };
 

+ 24 - 0
wpa_supplicant/dbus/dbus_new_handlers.c

@@ -1684,6 +1684,30 @@ DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message,
 
 }
 
+/*
+ * wpas_dbus_handler_flush_bss - Flush the BSS cache
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL
+ *
+ * Handler function for "FlushBSS" method call of network interface.
+ */
+DBusMessage * wpas_dbus_handler_flush_bss(DBusMessage *message,
+					  struct wpa_supplicant *wpa_s)
+{
+	dbus_uint32_t age;
+
+	dbus_message_get_args(message, NULL, DBUS_TYPE_UINT32, &age,
+			      DBUS_TYPE_INVALID);
+
+	if (age == 0)
+		wpa_bss_flush(wpa_s);
+	else
+		wpa_bss_flush_by_age(wpa_s, age);
+
+	return NULL;
+}
+
 
 /**
  * wpas_dbus_getter_capabilities - Return interface capabilities

+ 3 - 0
wpa_supplicant/dbus/dbus_new_handlers.h

@@ -95,6 +95,9 @@ DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message,
 DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message,
 					    struct wpa_supplicant *wpa_s);
 
+DBusMessage * wpas_dbus_handler_flush_bss(DBusMessage *message,
+					  struct wpa_supplicant *wpa_s);
+
 DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message,
 					    struct wpa_supplicant *wpa_s);
 

+ 2 - 0
wpa_supplicant/dbus/dbus_old.c

@@ -287,6 +287,8 @@ static DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection,
 		else if (!os_strcmp(method, "wpsReg"))
 			reply = wpas_dbus_iface_wps_reg(message, wpa_s);
 #endif /* CONFIG_WPS */
+		else if (!os_strcmp(method, "flush"))
+			reply = wpas_dbus_iface_flush(message, wpa_s);
 	}
 
 	/* If the message was handled, send back the reply */

+ 32 - 0
wpa_supplicant/dbus/dbus_old_handlers.c

@@ -1434,3 +1434,35 @@ DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message,
 
 	return wpas_dbus_new_success_reply(message);
 }
+
+
+/**
+ * wpas_dbus_iface_flush - Clear BSS of old or all inactive entries
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: %wpa_supplicant data structure
+ * Returns: a dbus message containing a UINT32 indicating success (1) or
+ *          failure (0), or returns a dbus error message with more information
+ *
+ * Handler function for "flush" method call. Handles requests for an
+ * interface with an optional "age" parameter that specifies the minimum
+ * age of a BSS to be flushed.
+ */
+DBusMessage * wpas_dbus_iface_flush(DBusMessage *message,
+				    struct wpa_supplicant *wpa_s)
+{
+	int flush_age = 0;
+
+	if (os_strlen(dbus_message_get_signature(message)) != 0 &&
+	    !dbus_message_get_args(message, NULL,
+				   DBUS_TYPE_INT32, &flush_age,
+				   DBUS_TYPE_INVALID)) {
+		return wpas_dbus_new_invalid_opts_error(message, NULL);
+	}
+
+	if (flush_age == 0)
+		wpa_bss_flush(wpa_s);
+	else
+		wpa_bss_flush_by_age(wpa_s, flush_age);
+
+	return wpas_dbus_new_success_reply(message);
+}

+ 3 - 0
wpa_supplicant/dbus/dbus_old_handlers.h

@@ -96,6 +96,9 @@ DBusMessage * wpas_dbus_iface_wps_pin(DBusMessage *message,
 DBusMessage * wpas_dbus_iface_wps_reg(DBusMessage *message,
 				      struct wpa_supplicant *wpa_s);
 
+DBusMessage * wpas_dbus_iface_flush(DBusMessage *message,
+				    struct wpa_supplicant *wpa_s);
+
 DBusMessage * wpas_dbus_new_success_reply(DBusMessage *message);
 DBusMessage * wpas_dbus_new_invalid_opts_error(DBusMessage *message,
 					       const char *arg);