dbus: Minor coding style cleanup
[libeap.git] / hostapd / ap_list.c
index 5f5b5d4..a4eeb37 100644 (file)
@@ -1,8 +1,9 @@
 /*
  * hostapd / AP table
- * Copyright 2002-2003, Jouni Malinen <j@w1.fi>
- * Copyright 2003-2004, Instant802 Networks, Inc.
- * Copyright 2006, Devicescape Software, Inc.
+ * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2004, Instant802 Networks, Inc.
+ * Copyright (c) 2006, Devicescape Software, Inc.
+ * Copyright (c) 2007-2008, Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 #include "includes.h"
 
 #include "hostapd.h"
+#include "config.h"
 #include "ieee802_11.h"
 #include "eloop.h"
+#include "sta_info.h"
 #include "ap_list.h"
 #include "hw_features.h"
 #include "beacon.h"
+#include "drivers/driver.h"
 
 
 struct ieee80211_frame_info {
@@ -68,23 +72,6 @@ enum ieee80211_phytype {
  * in this link will thus be the least recently used entry. */
 
 
-static void ap_list_new_ap(struct hostapd_iface *iface, struct ap_info *ap)
-{
-       wpa_printf(MSG_DEBUG, "New AP detected: " MACSTR, MAC2STR(ap->addr));
-
-       /* TODO: could send a notification message to an external program that
-        * would then determine whether a rogue AP has been detected */
-}
-
-
-static void ap_list_expired_ap(struct hostapd_iface *iface, struct ap_info *ap)
-{
-       wpa_printf(MSG_DEBUG, "AP info expired: " MACSTR, MAC2STR(ap->addr));
-
-       /* TODO: could send a notification message to an external program */
-}
-
-
 static int ap_list_beacon_olbc(struct hostapd_iface *iface, struct ap_info *ap)
 {
        int i;
@@ -107,6 +94,15 @@ static int ap_list_beacon_olbc(struct hostapd_iface *iface, struct ap_info *ap)
 }
 
 
