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;