P2P: Add group notifications
[libeap.git] / src / ap / sta_info.c
index 4016bd8..8cd6c3f 100644 (file)
  * See README and COPYING for more details.
  */
 
-#include "includes.h"
+#include "utils/includes.h"
 
-#include "common.h"
+#include "utils/common.h"
+#include "utils/eloop.h"
+#include "common/ieee802_11_defs.h"
 #include "radius/radius.h"
 #include "radius/radius_client.h"
 #include "drivers/driver.h"
+#include "p2p/p2p.h"
 #include "hostapd.h"
-#include "sta_info.h"
-#include "eloop.h"
 #include "accounting.h"
 #include "ieee802_1x.h"
 #include "ieee802_11.h"
-#include "wpa.h"
-#include "preauth.h"
-#include "config.h"
+#include "wpa_auth.h"
+#include "preauth_auth.h"
+#include "ap_config.h"
 #include "beacon.h"
-#include "mlme.h"
+#include "ap_mlme.h"
 #include "vlan_init.h"
+#include "sta_info.h"
 
-static int ap_sta_in_other_bss(struct hostapd_data *hapd,
-                              struct sta_info *sta, u32 flags);
+static void ap_sta_remove_in_other_bss(struct hostapd_data *hapd,
+                                      struct sta_info *sta);
 static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx);
 #ifdef CONFIG_IEEE80211W
 static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx);
@@ -120,9 +122,10 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
 
        accounting_sta_stop(hapd, sta);
 
-       hapd->drv.set_wds_sta(hapd, sta->addr, sta->aid, 0);
-       if (!ap_sta_in_other_bss(hapd, sta, WLAN_STA_ASSOC) &&
-           !(sta->flags & WLAN_STA_PREAUTH))
+       if (sta->flags & WLAN_STA_WDS)
+               hapd->drv.set_wds_sta(hapd, sta->addr, sta->aid, 0);
+
+       if (!(sta->flags & WLAN_STA_PREAUTH))
                hapd->drv.sta_remove(hapd, sta->addr);
 
        ap_sta_hash_del(hapd, sta);
@@ -197,7 +200,12 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
        eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
 #endif /* CONFIG_IEEE80211W */
 
+#ifdef CONFIG_P2P
+       p2p_group_notif_disassoc(hapd->p2p_group, sta->addr);
+#endif /* CONFIG_P2P */
+
        wpabuf_free(sta->wps_ie);
+       wpabuf_free(sta->p2p_ie);
 
        os_free(sta->ht_capabilities);
 
@@ -286,6 +294,7 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
 
        if (sta->timeout_next == STA_NULLFUNC &&
            (sta->flags & WLAN_STA_ASSOC)) {
+#ifndef CONFIG_NATIVE_WINDOWS
                /* send data frame to poll STA and check whether this frame
                 * is ACKed */
                struct ieee80211_hdr hdr;
@@ -293,7 +302,6 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
                wpa_printf(MSG_DEBUG, "  Polling STA with data frame");
                sta->flags |= WLAN_STA_PENDING_POLL;
 
-#ifndef CONFIG_NATIVE_WINDOWS
                os_memset(&hdr, 0, sizeof(hdr));
                if (hapd->driver &&
                    os_strcmp(hapd->driver->name, "hostap") == 0) {
@@ -449,6 +457,7 @@ struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
        hapd->num_sta++;
        ap_sta_hash_add(hapd, sta);
        sta->ssid = &hapd->conf->ssid;
+       ap_sta_remove_in_other_bss(hapd, sta);
 
        return sta;
 }
@@ -470,8 +479,8 @@ static int ap_sta_remove(struct hostapd_data *hapd, struct sta_info *sta)
 }
 
 
-static int ap_sta_in_other_bss(struct hostapd_data *hapd,
-                              struct sta_info *sta, u32 flags)
+static void ap_sta_remove_in_other_bss(struct hostapd_data *hapd,
+                                      struct sta_info *sta)
 {
        struct hostapd_iface *iface = hapd->iface;
        size_t i;
@@ -486,11 +495,12 @@ static int ap_sta_in_other_bss(struct hostapd_data *hapd,
                if (bss == hapd || bss == NULL)
                        continue;
                sta2 = ap_get_sta(bss, sta->addr);
-               if (sta2 && ((sta2->flags & flags) == flags))
-                       return 1;
-       }
+               if (!sta2)
+                       continue;
 
-       return 0;
+               ap_sta_disconnect(bss, sta2, sta2->addr,
+                                 WLAN_REASON_PREV_AUTH_NOT_VALID);
+       }
 }
 
 
@@ -500,8 +510,7 @@ void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta,
        wpa_printf(MSG_DEBUG, "%s: disassociate STA " MACSTR,
                   hapd->conf->iface, MAC2STR(sta->addr));
        sta->flags &= ~WLAN_STA_ASSOC;
-       if (!ap_sta_in_other_bss(hapd, sta, WLAN_STA_ASSOC))
-               ap_sta_remove(hapd, sta);
+       ap_sta_remove(hapd, sta);
        sta->timeout_next = STA_DEAUTH;
        eloop_cancel_timeout(ap_handle_timer, hapd, sta);
        eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DISASSOC, 0,
@@ -519,8 +528,7 @@ void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta,
        wpa_printf(MSG_DEBUG, "%s: deauthenticate STA " MACSTR,
                   hapd->conf->iface, MAC2STR(sta->addr));
        sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
-       if (!ap_sta_in_other_bss(hapd, sta, WLAN_STA_ASSOC))
-               ap_sta_remove(hapd, sta);
+       ap_sta_remove(hapd, sta);
        sta->timeout_next = STA_REMOVE;
        eloop_cancel_timeout(ap_handle_timer, hapd, sta);
        eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH, 0,
@@ -538,6 +546,7 @@ int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta,
 #ifndef CONFIG_NO_VLAN
        const char *iface;
        struct hostapd_vlan *vlan = NULL;
+       int ret;
 
        /*
         * Do not proceed furthur if the vlan id remains same. We do not want
@@ -633,7 +642,13 @@ int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta,
        if (wpa_auth_sta_set_vlan(sta->wpa_sm, sta->vlan_id) < 0)
                wpa_printf(MSG_INFO, "Failed to update VLAN-ID for WPA");
 
-       return hapd->drv.set_sta_vlan(iface, hapd, sta->addr, sta->vlan_id);
+       ret = hapd->drv.set_sta_vlan(iface, hapd, sta->addr, sta->vlan_id);
+       if (ret < 0) {
+               hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
+                              HOSTAPD_LEVEL_DEBUG, "could not bind the STA "
+                              "entry to vlan_id=%d", sta->vlan_id);
+       }
+       return ret;
 #else /* CONFIG_NO_VLAN */
        return 0;
 #endif /* CONFIG_NO_VLAN */