/** * wpa_bss_update_end - End a BSS table update from scan results * @wpa_s: Pointer to wpa_supplicant data * @info: Information about scan parameters * @new_scan: Whether this update round was based on a new scan * * This function is called at the end of each BSS table update round for new * scan results. The start of the update was indicated with a call to * wpa_bss_update_start(). */ void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info, int new_scan) { struct wpa_bss *bss, *n; os_get_reltime(&wpa_s->last_scan); if (!new_scan) return; /* do not expire entries without new scan */ dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) { if (wpa_bss_in_use(wpa_s, bss)) continue; if (!wpa_bss_included_in_scan(bss, info)) continue; /* expire only BSSes that were scanned */ if (bss->last_update_idx < wpa_s->bss_update_idx) bss->scan_miss_count++; if (bss->scan_miss_count >= wpa_s->conf->bss_expiration_scan_count) { wpa_bss_remove(wpa_s, bss, "no match in scan"); } } wpa_printf(MSG_DEBUG, "BSS: last_scan_res_used=%u/%u", wpa_s->last_scan_res_used, wpa_s->last_scan_res_size); }
static int wpa_bss_remove_oldest_unknown(struct wpa_supplicant *wpa_s) { struct wpa_bss *bss; dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { if (!wpa_bss_known(wpa_s, bss)) { wpa_bss_remove(wpa_s, bss, __func__); return 0; } } return -1; }
/** * wpa_bss_flush - Flush all unused BSS entries * @wpa_s: Pointer to wpa_supplicant data */ void wpa_bss_flush(struct wpa_supplicant *wpa_s) { struct wpa_bss *bss, *n; wpa_s->clear_driver_scan_cache = 1; if (wpa_s->bss.next == NULL) return; /* BSS table not yet initialized */ dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) { if (wpa_bss_in_use(wpa_s, bss)) continue; wpa_bss_remove(wpa_s, bss, __func__); } }
/** * wpa_bss_flush_by_age - Flush old BSS entries * @wpa_s: Pointer to wpa_supplicant data * @age: Maximum entry age in seconds * * Remove BSS entries that have not been updated during the last @age seconds. */ void wpa_bss_flush_by_age(struct wpa_supplicant *wpa_s, int age) { struct wpa_bss *bss, *n; struct os_reltime t; if (dl_list_empty(&wpa_s->bss)) return; os_get_reltime(&t); t.sec -= age; dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) { if (wpa_bss_in_use(wpa_s, bss)) continue; if (os_reltime_before(&bss->last_update, &t)) { wpa_bss_remove(wpa_s, bss, __func__); } else break; } }
static int wpa_bss_remove_oldest(struct wpa_supplicant *wpa_s) { struct wpa_bss *bss; /* * Remove the oldest entry that does not match with any configured * network. */ if (wpa_bss_remove_oldest_unknown(wpa_s) == 0) return 0; /* * Remove the oldest entry that isn't currently in use. */ dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { if (!wpa_bss_in_use(wpa_s, bss)) { wpa_bss_remove(wpa_s, bss, __func__); return 0; } } return -1; }