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 <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2012-04-03 16:43:06 +03:00 committed by Jouni Malinen
parent 52b2004285
commit 3fc14102f8
4 changed files with 40 additions and 15 deletions

View file

@ -2124,7 +2124,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
wpas_p2p_disassoc_notif( wpas_p2p_disassoc_notif(
wpa_s, data->disassoc_info.addr, reason_code, wpa_s, data->disassoc_info.addr, reason_code,
data->disassoc_info.ie, data->disassoc_info.ie,
data->disassoc_info.ie_len); data->disassoc_info.ie_len,
locally_generated);
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
} }
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) 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)", "Deauthentication frame IE(s)",
data->deauth_info.ie, data->deauth_info.ie,
data->deauth_info.ie_len); 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 #ifdef CONFIG_AP
@ -2175,6 +2169,15 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
#endif /* CONFIG_AP */ #endif /* CONFIG_AP */
wpa_supplicant_event_disassoc(wpa_s, reason_code, wpa_supplicant_event_disassoc(wpa_s, reason_code,
locally_generated); 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; break;
case EVENT_MICHAEL_MIC_FAILURE: case EVENT_MICHAEL_MIC_FAILURE:
wpa_supplicant_event_michael_mic_failure(wpa_s, data); wpa_supplicant_event_michael_mic_failure(wpa_s, data);

View file

@ -255,6 +255,9 @@ static void wpas_p2p_group_delete(struct wpa_supplicant *wpa_s)
case P2P_GROUP_REMOVAL_UNAVAILABLE: case P2P_GROUP_REMOVAL_UNAVAILABLE:
reason = " reason=UNAVAILABLE"; reason = " reason=UNAVAILABLE";
break; break;
case P2P_GROUP_REMOVAL_GO_ENDING_SESSION:
reason = " reason=GO_ENDING_SESSION";
break;
default: default:
reason = ""; reason = "";
break; 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, 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) if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
return; return;
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)
return; 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, 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) if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
return; return;
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)
return; 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);
} }

View file

@ -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, int wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period,
unsigned int interval); unsigned int interval);
void wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid, 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, 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); 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 wpas_p2p_set_noa(struct wpa_supplicant *wpa_s, u8 count, int start,
int duration); int duration);

View file

@ -503,7 +503,8 @@ struct wpa_supplicant {
P2P_GROUP_REMOVAL_UNKNOWN, P2P_GROUP_REMOVAL_UNKNOWN,
P2P_GROUP_REMOVAL_REQUESTED, P2P_GROUP_REMOVAL_REQUESTED,
P2P_GROUP_REMOVAL_IDLE_TIMEOUT, P2P_GROUP_REMOVAL_IDLE_TIMEOUT,
P2P_GROUP_REMOVAL_UNAVAILABLE P2P_GROUP_REMOVAL_UNAVAILABLE,
P2P_GROUP_REMOVAL_GO_ENDING_SESSION
} removal_reason; } removal_reason;
unsigned int p2p_cb_on_scan_complete:1; unsigned int p2p_cb_on_scan_complete:1;