P2P: Remove client group on Deauthentication reason code 3
authorJouni Malinen <jouni@qca.qualcomm.com>
Tue, 3 Apr 2012 13:43:06 +0000 (16:43 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 3 Apr 2012 13:45:28 +0000 (16:45 +0300)
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>

wpa_supplicant/events.c
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/p2p_supplicant.h
wpa_supplicant/wpa_supplicant_i.h

index 79a4a55..8fdc544 100644 (file)
@@ -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);
index 413d0b2..f4e43a8 100644 (file)
@@ -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);
 }
 
 
index 4cd7193..8f8e635 100644 (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,
                        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);
index 14ef278..a494c49 100644 (file)
@@ -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;