From c2762e410fa319f75a174aeb12343beddf99fce4 Mon Sep 17 00:00:00 2001 From: Jayant Sane Date: Thu, 23 Jun 2011 21:25:13 +0300 Subject: [PATCH] P2P: Update D-Bus network object semantics during group formation Do not emit network objects during P2P group formation since such network objects can confuse certain apps. Instead, a persistent group object is created to allow apps to keep track of persistent groups. Persistent group objects only represent the info needed to recreate the group. Also fixes a minor bug in the handling of persistent group objects during WPS operations. Signed-off-by: Jayant Sane --- wpa_supplicant/dbus/dbus_new.c | 260 ++++++++++++++++++++ wpa_supplicant/dbus/dbus_new.h | 24 ++ wpa_supplicant/dbus/dbus_new_handlers.c | 5 +- wpa_supplicant/dbus/dbus_new_handlers_p2p.c | 84 +++++++ wpa_supplicant/dbus/dbus_new_handlers_p2p.h | 9 + wpa_supplicant/notify.c | 19 +- wpa_supplicant/notify.h | 2 + wpa_supplicant/p2p_supplicant.c | 24 +- wpa_supplicant/wpa_supplicant_i.h | 11 + wpa_supplicant/wps_supplicant.c | 15 +- 10 files changed, 442 insertions(+), 11 deletions(-) diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c index 5e9ef6a9c..806b61f2b 100644 --- a/wpa_supplicant/dbus/dbus_new.c +++ b/wpa_supplicant/dbus/dbus_new.c @@ -1281,6 +1281,102 @@ error: dbus_message_unref(msg); } +/** + * wpas_dbus_signal_persistent_group - Send a persistent group related + * event signal + * @wpa_s: %wpa_supplicant network interface data + * @id: new persistent group id + * @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved + * @properties: determines if add second argument with object properties + * + * Notify listeners about an event related to persistent groups. + */ +static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s, + int id, const char *sig_name, + int properties) +{ + struct wpas_dbus_priv *iface; + DBusMessage *msg; + DBusMessageIter iter, iter_dict; + char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path; + + iface = wpa_s->global->dbus; + + /* Do nothing if the control interface is not turned on */ + if (iface == NULL) + return; + + os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u", + wpa_s->dbus_new_path, id); + + msg = dbus_message_new_signal(wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_P2PDEVICE, + sig_name); + if (msg == NULL) + return; + + dbus_message_iter_init_append(msg, &iter); + path = pgrp_obj_path; + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, + &path)) + goto err; + + if (properties) { + if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) + goto err; + + wpa_dbus_get_object_properties( + iface, pgrp_obj_path, + WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, + &iter_dict); + + if (!wpa_dbus_dict_close_write(&iter, &iter_dict)) + goto err; + } + + dbus_connection_send(iface->con, msg, NULL); + + dbus_message_unref(msg); + return; + +err: + wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); + dbus_message_unref(msg); +} + + +/** + * wpas_dbus_signal_persistent_group_added - Send a persistent_group + * added signal + * @wpa_s: %wpa_supplicant network interface data + * @id: new persistent group id + * + * Notify listeners about addition of a new persistent group. + */ +static void wpas_dbus_signal_persistent_group_added( + struct wpa_supplicant *wpa_s, int id) +{ + wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupAdded", + TRUE); +} + + +/** + * wpas_dbus_signal_persistent_group_removed - Send a persistent_group + * removed signal + * @wpa_s: %wpa_supplicant network interface data + * @id: persistent group id + * + * Notify listeners about removal of a persistent group. + */ +static void wpas_dbus_signal_persistent_group_removed( + struct wpa_supplicant *wpa_s, int id) +{ + wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupRemoved", + TRUE); +} + #endif /*CONFIG_P2P*/ @@ -1654,6 +1750,14 @@ int wpas_dbus_register_network(struct wpa_supplicant *wpa_s, struct network_handler_args *arg; char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; + /* + * If it is a persistent group register it as such. + * This is to handle cases where an interface is being initialized + * with a list of networks read from config. + */ + if (network_is_persistent_group(ssid)) + return wpas_dbus_register_persistent_group(wpa_s, ssid); + /* Do nothing if the control interface is not turned on */ if (wpa_s == NULL || wpa_s->global == NULL) return 0; @@ -1716,6 +1820,13 @@ int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid) struct wpas_dbus_priv *ctrl_iface; char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; int ret; + struct wpa_ssid *ssid; + + ssid = wpa_config_get_network(wpa_s->conf, nid); + + /* If it is a persistent group unregister it as such */ + if (ssid && network_is_persistent_group(ssid)) + return wpas_dbus_unregister_persistent_group(wpa_s, nid); /* Do nothing if the control interface is not turned on */ if (wpa_s == NULL || wpa_s->global == NULL || @@ -2245,6 +2356,10 @@ static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = { (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peergo, NULL, R }, + { "PersistentGroups", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao", + (WPADBusPropertyAccessor) wpas_dbus_getter_persistent_groups, + NULL, R + }, #endif /* CONFIG_P2P */ { NULL, NULL, NULL, NULL, NULL, 0 } }; @@ -2441,6 +2556,13 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = { END_ARGS } }, + { "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE, + { + { "path", "o", ARG_OUT }, + { "properties", "a{sv}", ARG_OUT }, + END_ARGS + } + }, #endif /* CONFIG_P2P */ { NULL, NULL, { END_ARGS } } }; @@ -2954,4 +3076,142 @@ void wpas_dbus_unregister_p2p_groupmember(struct wpa_supplicant *wpa_s, wpa_dbus_unregister_object_per_iface(ctrl_iface, groupmember_obj_path); } + + +static const struct wpa_dbus_property_desc + wpas_dbus_persistent_group_properties[] = { + { "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}", + (WPADBusPropertyAccessor) + wpas_dbus_getter_persistent_group_properties, + NULL, + R + }, + { NULL, NULL, NULL, NULL, NULL, 0 } +}; + +/* No signals intended for persistent group objects */ + +/** + * wpas_dbus_register_persistent_group - Register a configured(saved) + * persistent group with dbus + * @wpa_s: wpa_supplicant interface structure + * @ssid: persistent group (still represented as a network within wpa) + * configuration data + * Returns: 0 on success, -1 on failure + * + * Registers a persistent group representing object with dbus. + */ +int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid) +{ + struct wpas_dbus_priv *ctrl_iface; + struct wpa_dbus_object_desc *obj_desc; + struct network_handler_args *arg; + char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; + + /* Do nothing if the control interface is not turned on */ + if (wpa_s == NULL || wpa_s->global == NULL) + return 0; + + /* Make sure ssid is a persistent group */ + if (ssid->disabled != 2 && !ssid->p2p_persistent_group) + return -1; /* should we return w/o complaining? */ + + ctrl_iface = wpa_s->global->dbus; + if (ctrl_iface == NULL) + return 0; + + /* + * Intentionally not coming up with different numbering scheme + * for persistent groups. + */ + os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u", + wpa_s->dbus_new_path, ssid->id); + + wpa_printf(MSG_DEBUG, "dbus: Register persistent group object '%s'", + pgrp_obj_path); + obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc)); + if (!obj_desc) { + wpa_printf(MSG_ERROR, "dbus: Not enough memory to create " + "object description"); + goto err; + } + + /* + * Reusing the same context structure as that for networks + * since these are represented using same data structure. + */ + /* allocate memory for handlers arguments */ + arg = os_zalloc(sizeof(struct network_handler_args)); + if (!arg) { + wpa_printf(MSG_ERROR, "dbus: Not enough memory to create " + "arguments for method"); + goto err; + } + + arg->wpa_s = wpa_s; + arg->ssid = ssid; + + wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL, + wpas_dbus_persistent_group_properties, + NULL); + + if (wpa_dbus_register_object_per_iface(ctrl_iface, pgrp_obj_path, + wpa_s->ifname, obj_desc)) + goto err; + + wpas_dbus_signal_persistent_group_added(wpa_s, ssid->id); + + return 0; + +err: + free_dbus_object_desc(obj_desc); + return -1; +} + + +/** + * wpas_dbus_unregister_persistent_group - Unregister a persistent_group + * from dbus + * @wpa_s: wpa_supplicant interface structure + * @nid: network id + * Returns: 0 on success, -1 on failure + * + * Unregisters persistent group representing object from dbus + * + * NOTE: There is a slight issue with the semantics here. While the + * implementation simply means the persistent group is unloaded from memory, + * it should not get interpreted as the group is actually being erased/removed + * from persistent storage as well. + */ +int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s, + int nid) +{ + struct wpas_dbus_priv *ctrl_iface; + char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; + int ret; + + /* Do nothing if the control interface is not turned on */ + if (wpa_s == NULL || wpa_s->global == NULL || + wpa_s->dbus_new_path == NULL) + return 0; + ctrl_iface = wpa_s->global->dbus; + if (ctrl_iface == NULL) + return 0; + + os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u", + wpa_s->dbus_new_path, nid); + + wpa_printf(MSG_DEBUG, "dbus: Unregister persistent group object '%s'", + pgrp_obj_path); + ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, pgrp_obj_path); + + if (!ret) + wpas_dbus_signal_persistent_group_removed(wpa_s, nid); + + return ret; +} + #endif /* CONFIG_P2P */ diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h index e8376fe0a..92cc36534 100644 --- a/wpa_supplicant/dbus/dbus_new.h +++ b/wpa_supplicant/dbus/dbus_new.h @@ -72,6 +72,14 @@ enum wpas_dbus_bss_prop { #define WPAS_DBUS_NEW_P2P_GROUPS_PART "Groups" #define WPAS_DBUS_NEW_IFACE_P2P_GROUP WPAS_DBUS_NEW_INTERFACE ".Group" +/* + * Different dbus object for persistent groups so they do not get confused + * with regular (configured) network objects. + */ +#define WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "PersistentGroups" +#define WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP \ + WPAS_DBUS_NEW_INTERFACE ".PersistentGroup" + #define WPAS_DBUS_NEW_P2P_PEERS_PART "Peers" #define WPAS_DBUS_NEW_IFACE_P2P_PEER WPAS_DBUS_NEW_INTERFACE ".Peer" @@ -170,6 +178,10 @@ void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s, void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s, int status); void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid); +int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid); +int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s, + int nid); void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s, int status, const u8 *bssid); void wpas_dbus_register_p2p_groupmember(struct wpa_supplicant *wpa_s, @@ -344,6 +356,18 @@ wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s, { } +static inline int wpas_dbus_register_persistent_group( + struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) +{ + return 0; +} + +static inline int wpas_dbus_unregister_persistent_group( + struct wpa_supplicant *wpa_s, int nid) +{ + return 0; +} + static inline void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s, int status) { diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index 87314960e..168142ffb 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -2508,7 +2508,8 @@ DBusMessage * wpas_dbus_getter_networks(DBusMessage *message, } for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) - num++; + if (!network_is_persistent_group(ssid)) + num++; paths = os_zalloc(num * sizeof(char *)); if (!paths) { @@ -2518,6 +2519,8 @@ DBusMessage * wpas_dbus_getter_networks(DBusMessage *message, /* Loop through configured networks and append object path of each */ for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { + if (network_is_persistent_group(ssid)) + continue; paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); if (paths[i] == NULL) { reply = dbus_message_new_error(message, diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c index ec43d0cb0..42391c3e3 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c +++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c @@ -1207,6 +1207,90 @@ DBusMessage *wpas_dbus_getter_p2p_peer_ies(DBusMessage * message, } +/** + * wpas_dbus_getter_persistent_groups - Get array of peristent group objects + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: a dbus message containing an array of all persistent group + * dbus object paths. + * + * Getter for "Networks" property. + */ +DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + struct wpa_ssid *ssid; + char **paths; + unsigned int i = 0, num = 0; + + if (wpa_s->conf == NULL) { + wpa_printf(MSG_ERROR, "dbus: " + "wpas_dbus_getter_persistent_groups: " + "An error occurred getting persistent groups list"); + return wpas_dbus_error_unknown_error(message, NULL); + } + + for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) + if (network_is_persistent_group(ssid)) + num++; + + paths = os_zalloc(num * sizeof(char *)); + if (!paths) { + return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + NULL); + } + + /* Loop through configured networks and append object path of each */ + for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { + if (!network_is_persistent_group(ssid)) + continue; + paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); + if (paths[i] == NULL) { + reply = dbus_message_new_error(message, + DBUS_ERROR_NO_MEMORY, + NULL); + goto out; + } + /* Construct the object path for this network. */ + os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%d", + wpa_s->dbus_new_path, ssid->id); + } + + reply = wpas_dbus_simple_array_property_getter(message, + DBUS_TYPE_OBJECT_PATH, + paths, num); + +out: + while (i) + os_free(paths[--i]); + os_free(paths); + return reply; +} + + +/** + * wpas_dbus_getter_persistent_group_properties - Get options for a persistent + * group + * @message: Pointer to incoming dbus message + * @net: wpa_supplicant structure for a network interface and + * wpa_ssid structure for a configured persistent group (internally network) + * Returns: DBus message with network properties or DBus error on failure + * + * Getter for "Properties" property of a persistent group. + */ +DBusMessage * wpas_dbus_getter_persistent_group_properties( + DBusMessage *message, struct network_handler_args *net) +{ + /* + * Leveraging the fact that persistent group object is still + * represented in same manner as network within. + */ + return wpas_dbus_getter_network_properties(message, net); +} + + /* * Group object properties accessor methods */ diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.h b/wpa_supplicant/dbus/dbus_new_handlers_p2p.h index b0c192966..14a139323 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.h +++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.h @@ -139,4 +139,13 @@ DBusMessage *wpas_dbus_setter_p2p_group_properties( DBusMessage *message, struct wpa_supplicant *wpa_s); +/* + * P2P Persistent Group properties + */ + +DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message, + struct wpa_supplicant *wpa_s); +DBusMessage * wpas_dbus_getter_persistent_group_properties( + DBusMessage *message, struct network_handler_args *net); + #endif /* DBUS_NEW_HANDLERS_P2P_H */ diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c index a60db1343..dd595e0d4 100644 --- a/wpa_supplicant/notify.c +++ b/wpa_supplicant/notify.c @@ -206,14 +206,29 @@ void wpas_notify_wps_event_success(struct wpa_supplicant *wpa_s) void wpas_notify_network_added(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { - wpas_dbus_register_network(wpa_s, ssid); + /* + * Networks objects created during any P2P activities should not be + * exposed out. They might/will confuse certain non-P2P aware + * applications since these network objects won't behave like + * regular ones. + */ + if (wpa_s->global->p2p_group_formation != wpa_s) + wpas_dbus_register_network(wpa_s, ssid); +} + + +void wpas_notify_persistent_group_added(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid) +{ + wpas_dbus_register_persistent_group(wpa_s, ssid); } void wpas_notify_network_removed(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { - wpas_dbus_unregister_network(wpa_s, ssid->id); + if (wpa_s->global->p2p_group_formation != wpa_s) + wpas_dbus_unregister_network(wpa_s, ssid->id); } diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h index 1e7109193..a6c800cd3 100644 --- a/wpa_supplicant/notify.h +++ b/wpa_supplicant/notify.h @@ -111,5 +111,7 @@ void wpas_notify_p2p_provision_discovery(struct wpa_supplicant *wpa_s, void wpas_notify_p2p_group_started(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int network_id, int client); +void wpas_notify_persistent_group_added(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid); #endif /* NOTIFY_H */ diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 345a7ff6c..3287df014 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -295,7 +295,15 @@ static void wpas_p2p_group_delete(struct wpa_supplicant *wpa_s) int id = ssid->id; if (ssid == wpa_s->current_ssid) wpa_s->current_ssid = NULL; - wpas_notify_network_removed(wpa_s, ssid); + /* + * Networks objects created during any P2P activities are not + * exposed out as they might/will confuse certain non-P2P aware + * applications since these network objects won't behave like + * regular ones. + * + * Likewise, we don't send out network removed signals for such + * network objects. + */ wpa_config_remove_network(wpa_s->conf, id); wpa_supplicant_clear_status(wpa_s); } else { @@ -400,7 +408,16 @@ static int wpas_p2p_store_persistent_group(struct wpa_supplicant *wpa_s, s = wpa_config_add_network(wpa_s->conf); if (s == NULL) return -1; - wpas_notify_network_added(wpa_s, s); + + /* + * Instead of network_added we emit persistent_group_added + * notification. Also to keep the defense checks in + * persistent_group obj registration method, we set the + * relevant flags in s to designate it as a persistent group. + */ + s->p2p_group = 1; + s->p2p_persistent_group = 1; + wpas_notify_persistent_group_added(wpa_s, s); wpa_config_set_network_defaults(s); } @@ -904,7 +921,6 @@ static void wpas_start_wps_go(struct wpa_supplicant *wpa_s, if (ssid == NULL) return; - wpas_notify_network_added(wpa_s, ssid); wpa_config_set_network_defaults(ssid); ssid->temporary = 1; ssid->p2p_group = 1; @@ -3303,7 +3319,6 @@ static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s, ssid = wpa_config_add_network(wpa_s->conf); if (ssid == NULL) return -1; - wpas_notify_network_added(wpa_s, ssid); wpa_config_set_network_defaults(ssid); ssid->temporary = 1; ssid->proto = WPA_PROTO_RSN; @@ -3312,7 +3327,6 @@ static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s, ssid->key_mgmt = WPA_KEY_MGMT_PSK; ssid->ssid = os_malloc(params->ssid_len); if (ssid->ssid == NULL) { - wpas_notify_network_removed(wpa_s, ssid); wpa_config_remove_network(wpa_s->conf, ssid->id); return -1; } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index c4d70f3fc..c1a88089b 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -17,6 +17,7 @@ #include "utils/list.h" #include "common/defs.h" +#include "config_ssid.h" extern const char *wpa_supplicant_version; extern const char *wpa_supplicant_license; @@ -642,4 +643,14 @@ void wpa_supplicant_connect(struct wpa_supplicant *wpa_s, /* eap_register.c */ int eap_register_methods(void); +/** + * Utility method to tell if a given network is a persistent group + * @ssid: Network object + * Returns: 1 if network is a persistent group, 0 otherwise + */ +static inline int network_is_persistent_group(struct wpa_ssid *ssid) +{ + return ((ssid->disabled == 2) || ssid->p2p_persistent_group); +} + #endif /* WPA_SUPPLICANT_I_H */ diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index 778ccaf37..ba59e7cf5 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -780,9 +780,18 @@ static void wpas_wps_reassoc(struct wpa_supplicant *wpa_s, ssid = wpa_s->conf->ssid; while (ssid) { int was_disabled = ssid->disabled; - ssid->disabled = ssid != selected; - if (was_disabled != ssid->disabled) - wpas_notify_network_enabled_changed(wpa_s, ssid); + /* + * In case the network object corresponds to a persistent group + * then do not send out network disabled signal. In addition, + * do not change disabled status of persistent network objects + * from 2 to 1 should we connect to another network. + */ + if (was_disabled != 2) { + ssid->disabled = ssid != selected; + if (was_disabled != ssid->disabled) + wpas_notify_network_enabled_changed(wpa_s, + ssid); + } ssid = ssid->next; } wpa_s->disconnected = 0;