OSDN Git Service

wpa_supplicant: Update to 07-Jul-2012 TOT
[android-x86/external-wpa_supplicant_8.git] / src / ap / sta_info.c
index afabdaa..95b701c 100644 (file)
@@ -28,6 +28,7 @@
 #include "vlan_init.h"
 #include "p2p_hostapd.h"
 #include "ap_drv_ops.h"
+#include "gas_serv.h"
 #include "sta_info.h"
 
 static void ap_sta_remove_in_other_bss(struct hostapd_data *hapd,
@@ -194,6 +195,8 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
        if (set_beacon)
                ieee802_11_set_beacons(hapd->iface);
 
+       wpa_printf(MSG_DEBUG, "%s: cancel ap_handle_timer for " MACSTR,
+                  __func__, MAC2STR(sta->addr));
        eloop_cancel_timeout(ap_handle_timer, hapd, sta);
        eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
        eloop_cancel_timeout(ap_sta_deauth_cb_timeout, hapd, sta);
@@ -218,6 +221,15 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
        p2p_group_notif_disassoc(hapd->p2p_group, sta->addr);
 #endif /* CONFIG_P2P */
 
+#ifdef CONFIG_INTERWORKING
+       if (sta->gas_dialog) {
+               int i;
+               for (i = 0; i < GAS_DIALOG_MAX; i++)
+                       gas_serv_dialog_clear(&sta->gas_dialog[i]);
+               os_free(sta->gas_dialog);
+       }
+#endif /* CONFIG_INTERWORKING */
+
        wpabuf_free(sta->wps_ie);
        wpabuf_free(sta->p2p_ie);
 
@@ -262,6 +274,9 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
        struct sta_info *sta = timeout_ctx;
        unsigned long next_time = 0;
 
+       wpa_printf(MSG_DEBUG, "%s: " MACSTR " flags=0x%x timeout_next=%d",
+                  __func__, MAC2STR(sta->addr), sta->flags,
+                  sta->timeout_next);
        if (sta->timeout_next == STA_REMOVE) {
                hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
                               HOSTAPD_LEVEL_INFO, "deauthenticated due to "
@@ -274,6 +289,12 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
            (sta->timeout_next == STA_NULLFUNC ||
             sta->timeout_next == STA_DISASSOC)) {
                int inactive_sec;
+               /*
+                * Add random value to timeout so that we don't end up bouncing
+                * all stations at the same time if we have lots of associated
+                * stations that are idle (but keep re-associating).
+                */
+               int fuzz = os_random() % 20;
                inactive_sec = hostapd_drv_get_inact_sec(hapd, sta->addr);
                if (inactive_sec == -1) {
                        wpa_msg(hapd->msg_ctx, MSG_DEBUG,
@@ -285,7 +306,7 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
                         * Anyway, try again after the next inactivity timeout,
                         * but do not disconnect the station now.
                         */
-                       next_time = hapd->conf->ap_max_inactivity;
+                       next_time = hapd->conf->ap_max_inactivity + fuzz;
                } else if (inactive_sec < hapd->conf->ap_max_inactivity &&
                           sta->flags & WLAN_STA_ASSOC) {
                        /* station activity detected; reset timeout state */
@@ -293,7 +314,7 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
                                "Station " MACSTR " has been active %is ago",
                                MAC2STR(sta->addr), inactive_sec);
                        sta->timeout_next = STA_NULLFUNC;
-                       next_time = hapd->conf->ap_max_inactivity -
+                       next_time = hapd->conf->ap_max_inactivity + fuzz -
                                inactive_sec;
                } else {
                        wpa_msg(hapd->msg_ctx, MSG_DEBUG,
@@ -320,6 +341,9 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
        }
 
        if (next_time) {
+               wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout "
+                          "for " MACSTR " (%lu seconds)",
+                          __func__, MAC2STR(sta->addr), next_time);
                eloop_register_timeout(next_time, 0, ap_handle_timer, hapd,
                                       sta);
                return;
@@ -353,6 +377,9 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
        switch (sta->timeout_next) {
        case STA_NULLFUNC:
                sta->timeout_next = STA_DISASSOC;
+               wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout "
+                          "for " MACSTR " (%d seconds - AP_DISASSOC_DELAY)",
+                          __func__, MAC2STR(sta->addr), AP_DISASSOC_DELAY);
                eloop_register_timeout(AP_DISASSOC_DELAY, 0, ap_handle_timer,
                                       hapd, sta);
                break;
@@ -369,6 +396,9 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
                               HOSTAPD_LEVEL_INFO, "disassociated due to "
                               "inactivity");
                sta->timeout_next = STA_DEAUTH;
+               wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout "
+                          "for " MACSTR " (%d seconds - AP_DEAUTH_DELAY)",
+                          __func__, MAC2STR(sta->addr), AP_DEAUTH_DELAY);
                eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
                                       hapd, sta);
                mlme_disassociate_indication(
@@ -397,8 +427,14 @@ static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx)
        struct sta_info *sta = timeout_ctx;
        u8 addr[ETH_ALEN];
 
