dbus: Add D-Bus methods to flush the BSS cache
authorSam Leffler <sleffler@chromium.org>
Sun, 20 Mar 2011 10:02:33 +0000 (12:02 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 20 Mar 2011 10:02:33 +0000 (12:02 +0200)
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).

wpa_supplicant/bss.c
wpa_supplicant/bss.h
wpa_supplicant/dbus/dbus_new.c
wpa_supplicant/dbus/dbus_new_handlers.c
wpa_supplicant/dbus/dbus_new_handlers.h
wpa_supplicant/dbus/dbus_old.c
wpa_supplicant/dbus/dbus_old_handlers.c
wpa_supplicant/dbus/dbus_old_handlers.h

index 07f92f1..5809284 100644 (file)
@@ -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);
 }
 
 
index 1de4722..992b9c0 100644 (file)
@@ -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,
index f85fedf..d86552f 100644 (file)
@@ -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 } }
 };
 
index 02ace9b..b590d62 100644 (file)
@@ -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
index 119d15d..dcac352 100644 (file)
@@ -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);
 
index 7f25bf0..6a00f3e 100644 (file)
@@ -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 */
index d914697..de66140 100644 (file)
@@ -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);
+}
index 65e876f..009e807 100644 (file)
@@ -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);