]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Update D-Bus network object semantics during group formation
authorJayant Sane <jayant.sane@intel.com>
Thu, 23 Jun 2011 18:25:13 +0000 (21:25 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 23 Jun 2011 18:25:13 +0000 (21:25 +0300)
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 <jayant.sane@intel.com>
wpa_supplicant/dbus/dbus_new.c
wpa_supplicant/dbus/dbus_new.h
wpa_supplicant/dbus/dbus_new_handlers.c
wpa_supplicant/dbus/dbus_new_handlers_p2p.c
wpa_supplicant/dbus/dbus_new_handlers_p2p.h
wpa_supplicant/notify.c
wpa_supplicant/notify.h
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/wpa_supplicant_i.h
wpa_supplicant/wps_supplicant.c

index 5e9ef6a9cd157c58cb8ecb84aefa8c3ea5aff704..806b61f2ba83bb281953454d71103959ff0d32f2 100644 (file)
@@ -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 */
index e8376fe0aa8f369a846ba82820ede549582ba6c6..92cc365343fed8b75559e2cbb045d22ce25438e3 100644 (file)
@@ -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)
 {
index 87314960e52a0e5ead21c79c0fad83a9907f2db0..168142ffb8371e675d04bf9a4c7a5d24b83a51c2 100644 (file)
@@ -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,
index ec43d0cb006a3f3472588af2f3fa568828c0d20f..42391c3e3162d42f4d2589bf1772ec668a6b6128 100644 (file)
@@ -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
  */
index b0c192966c3152c0a686db66dc5f927dad424b3e..14a139323a12ec68014ca71fadb2408363f34186 100644 (file)
@@ -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 */
index a60db134367749e9738e264254d5b797a287b31d..dd595e0d48f3ee5cd2525a7d2aad23ee1ac6eba8 100644 (file)
@@ -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);
 }
 
 
index 1e7109193513ede0e442cf5703cc1b4a2c008d21..a6c800cd337670ef4e70b6b7f3aef2ec207febb2 100644 (file)
@@ -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 */
index 345a7ff6cf151e1e051437b4fe08e7057e981e26..3287df01458495df6fe89727563d48aeddd8ef50 100644 (file)
@@ -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;
        }
index c4d70f3fc8ce15369f1e4cb2898ea7dde15ab2fe..c1a88089b3d7bf269f69a237e4a74e94b8b3cbc3 100644 (file)
@@ -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 */
index 778ccaf37a20c4137b4b689ef31fad2bb1817df4..ba59e7cf5df8f4e76f629de2d687a6dbcfd4e3f6 100644 (file)
@@ -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;