static struct wpa_bss * wpa_bss_add(struct wpa_supplicant *wpa_s, const u8 *ssid, size_t ssid_len, struct wpa_scan_res *res) { struct wpa_bss *bss; bss = os_zalloc(sizeof(*bss) + res->ie_len + res->beacon_ie_len); if (bss == NULL) return NULL; bss->id = wpa_s->bss_next_id++; bss->last_update_idx = wpa_s->bss_update_idx; wpa_bss_copy_res(bss, res); os_memcpy(bss->ssid, ssid, ssid_len); bss->ssid_len = ssid_len; bss->ie_len = res->ie_len; bss->beacon_ie_len = res->beacon_ie_len; os_memcpy(bss + 1, res + 1, res->ie_len + res->beacon_ie_len); wpa_bss_set_hessid(bss); dl_list_add_tail(&wpa_s->bss, &bss->list); dl_list_add_tail(&wpa_s->bss_id, &bss->list_id); wpa_s->num_bss++; wpa_dbg(wpa_s, 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_s->conf->bss_max_count && wpa_bss_remove_oldest(wpa_s) != 0) { wpa_printf(MSG_ERROR, "Increasing the MAX BSS count to %d " "because all BSSes are in use. We should normally " "not get here!", (int) wpa_s->num_bss); wpa_s->conf->bss_max_count = wpa_s->num_bss; } return bss; }
static void wpa_bss_add(struct wpa_supplicant *wpa_s, const u8 *ssid, size_t ssid_len, struct wpa_scan_res *res) { struct wpa_bss *bss; bss = os_zalloc(sizeof(*bss) + res->ie_len + res->beacon_ie_len); if (bss == NULL) return; bss->id = wpa_s->bss_next_id++; bss->last_update_idx = wpa_s->bss_update_idx; wpa_bss_copy_res(bss, res); os_memcpy(bss->ssid, ssid, ssid_len); bss->ssid_len = ssid_len; bss->ie_len = 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); wpa_s->num_bss++; 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_s->conf->bss_max_count) { /* Remove the oldest entry */ wpa_bss_remove(wpa_s, dl_list_first(&wpa_s->bss, struct wpa_bss, list)); }
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; }