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).
This commit is contained in:
Sam Leffler 2011-03-20 12:02:33 +02:00 committed by Jouni Malinen
parent d4c1ec56f1
commit 2b65b30da8
8 changed files with 97 additions and 6 deletions

View 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);
}

View 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,

View 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 } }
};

View 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

View 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);

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

View 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);
}

View 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);