diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index de68ec845..dd6bc43a1 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -1730,6 +1730,31 @@ void wpa_config_free(struct wpa_config *config) } +/** + * wpa_config_foreach_network - Iterate over each configured network + * @config: Configuration data from wpa_config_read() + * @func: Callback function to process each network + * @arg: Opaque argument to pass to callback function + * + * Iterate over the set of configured networks calling the specified + * function for each item. We guard against callbacks removing the + * supplied network. + */ +void wpa_config_foreach_network(struct wpa_config *config, + void (*func)(void *, struct wpa_ssid *), + void *arg) +{ + struct wpa_ssid *ssid, *next; + + ssid = config->ssid; + while (ssid) { + next = ssid->next; + func(arg, ssid); + ssid = next; + } +} + + /** * wpa_config_get_network - Get configured network based on id * @config: Configuration data from wpa_config_read() diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 75406ef3a..9e9e0f77e 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -410,6 +410,9 @@ struct wpa_config { void wpa_config_free(struct wpa_config *ssid); void wpa_config_free_ssid(struct wpa_ssid *ssid); +void wpa_config_foreach_network(struct wpa_config *config, + void (*func)(void *, struct wpa_ssid *), + void *arg); struct wpa_ssid * wpa_config_get_network(struct wpa_config *config, int id); struct wpa_ssid * wpa_config_add_network(struct wpa_config *config); int wpa_config_remove_network(struct wpa_config *config, int id); diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c index d86552fad..63bea98e8 100644 --- a/wpa_supplicant/dbus/dbus_new.c +++ b/wpa_supplicant/dbus/dbus_new.c @@ -1312,6 +1312,12 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = { END_ARGS } }, + { "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) &wpas_dbus_handler_remove_all_networks, + { + END_ARGS + } + }, { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, (WPADBusMethodHandler) &wpas_dbus_handler_select_network, { diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index b590d6216..c7014328b 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -1470,6 +1470,42 @@ out: } +static void remove_network(void *arg, struct wpa_ssid *ssid) +{ + struct wpa_supplicant *wpa_s = arg; + + wpas_notify_network_removed(wpa_s, ssid); + + if (wpa_config_remove_network(wpa_s->conf, ssid->id) < 0) { + wpa_printf(MSG_ERROR, + "wpas_dbus_handler_remove_all_networks[dbus]: " + "error occurred when removing network %d", + ssid->id); + return; + } + + if (ssid == wpa_s->current_ssid) + wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); +} + + +/** + * wpas_dbus_handler_remove_all_networks - Remove all configured networks + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: NULL on success or dbus error on failure + * + * Handler function for "RemoveAllNetworks" method call of a network interface. + */ +DBusMessage * wpas_dbus_handler_remove_all_networks( + DBusMessage *message, struct wpa_supplicant *wpa_s) +{ + /* NB: could check for failure and return an error */ + wpa_config_foreach_network(wpa_s->conf, remove_network, wpa_s); + return NULL; +} + + /** * wpas_dbus_handler_select_network - Attempt association with a network * @message: Pointer to incoming dbus message diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h index dcac3520a..288cd43b9 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.h +++ b/wpa_supplicant/dbus/dbus_new_handlers.h @@ -83,6 +83,9 @@ DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message, DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message, struct wpa_supplicant *wpa_s); +DBusMessage * wpas_dbus_handler_remove_all_networks( + DBusMessage *message, struct wpa_supplicant *wpa_s); + DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message, struct wpa_supplicant *wpa_s);