P2P disconnect problem
Jouni Malinen
j
Sun Aug 2 09:32:56 PDT 2015
On Fri, Jul 31, 2015 at 10:19:05AM +0200, Michael Olbrich wrote:
> I have the problem, that ending a P2P connection does not work correctly
> under certain circumstances.
> With a Windows Tablet, it does not work as expected:
> - the group interface is disconnected but not removed
This is expected if the GO does not indicate group termination properly.
> - after the Group idle timeout is reached, the group and interface are
> removed
This is also expected in case of no explicit group termination
indication.
> - The changes to the peer group list are never announced
But this does not sound correct.
> The Android tablet sends a unicast 'deauthentication' frame with a reason
> code 3 ( STA is leaving), At least that's what wireshark on a monitor
> interface tells me.
This is correct GO behavior for indicating group termination.
> The Windows tablet sends a unicast 'deauthentication' frame with a reason
> code 0 (unknown) followed by a broadcast 'deauthentication' frame with a
> reason code 3 ( STA is leaving).
This is broken.. That unicast Deauthentication frame should have used
reason code 3.
> I don't think the second reaches wpa_supplicant.
Not after the unicast Deauthentication frame.
> It seems the reason code is checked in various places, e.g. in
> wpas_event_disconnect() and for reason code == 0 some steps are skipped.
Correct. Reason code 3 has special meaning for P2P.
> One side effect is, that wpa_supplicant_mark_disassoc() is called before
> wpas_dbus_unregister_p2p_group(). wpa_supplicant_mark_disassoc() clears
> wpa_s->go_dev_addr and as a result, in signal_peer_groups_changed()
> wpas_get_p2p_client_iface() returns NULL and
> wpas_dbus_signal_peer_groups_changed() is never called.
That is not the only issue, i.e., wpa_s->current_ssid is also cleared to
NULL in this case.
> Then the disconnect works as expected so this is the cause of my problem.
> I'm guessing the reason code is checked for a reason. So what is really
> supposed to happen in this case?
Well.. The GO device that sends reason code 0 should really be fixed,
but as far as wpa_supplicant behavior as a P2P Client is concerned, the
following change should fix the missing D-Bus signal on group idle
timeout:
[PATCH] P2P: Do not clear wpa_s->go_dev_addr before group removal
This variable is needed to figure out whether a wpa_supplicant interface
is for a P2P group that is (or was) connected to a specific GO. The
previous implementation was able to find such a case only when there was
an association with the GO. However, this may be needed even if there is
a temporary disconnection from the GO. Keep the GO device address
information over such temporary disconnections and only remove it on
group termination. This fixes an issue with D-Bus Peer PropertiesChanged
signals for the Groups property in case a P2P group gets removed due to
group idle timeout instead of explicit group termination command (local
request) or GO notification.
Signed-off-by: Jouni Malinen <j at w1.fi>
---
wpa_supplicant/events.c | 3 ---
wpa_supplicant/p2p_supplicant.c | 15 ++++++++-------
2 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 70f7511..ee2ff81 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -287,9 +287,6 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
os_memset(wpa_s->bssid, 0, ETH_ALEN);
os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
sme_clear_on_disassoc(wpa_s);
-#ifdef CONFIG_P2P
- os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN);
-#endif /* CONFIG_P2P */
wpa_s->current_bss = NULL;
wpa_s->assoc_freq = 0;
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 5bf612e..e41c2bf 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -946,6 +946,8 @@ static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s,
else
wpa_drv_deinit_p2p_cli(wpa_s);
+ os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN);
+
return 0;
}
@@ -1780,6 +1782,7 @@ static void wpas_start_wps_go(struct wpa_supplicant *wpa_s,
wpa_s->show_group_started = 0;
wpa_s->p2p_go_group_formation_completed = 0;
wpa_s->group_formation_reported = 0;
+ os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN);
wpa_config_set_network_defaults(ssid);
ssid->temporary = 1;
@@ -3391,12 +3394,7 @@ struct wpa_supplicant * wpas_get_p2p_client_iface(struct wpa_supplicant *wpa_s,
{
for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
struct wpa_ssid *ssid = wpa_s->current_ssid;
- if (ssid == NULL)
- continue;
- if (ssid->mode != WPAS_MODE_INFRA)
- continue;
- if (wpa_s->wpa_state != WPA_COMPLETED &&
- wpa_s->wpa_state != WPA_GROUP_HANDSHAKE)
+ if (ssid && (ssid->mode != WPAS_MODE_INFRA || !ssid->p2p_group))
continue;
if (os_memcmp(wpa_s->go_dev_addr, peer_dev_addr, ETH_ALEN) == 0)
return wpa_s;
@@ -5084,8 +5082,10 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
}
if_addr = wpa_s->pending_interface_addr;
- } else
+ } else {
if_addr = wpa_s->own_addr;
+ os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN);
+ }
if (auth) {
if (wpas_p2p_auth_go_neg(wpa_s, peer_addr, wps_method,
@@ -5609,6 +5609,7 @@ static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
ssid = wpa_config_add_network(wpa_s->conf);
if (ssid == NULL)
return -1;
+ os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN);
wpa_config_set_network_defaults(ssid);
ssid->temporary = 1;
ssid->proto = WPA_PROTO_RSN;
--
1.9.1
--
Jouni Malinen PGP id EFC895FA
More information about the Hostap
mailing list