-       if (!(sta->flags & WLAN_STA_AUTH))
+       if (!(sta->flags & WLAN_STA_AUTH)) {
+               if (sta->flags & WLAN_STA_GAS) {
+                       wpa_printf(MSG_DEBUG, "GAS: Remove temporary STA "
+                                  "entry " MACSTR, MAC2STR(sta->addr));
+                       ap_free_sta(hapd, sta);
+               }
                return;
+       }
 
        mlme_deauthenticate_indication(hapd, sta,
                                       WLAN_REASON_PREV_AUTH_NOT_VALID);
@@ -455,6 +491,10 @@ struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
        sta->acct_interim_interval = hapd->conf->acct_interim_interval;
 
        /* initialize STA info data */
+       wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout "
+                  "for " MACSTR " (%d seconds - ap_max_inactivity)",
+                  __func__, MAC2STR(addr),
+                  hapd->conf->ap_max_inactivity);
        eloop_register_timeout(hapd->conf->ap_max_inactivity, 0,
                               ap_handle_timer, hapd, sta);
        os_memcpy(sta->addr, addr, ETH_ALEN);
@@ -528,6 +568,11 @@ void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta,
        sta->flags &= ~WLAN_STA_ASSOC;
        ap_sta_set_authorized(hapd, sta, 0);
        sta->timeout_next = STA_DEAUTH;
+       wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout "
+                  "for " MACSTR " (%d seconds - "
+                  "AP_MAX_INACTIVITY_AFTER_DISASSOC)",
+                  __func__, MAC2STR(sta->addr),
+                  AP_MAX_INACTIVITY_AFTER_DISASSOC);
        eloop_cancel_timeout(ap_handle_timer, hapd, sta);
        eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DISASSOC, 0,
                               ap_handle_timer, hapd, sta);
@@ -561,6 +606,11 @@ void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta,
        sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
        ap_sta_set_authorized(hapd, sta, 0);
        sta->timeout_next = STA_REMOVE;
+       wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout "
+                  "for " MACSTR " (%d seconds - "
+                  "AP_MAX_INACTIVITY_AFTER_DEAUTH)",
+                  __func__, MAC2STR(sta->addr),
+                  AP_MAX_INACTIVITY_AFTER_DEAUTH);
        eloop_cancel_timeout(ap_handle_timer, hapd, sta);
        eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH, 0,
                               ap_handle_timer, hapd, sta);
@@ -576,6 +626,23 @@ void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta,
 }
 
 
+#ifdef CONFIG_WPS
+int ap_sta_wps_cancel(struct hostapd_data *hapd,
+                     struct sta_info *sta, void *ctx)
+{
+       if (sta && (sta->flags & WLAN_STA_WPS)) {
+               ap_sta_deauthenticate(hapd, sta,
+                                     WLAN_REASON_PREV_AUTH_NOT_VALID);
+               wpa_printf(MSG_DEBUG, "WPS: %s: Deauth sta=" MACSTR,
+                          __func__, MAC2STR(sta->addr));
+               return 1;
+       }
+
+       return 0;
+}
+#endif /* CONFIG_WPS */
+
+
 int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta,
                     int old_vlanid)
 {
@@ -778,11 +845,20 @@ void ap_sta_set_authorized(struct hostapd_data *hapd, struct sta_info *sta,
                           int authorized)
 {
        const u8 *dev_addr = NULL;
+#ifdef CONFIG_P2P
+       u8 addr[ETH_ALEN];
+#endif /* CONFIG_P2P */
+
        if (!!authorized == !!(sta->flags & WLAN_STA_AUTHORIZED))
                return;
 
 #ifdef CONFIG_P2P
-       dev_addr = p2p_group_get_dev_addr(hapd->p2p_group, sta->addr);
+       if (hapd->p2p_group == NULL) {
+               if (sta->p2p_ie != NULL &&
+                   p2p_parse_dev_addr_in_p2p_ie(sta->p2p_ie, addr) == 0)
+                       dev_addr = addr;
+       } else
+               dev_addr = p2p_group_get_dev_addr(hapd->p2p_group, sta->addr);
 #endif /* CONFIG_P2P */
 
        if (authorized) {
@@ -848,6 +924,11 @@ void ap_sta_disconnect(struct hostapd_data *hapd, struct sta_info *sta,
        wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
        ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
        sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
+       wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout "
+                  "for " MACSTR " (%d seconds - "
+                  "AP_MAX_INACTIVITY_AFTER_DEAUTH)",
+                  __func__, MAC2STR(sta->addr),
+                  AP_MAX_INACTIVITY_AFTER_DEAUTH);
        eloop_cancel_timeout(ap_handle_timer, hapd, sta);
        eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH, 0,
                               ap_handle_timer, hapd, sta);