From 3fc14102f8a0e50d32085364334ab4fac130b865 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 3 Apr 2012 16:43:06 +0300 Subject: [PATCH] P2P: Remove client group on Deauthentication reason code 3 The GO can indicate that the P2P Group session is ending by sending a Deauthentication frame with reason code 3 (Deauthenticated because sending STA is leaving) based on P2P specification section 3.2.9. Use this reason code to remove the P2P client group without waiting for the group idle timeout. Signed-hostap: Jouni Malinen --- wpa_supplicant/events.c | 19 +++++++++++-------- wpa_supplicant/p2p_supplicant.c | 27 +++++++++++++++++++++++---- wpa_supplicant/p2p_supplicant.h | 6 ++++-- wpa_supplicant/wpa_supplicant_i.h | 3 ++- 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 79a4a55cf..8fdc544da 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -2124,7 +2124,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, wpas_p2p_disassoc_notif( wpa_s, data->disassoc_info.addr, reason_code, data->disassoc_info.ie, - data->disassoc_info.ie_len); + data->disassoc_info.ie_len, + locally_generated); #endif /* CONFIG_P2P */ } if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) @@ -2152,13 +2153,6 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, "Deauthentication frame IE(s)", data->deauth_info.ie, data->deauth_info.ie_len); -#ifdef CONFIG_P2P - wpas_p2p_deauth_notif( - wpa_s, data->deauth_info.addr, - reason_code, - data->deauth_info.ie, - data->deauth_info.ie_len); -#endif /* CONFIG_P2P */ } } #ifdef CONFIG_AP @@ -2175,6 +2169,15 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, #endif /* CONFIG_AP */ wpa_supplicant_event_disassoc(wpa_s, reason_code, locally_generated); +#ifdef CONFIG_P2P + if (event == EVENT_DEAUTH && data) { + wpas_p2p_deauth_notif(wpa_s, data->deauth_info.addr, + reason_code, + data->deauth_info.ie, + data->deauth_info.ie_len, + locally_generated); + } +#endif /* CONFIG_P2P */ break; case EVENT_MICHAEL_MIC_FAILURE: wpa_supplicant_event_michael_mic_failure(wpa_s, data); diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 413d0b277..f4e43a882 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -255,6 +255,9 @@ static void wpas_p2p_group_delete(struct wpa_supplicant *wpa_s) case P2P_GROUP_REMOVAL_UNAVAILABLE: reason = " reason=UNAVAILABLE"; break; + case P2P_GROUP_REMOVAL_GO_ENDING_SESSION: + reason = " reason=GO_ENDING_SESSION"; + break; default: reason = ""; break; @@ -4031,26 +4034,42 @@ static void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s) void wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid, - u16 reason_code, const u8 *ie, size_t ie_len) + u16 reason_code, const u8 *ie, size_t ie_len, + int locally_generated) { if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) return; if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) return; - p2p_deauth_notif(wpa_s->global->p2p, bssid, reason_code, ie, ie_len); + if (!locally_generated) + p2p_deauth_notif(wpa_s->global->p2p, bssid, reason_code, ie, + ie_len); + + if (reason_code == WLAN_REASON_DEAUTH_LEAVING && !locally_generated && + wpa_s->current_ssid && + wpa_s->current_ssid->p2p_group && + wpa_s->current_ssid->mode == WPAS_MODE_INFRA) { + wpa_printf(MSG_DEBUG, "P2P: GO indicated that the P2P Group " + "session is ending"); + wpa_s->removal_reason = P2P_GROUP_REMOVAL_GO_ENDING_SESSION; + wpas_p2p_group_delete(wpa_s); + } } void wpas_p2p_disassoc_notif(struct wpa_supplicant *wpa_s, const u8 *bssid, - u16 reason_code, const u8 *ie, size_t ie_len) + u16 reason_code, const u8 *ie, size_t ie_len, + int locally_generated) { if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) return; if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) return; - p2p_disassoc_notif(wpa_s->global->p2p, bssid, reason_code, ie, ie_len); + if (!locally_generated) + p2p_disassoc_notif(wpa_s->global->p2p, bssid, reason_code, ie, + ie_len); } diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index 4cd71932e..8f8e635b3 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -105,9 +105,11 @@ int wpas_p2p_presence_req(struct wpa_supplicant *wpa_s, u32 duration1, int wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period, unsigned int interval); void wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid, - u16 reason_code, const u8 *ie, size_t ie_len); + u16 reason_code, const u8 *ie, size_t ie_len, + int locally_generated); void wpas_p2p_disassoc_notif(struct wpa_supplicant *wpa_s, const u8 *bssid, - u16 reason_code, const u8 *ie, size_t ie_len); + u16 reason_code, const u8 *ie, size_t ie_len, + int locally_generated); void wpas_p2p_update_config(struct wpa_supplicant *wpa_s); int wpas_p2p_set_noa(struct wpa_supplicant *wpa_s, u8 count, int start, int duration); diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 14ef278fe..a494c49de 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -503,7 +503,8 @@ struct wpa_supplicant { P2P_GROUP_REMOVAL_UNKNOWN, P2P_GROUP_REMOVAL_REQUESTED, P2P_GROUP_REMOVAL_IDLE_TIMEOUT, - P2P_GROUP_REMOVAL_UNAVAILABLE + P2P_GROUP_REMOVAL_UNAVAILABLE, + P2P_GROUP_REMOVAL_GO_ENDING_SESSION } removal_reason; unsigned int p2p_cb_on_scan_complete:1;