Beispiel #1
0
static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
                           const char *reason)
{
    if (wpa_s->last_scan_res) {
        unsigned int i;
        for (i = 0; i < wpa_s->last_scan_res_used; i++) {
            if (wpa_s->last_scan_res[i] == bss) {
                os_memmove(&wpa_s->last_scan_res[i],
                           &wpa_s->last_scan_res[i + 1],
                           (wpa_s->last_scan_res_used - i - 1)
                           * sizeof(struct wpa_bss *));
                wpa_s->last_scan_res_used--;
                break;
            }
        }
    }
    wpa_bss_update_pending_connect(wpa_s, bss, NULL);
    dl_list_del(&bss->list);
    dl_list_del(&bss->list_id);
    wpa_s->num_bss--;
    wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Remove id %u BSSID " MACSTR
            " SSID '%s' due to %s", bss->id, MAC2STR(bss->bssid),
            wpa_ssid_txt(bss->ssid, bss->ssid_len), reason);
    wpas_notify_bss_removed(wpa_s, bss->bssid, bss->id);
    wpa_bss_anqp_free(bss->anqp);
    os_free(bss);
}
Beispiel #2
0
static struct wpa_bss *
wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
	       struct wpa_scan_res *res, struct os_reltime *fetch_time)
{
	u32 changes;

	changes = wpa_bss_compare_res(bss, res);
	if (changes & WPA_BSS_FREQ_CHANGED_FLAG)
		wpa_printf(MSG_DEBUG, "BSS: " MACSTR " changed freq %d --> %d",
			   MAC2STR(bss->bssid), bss->freq, res->freq);
	bss->scan_miss_count = 0;
	bss->last_update_idx = wpa_s->bss_update_idx;
	wpa_bss_copy_res(bss, res, fetch_time);
	/* Move the entry to the end of the list */
	dl_list_del(&bss->list);
#ifdef CONFIG_P2P
	if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) &&
	    !wpa_scan_get_vendor_ie(res, P2P_IE_VENDOR_TYPE)) {
		/*
		 * This can happen when non-P2P station interface runs a scan
		 * without P2P IE in the Probe Request frame. P2P GO would reply
		 * to that with a Probe Response that does not include P2P IE.
		 * Do not update the IEs in this BSS entry to avoid such loss of
		 * information that may be needed for P2P operations to
		 * determine group information.
		 */
		wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Do not update scan IEs for "
			MACSTR " since that would remove P2P IE information",
			MAC2STR(bss->bssid));
	} else
#endif /* CONFIG_P2P */
	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 +
				  res->beacon_ie_len);
		if (nbss) {
			unsigned int i;
			for (i = 0; i < wpa_s->last_scan_res_used; i++) {
				if (wpa_s->last_scan_res[i] == bss) {
					wpa_s->last_scan_res[i] = nbss;
					break;
				}
			}
			if (wpa_s->current_bss == bss)
				wpa_s->current_bss = nbss;
			wpa_bss_update_pending_connect(wpa_s, bss, nbss);
			bss = nbss;
			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);
	}
	if (changes & WPA_BSS_IES_CHANGED_FLAG)
		wpa_bss_set_hessid(bss);
	dl_list_add_tail(&wpa_s->bss, &bss->list);

	notify_bss_changes(wpa_s, changes, bss);

	return bss;
}