]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2PS: Callback to remove stale persistent groups
authorKrishna Vamsi <vamsin@qti.qualcomm.com>
Wed, 10 Dec 2014 13:38:17 +0000 (19:08 +0530)
committerJouni Malinen <j@w1.fi>
Mon, 2 Feb 2015 23:35:07 +0000 (01:35 +0200)
When the peer device is trying to form a new group despite having
old persistent group with same roles, remove the stale persistent
group.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/p2p/p2p.h
wpa_supplicant/p2p_supplicant.c

index 317dbacda35ae5cd50408c3cd67c6c793bb99891..2681a6b9d0a83273e0c899d9dee259e9f1c9c369 100644 (file)
@@ -970,6 +970,16 @@ struct p2p_config {
         */
        int (*get_go_info)(void *ctx, u8 *intended_addr,
                           u8 *ssid, size_t *ssid_len, int *group_iface);
+
+       /**
+        * remove_stale_groups - Remove stale P2PS groups
+        *
+        * Because P2PS stages *potential* GOs, and remote devices can remove
+        * credentials unilaterally, we need to make sure we don't let stale
+        * unusable groups build up.
+        */
+       int (*remove_stale_groups)(void *ctx, const u8 *peer, const u8 *go,
+                                  const u8 *ssid, size_t ssid_len);
 };
 
 
index 95aa9707e67d9c7dc79d9f87c825931ff78b02bc..47cf05642722110ca99a0cb98514f367926163ea 100644 (file)
@@ -1608,6 +1608,16 @@ static void p2p_go_save_group_common_freqs(struct wpa_supplicant *wpa_s,
 }
 
 
+static void p2p_config_write(struct wpa_supplicant *wpa_s)
+{
+#ifndef CONFIG_NO_CONFIG_WRITE
+       if (wpa_s->parent->conf->update_config &&
+           wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf))
+               wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
+#endif /* CONFIG_NO_CONFIG_WRITE */
+}
+
+
 static void p2p_go_configured(void *ctx, void *data)
 {
        struct wpa_supplicant *wpa_s = ctx;
@@ -4674,6 +4684,51 @@ static int wpas_get_go_info(void *ctx, u8 *intended_addr,
 }
 
 
+static int wpas_remove_stale_groups(void *ctx, const u8 *peer, const u8 *go,
+                                   const u8 *ssid, size_t ssid_len)
+{
+       struct wpa_supplicant *wpa_s = ctx;
+       struct wpa_ssid *s;
+       int save_config = 0;
+       size_t i;
+
+       /* Start with our first choice of Persistent Groups */
+       while ((s = wpas_p2p_get_persistent(wpa_s, peer, NULL, 0))) {
+               if (go && ssid && ssid_len &&
+                   s->ssid_len == ssid_len &&
+                   os_memcmp(go, s->bssid, ETH_ALEN) == 0 &&
+                   os_memcmp(ssid, s->ssid, ssid_len) == 0)
+                       break;
+
+               /* Remove stale persistent group */
+               if (s->mode != WPAS_MODE_P2P_GO || s->num_p2p_clients <= 1) {
+                       wpa_config_remove_network(wpa_s->conf, s->id);
+                       save_config = 1;
+                       continue;
+               }
+
+               for (i = 0; i < s->num_p2p_clients; i++) {
+                       if (os_memcmp(s->p2p_client_list + i * 2 * ETH_ALEN,
+                                     peer, ETH_ALEN) != 0)
+                               continue;
+
+                       os_memmove(s->p2p_client_list + i * 2 * ETH_ALEN,
+                                  s->p2p_client_list + (i + 1) * 2 * ETH_ALEN,
+                                  (s->num_p2p_clients - i - 1) * 2 * ETH_ALEN);
+                       break;
+               }
+               s->num_p2p_clients--;
+               save_config = 1;
+       }
+
+       if (save_config)
+               p2p_config_write(wpa_s);
+
+       /* Return TRUE if valid SSID remains */
+       return s != NULL;
+}
+
+
 static int _wpas_p2p_in_progress(void *ctx)
 {
        struct wpa_supplicant *wpa_s = ctx;
@@ -4730,6 +4785,7 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
        p2p.is_p2p_in_progress = _wpas_p2p_in_progress;
        p2p.get_persistent_group = wpas_get_persistent_group;
        p2p.get_go_info = wpas_get_go_info;
+       p2p.remove_stale_groups = wpas_remove_stale_groups;
 
        os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
        os_memcpy(p2p.dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN);