aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2013-03-15 14:31:31 (GMT)
committerJouni Malinen <j@w1.fi>2013-03-15 14:43:06 (GMT)
commitdbca75f82af4e4fb8ffb2071a64a88dc7b6c50f5 (patch)
tree82fb5a26ca95add9a56e54b32659925555e0383e /wpa_supplicant
parentb277a2bebc9365ec7db444d51e34aab6d1b48e63 (diff)
downloadhostap-dbca75f82af4e4fb8ffb2071a64a88dc7b6c50f5.zip
hostap-dbca75f82af4e4fb8ffb2071a64a88dc7b6c50f5.tar.gz
hostap-dbca75f82af4e4fb8ffb2071a64a88dc7b6c50f5.tar.bz2
P2P: Remove persistent group peer if it rejects invitation
If a peer replies to persistent group invitation with status code 8 (unknown group), remove the peer from the p2p_client_list if we are the GO or remove the persistent group if we are the P2P client since it looks like that the peer has dropped persistent group credentials and the provisioning step needs to be executed again. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/p2p_supplicant.c76
-rw-r--r--wpa_supplicant/wpa_supplicant.c2
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h1
3 files changed, 77 insertions, 2 deletions
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index afc0dfb..bbcde8f 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -2510,8 +2510,68 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid,
}
+static void wpas_remove_persistent_peer(struct wpa_supplicant *wpa_s,
+ struct wpa_ssid *ssid,
+ const u8 *peer)
+{
+ size_t i;
+
+ if (ssid == NULL)
+ return;
+
+ for (i = 0; ssid->p2p_client_list && i < ssid->num_p2p_clients; i++) {
+ if (os_memcmp(ssid->p2p_client_list + i * ETH_ALEN, peer,
+ ETH_ALEN) == 0)
+ break;
+ }
+ if (i >= ssid->num_p2p_clients) {
+ if (ssid->mode != WPAS_MODE_P2P_GO &&
+ os_memcmp(ssid->bssid, peer, ETH_ALEN) == 0) {
+ wpa_printf(MSG_DEBUG, "P2P: Remove persistent group %d "
+ "due to invitation result", ssid->id);
+ wpas_notify_network_removed(wpa_s, ssid);
+ wpa_config_remove_network(wpa_s->conf, ssid->id);
+ return;
+ }
+ return; /* Peer not found in client list */
+ }
+
+ wpa_printf(MSG_DEBUG, "P2P: Remove peer " MACSTR " from persistent "
+ "group %d client list due to invitation result",
+ MAC2STR(peer), ssid->id);
+ os_memmove(ssid->p2p_client_list + i * ETH_ALEN,
+ ssid->p2p_client_list + (i + 1) * ETH_ALEN,
+ (ssid->num_p2p_clients - i - 1) * ETH_ALEN);
+ ssid->num_p2p_clients--;
+#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 wpas_remove_persistent_client(struct wpa_supplicant *wpa_s,
+ const u8 *peer)
+{
+ struct wpa_ssid *ssid;
+
+ wpa_s = wpa_s->global->p2p_invite_group;
+ if (wpa_s == NULL)
+ return; /* No known invitation group */
+ ssid = wpa_s->current_ssid;
+ if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
+ !ssid->p2p_persistent_group)
+ return; /* Not operating as a GO in persistent group */
+ ssid = wpas_p2p_get_persistent(wpa_s->parent, peer,
+ ssid->ssid, ssid->ssid_len);
+ wpas_remove_persistent_peer(wpa_s, ssid, peer);
+}
+
+
static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
- const struct p2p_channels *channels)
+ const struct p2p_channels *channels,
+ const u8 *peer)
{
struct wpa_supplicant *wpa_s = ctx;
struct wpa_ssid *ssid;
@@ -2526,8 +2586,13 @@ static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
}
wpas_notify_p2p_invitation_result(wpa_s, status, bssid);
- if (wpa_s->pending_invite_ssid_id == -1)
+ wpa_printf(MSG_DEBUG, "P2P: Invitation result - status=%d peer=" MACSTR,
+ status, MAC2STR(peer));
+ if (wpa_s->pending_invite_ssid_id == -1) {
+ if (status == P2P_SC_FAIL_UNKNOWN_GROUP)
+ wpas_remove_persistent_client(wpa_s, peer);
return; /* Invitation to active group */
+ }
if (status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
wpa_printf(MSG_DEBUG, "P2P: Waiting for peer to start another "
@@ -2536,6 +2601,11 @@ static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
}
if (status != P2P_SC_SUCCESS) {
+ if (status == P2P_SC_FAIL_UNKNOWN_GROUP) {
+ ssid = wpa_config_get_network(
+ wpa_s->conf, wpa_s->pending_invite_ssid_id);
+ wpas_remove_persistent_peer(wpa_s, ssid, peer);
+ }
wpas_p2p_remove_pending_group_interface(wpa_s);
return;
}
@@ -4687,6 +4757,7 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
int force_freq = 0, oper_freq = 0;
int res;
+ wpa_s->global->p2p_invite_group = NULL;
if (peer_addr)
os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN);
else
@@ -4779,6 +4850,7 @@ int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
return -1;
}
+ wpa_s->global->p2p_invite_group = wpa_s;
persistent = ssid->p2p_persistent_group &&
wpas_p2p_get_persistent(wpa_s->parent, peer_addr,
ssid->ssid, ssid->ssid_len);
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 42a475f..908d798 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -3125,6 +3125,8 @@ int wpa_supplicant_remove_iface(struct wpa_global *global,
if (global->p2p_group_formation == wpa_s)
global->p2p_group_formation = NULL;
+ if (global->p2p_invite_group == wpa_s)
+ global->p2p_invite_group = NULL;
wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
os_free(wpa_s);
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 4ec15c1..5465c4f 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -228,6 +228,7 @@ struct wpa_global {
struct p2p_data *p2p;
struct wpa_supplicant *p2p_init_wpa_s;
struct wpa_supplicant *p2p_group_formation;
+ struct wpa_supplicant *p2p_invite_group;
u8 p2p_dev_addr[ETH_ALEN];
struct dl_list p2p_srv_bonjour; /* struct p2p_srv_bonjour */
struct dl_list p2p_srv_upnp; /* struct p2p_srv_upnp */