Merge branch 'moonshot' of ssh://moonshot.suchdamage.org:822/srv/git/libeap into...
[libeap.git] / wpa_supplicant / bss.c
index b1d9b67..dc978af 100644 (file)
 #include "common/ieee802_11_defs.h"
 #include "drivers/driver.h"
 #include "wpa_supplicant_i.h"
+#include "config.h"
 #include "notify.h"
 #include "scan.h"
 #include "bss.h"
 
 
-#ifndef WPA_BSS_MAX_COUNT
-#define WPA_BSS_MAX_COUNT 200
-#endif /* WPA_BSS_MAX_COUNT */
-
 /**
  * WPA_BSS_EXPIRATION_PERIOD - Period of expiration run in seconds
  */
@@ -60,6 +57,7 @@
 #define WPA_BSS_RSNIE_CHANGED_FLAG     BIT(5)
 #define WPA_BSS_WPS_CHANGED_FLAG       BIT(6)
 #define WPA_BSS_RATES_CHANGED_FLAG     BIT(7)
+#define WPA_BSS_IES_CHANGED_FLAG       BIT(8)
 
 
 static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
@@ -120,7 +118,7 @@ static void wpa_bss_add(struct wpa_supplicant *wpa_s,
 {
        struct wpa_bss *bss;
 
-       bss = os_zalloc(sizeof(*bss) + res->ie_len);
+       bss = os_zalloc(sizeof(*bss) + res->ie_len + res->beacon_ie_len);
        if (bss == NULL)
                return;
        bss->id = wpa_s->bss_next_id++;
@@ -129,7 +127,8 @@ static void wpa_bss_add(struct wpa_supplicant *wpa_s,
        os_memcpy(bss->ssid, ssid, ssid_len);
        bss->ssid_len = ssid_len;
        bss->ie_len = res->ie_len;
-       os_memcpy(bss + 1, res + 1, res->ie_len);
+       bss->beacon_ie_len = res->beacon_ie_len;
+       os_memcpy(bss + 1, res + 1, res->ie_len + res->beacon_ie_len);
 
        dl_list_add_tail(&wpa_s->bss, &bss->list);
        dl_list_add_tail(&wpa_s->bss_id, &bss->list_id);
@@ -137,7 +136,7 @@ static void wpa_bss_add(struct wpa_supplicant *wpa_s,
        wpa_printf(MSG_DEBUG, "BSS: Add new id %u BSSID " MACSTR " SSID '%s'",
                   bss->id, MAC2STR(bss->bssid), wpa_ssid_txt(ssid, ssid_len));
        wpas_notify_bss_added(wpa_s, bss->bssid, bss->id);
-       if (wpa_s->num_bss > WPA_BSS_MAX_COUNT) {
+       if (wpa_s->num_bss > wpa_s->conf->bss_max_count) {
                /* Remove the oldest entry */
                wpa_bss_remove(wpa_s, dl_list_first(&wpa_s->bss,
                                                    struct wpa_bss, list));
@@ -216,6 +215,11 @@ static u32 wpa_bss_compare_res(const struct wpa_bss *old,
        if (caps_diff & IEEE80211_CAP_IBSS)
                changes |= WPA_BSS_MODE_CHANGED_FLAG;
 
+       if (old->ie_len == new->ie_len &&
+           os_memcmp(old + 1, new + 1, old->ie_len) == 0)
+               return changes;
+       changes |= WPA_BSS_IES_CHANGED_FLAG;
+
        if (!are_ies_equal(old, new, WPA_IE_VENDOR_TYPE))
                changes |= WPA_BSS_WPAIE_CHANGED_FLAG;
 
@@ -257,6 +261,9 @@ static void notify_bss_changes(struct wpa_supplicant *wpa_s, u32 changes,
        if (changes & WPA_BSS_WPS_CHANGED_FLAG)
                wpas_notify_bss_wps_changed(wpa_s, bss->id);
 
+       if (changes & WPA_BSS_IES_CHANGED_FLAG)
+               wpas_notify_bss_ies_changed(wpa_s, bss->id);
+
        if (changes & WPA_BSS_RATES_CHANGED_FLAG)
                wpas_notify_bss_rates_changed(wpa_s, bss->id);
 }
@@ -273,18 +280,23 @@ static void wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
        wpa_bss_copy_res(bss, res);
        /* Move the entry to the end of the list */
        dl_list_del(&bss->list);
-       if (bss->ie_len >= res->ie_len) {
-               os_memcpy(bss + 1, res + 1, res->ie_len);
+       if (bss->ie_len + bss->beacon_ie_len >=
+           res->ie_len + res->beacon_ie_len) {
+               os_memcpy(bss + 1, res + 1, res->ie_len + res->beacon_ie_len);
                bss->ie_len = res->ie_len;
+               bss->beacon_ie_len = res->beacon_ie_len;
        } else {
                struct wpa_bss *nbss;
                struct dl_list *prev = bss->list_id.prev;
                dl_list_del(&bss->list_id);
-               nbss = os_realloc(bss, sizeof(*bss) + res->ie_len);
+               nbss = os_realloc(bss, sizeof(*bss) + res->ie_len +
+                                 res->beacon_ie_len);
                if (nbss) {
                        bss = nbss;
-                       os_memcpy(bss + 1, res + 1, res->ie_len);
+                       os_memcpy(bss + 1, res + 1,
+                                 res->ie_len + res->beacon_ie_len);
                        bss->ie_len = res->ie_len;
+                       bss->beacon_ie_len = res->beacon_ie_len;
                }
                dl_list_add(prev, &bss->list_id);
        }
@@ -313,7 +325,7 @@ void wpa_bss_update_start(struct wpa_supplicant *wpa_s)
 void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s,
                             struct wpa_scan_res *res)
 {
-       const u8 *ssid;
+       const u8 *ssid, *p2p;
        struct wpa_bss *bss;
 
        ssid = wpa_scan_get_ie(res, WLAN_EID_SSID);
@@ -328,6 +340,11 @@ void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s,
                return;
        }
 
+       p2p = wpa_scan_get_vendor_ie(res, P2P_IE_VENDOR_TYPE);
+       if (p2p && ssid[1] == P2P_WILDCARD_SSID_LEN &&
+           os_memcmp(ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) == 0)
+               return; /* Skip P2P listen discovery results here */
+
        /* TODO: add option for ignoring BSSes we are not interested in
         * (to save memory) */
        bss = wpa_bss_get(wpa_s, res->bssid, ssid + 2, ssid[1]);