+#ifdef CONFIG_IEEE80211N
+static int ap_list_beacon_olbc_ht(struct hostapd_iface *iface,
+                                 struct ap_info *ap)
+{
+       return !ap->ht_support;
+}
+#endif /* CONFIG_IEEE80211N */
+
+
 struct ap_info * ap_get_ap(struct hostapd_iface *iface, u8 *ap)
 {
        struct ap_info *s;
@@ -265,8 +261,6 @@ static struct ap_info * ap_ap_add(struct hostapd_iface *iface, u8 *addr)
        if (iface->num_ap > iface->conf->ap_table_max_size && ap != ap->prev) {
                wpa_printf(MSG_DEBUG, "Removing the least recently used AP "
                           MACSTR " from AP table", MAC2STR(ap->prev->addr));
-               if (iface->conf->passive_scan_interval > 0)
-                       ap_list_expired_ap(iface, ap->prev);
                ap_free_ap(iface, ap->prev);
        }
 
@@ -282,6 +276,7 @@ void ap_list_process_beacon(struct hostapd_iface *iface,
        struct ap_info *ap;
        int new_ap = 0;
        size_t len;
+       int set_beacon = 0;
 
        if (iface->conf->ap_table_max_size < 1)
                return;
@@ -338,6 +333,11 @@ void ap_list_process_beacon(struct hostapd_iface *iface,
        else if (fi)
                ap->channel = fi->channel;
 
+       if (elems->ht_capabilities)
+               ap->ht_support = 1;
+       else
+               ap->ht_support = 0;
+
        ap->num_beacons++;
        time(&ap->last_beacon);
        if (fi) {
@@ -346,10 +346,7 @@ void ap_list_process_beacon(struct hostapd_iface *iface,
                ap->datarate = fi->datarate;
        }
 
-       if (new_ap) {
-               if (iface->conf->passive_scan_interval > 0)
-                       ap_list_new_ap(iface, ap);
-       } else if (ap != iface->ap_list) {
+       if (!new_ap && ap != iface->ap_list) {
                /* move AP entry into the beginning of the list so that the
                 * oldest entry is always in the end of the list */
                ap_ap_list_del(iface, ap);
@@ -358,12 +355,24 @@ void ap_list_process_beacon(struct hostapd_iface *iface,
 
        if (!iface->olbc &&
            ap_list_beacon_olbc(iface, ap)) {
-               struct hostapd_data *hapd = iface->bss[0];
                iface->olbc = 1;
                wpa_printf(MSG_DEBUG, "OLBC AP detected: " MACSTR " - enable "
                           "protection", MAC2STR(ap->addr));
-               ieee802_11_set_beacons(hapd->iface);
+               set_beacon++;
+       }
+
+#ifdef CONFIG_IEEE80211N
+       if (!iface->olbc_ht && ap_list_beacon_olbc_ht(iface, ap)) {
+               iface->olbc_ht = 1;
+               hostapd_ht_operation_update(iface);
+               wpa_printf(MSG_DEBUG, "OLBC HT AP detected: " MACSTR
+                          " - enable protection", MAC2STR(ap->addr));
+               set_beacon++;
        }
+#endif /* CONFIG_IEEE80211N */
+
+       if (set_beacon)
+               ieee802_11_set_beacons(iface);
 }
 
 
@@ -372,6 +381,7 @@ static void ap_list_timer(void *eloop_ctx, void *timeout_ctx)
        struct hostapd_iface *iface = eloop_ctx;
        time_t now;
        struct ap_info *ap;
+       int set_beacon = 0;
 
        eloop_register_timeout(10, 0, ap_list_timer, iface, NULL);
 
@@ -380,38 +390,46 @@ static void ap_list_timer(void *eloop_ctx, void *timeout_ctx)
 
        time(&now);
 
-       /* FIX: it looks like jkm-Purina ended up in busy loop in this
-        * function. Apparently, something can still cause a loop in the AP
-        * list.. */
-
        while (iface->ap_list) {
                ap = iface->ap_list->prev;
                if (ap->last_beacon + iface->conf->ap_table_expiration_time >=
                    now)
                        break;
 
-               if (iface->conf->passive_scan_interval > 0)
-                       ap_list_expired_ap(iface, ap);
                ap_free_ap(iface, ap);
        }
 
-       if (iface->olbc) {
+       if (iface->olbc || iface->olbc_ht) {
                int olbc = 0;
+               int olbc_ht = 0;
+
                ap = iface->ap_list;
-               while (ap) {
-                       if (ap_list_beacon_olbc(iface, ap)) {
+               while (ap && (olbc == 0 || olbc_ht == 0)) {
+                       if (ap_list_beacon_olbc(iface, ap))
                                olbc = 1;
-                               break;
-                       }
+#ifdef CONFIG_IEEE80211N
+                       if (ap_list_beacon_olbc_ht(iface, ap))
+                               olbc_ht = 1;
+#endif /* CONFIG_IEEE80211N */
                        ap = ap->next;
                }
-               if (!olbc) {
-                       struct hostapd_data *hapd = iface->bss[0];
+               if (!olbc && iface->olbc) {
                        wpa_printf(MSG_DEBUG, "OLBC not detected anymore");
                        iface->olbc = 0;
-                       ieee802_11_set_beacons(hapd->iface);
+                       set_beacon++;
                }
+#ifdef CONFIG_IEEE80211N
+               if (!olbc_ht && iface->olbc_ht) {
+                       wpa_printf(MSG_DEBUG, "OLBC HT not detected anymore");
+                       iface->olbc_ht = 0;
+                       hostapd_ht_operation_update(iface);
+                       set_beacon++;
+               }
+#endif /* CONFIG_IEEE80211N */
        }
+
+       if (set_beacon)
+               ieee802_11_set_beacons(iface);
 }
 
 
@@ -449,8 +467,6 @@ int ap_list_reconfig(struct hostapd_iface *iface,
                    now)
                        break;
 
-               if (iface->conf->passive_scan_interval > 0)
-                       ap_list_expired_ap(iface, iface->ap_list->prev);
                ap_free_ap(iface, iface->ap_list->prev);
        }