/** * wpa_supplicant_get_scan_results - Get scan results * @wpa_s: Pointer to wpa_supplicant data * @info: Information about what was scanned or %NULL if not available * @new_scan: Whether a new scan was performed * Returns: Scan results, %NULL on failure * * This function request the current scan results from the driver and updates * the local BSS list wpa_s->bss. The caller is responsible for freeing the * results with wpa_scan_results_free(). */ struct wpa_scan_results * wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s, struct scan_info *info, int new_scan) { struct wpa_scan_results *scan_res; size_t i; int (*compar)(const void *, const void *) = wpa_scan_result_compar; if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) scan_res = ieee80211_sta_get_scan_results(wpa_s); else scan_res = wpa_drv_get_scan_results2(wpa_s); if (scan_res == NULL) { wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results"); return NULL; } #ifdef CONFIG_WPS if (wpas_wps_in_progress(wpa_s)) { wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Order scan results with WPS " "provisioning rules"); compar = wpa_scan_result_wps_compar; } #endif /* CONFIG_WPS */ qsort(scan_res->res, scan_res->num, sizeof(struct wpa_scan_res *), compar); wpa_bss_update_start(wpa_s); for (i = 0; i < scan_res->num; i++) wpa_bss_update_scan_res(wpa_s, scan_res->res[i]); wpa_bss_update_end(wpa_s, info, new_scan); return scan_res; }
/** * wpa_supplicant_get_scan_results - Get scan results * @wpa_s: Pointer to wpa_supplicant data * @info: Information about what was scanned or %NULL if not available * @new_scan: Whether a new scan was performed * Returns: Scan results, %NULL on failure * * This function request the current scan results from the driver and updates * the local BSS list wpa_s->bss. The caller is responsible for freeing the * results with wpa_scan_results_free(). */ struct wpa_scan_results * wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s, struct scan_info *info, int new_scan) { struct wpa_scan_results *scan_res; size_t i; if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) scan_res = ieee80211_sta_get_scan_results(wpa_s); else scan_res = wpa_drv_get_scan_results2(wpa_s); if (scan_res == NULL) { wpa_printf(MSG_DEBUG, "Failed to get scan results"); return NULL; } qsort(scan_res->res, scan_res->num, sizeof(struct wpa_scan_res *), wpa_scan_result_compar); wpa_bss_update_start(wpa_s); for (i = 0; i < scan_res->num; i++) wpa_bss_update_scan_res(wpa_s, scan_res->res[i]); wpa_bss_update_end(wpa_s, info, new_scan); return scan_res; }
/** * wpa_supplicant_get_scan_results - Get scan results * @wpa_s: Pointer to wpa_supplicant data * @info: Information about what was scanned or %NULL if not available * @new_scan: Whether a new scan was performed * Returns: Scan results, %NULL on failure * * This function request the current scan results from the driver and updates * the local BSS list wpa_s->bss. The caller is responsible for freeing the * results with wpa_scan_results_free(). */ struct wpa_scan_results * wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s, struct scan_info *info, int new_scan) { struct wpa_scan_results *scan_res; size_t i; int (*compar)(const void *, const void *) = wpa_scan_result_compar; scan_res = wpa_drv_get_scan_results2(wpa_s); if (scan_res == NULL) { wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results"); return NULL; } if (scan_res->fetch_time.sec == 0) { /* * Make sure we have a valid timestamp if the driver wrapper * does not set this. */ os_get_time(&scan_res->fetch_time); } filter_scan_res(wpa_s, scan_res); #ifdef CONFIG_WPS if (wpas_wps_in_progress(wpa_s)) { wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Order scan results with WPS " "provisioning rules"); compar = wpa_scan_result_wps_compar; } #endif /* CONFIG_WPS */ qsort(scan_res->res, scan_res->num, sizeof(struct wpa_scan_res *), compar); dump_scan_res(scan_res); wpa_bss_update_start(wpa_s); for (i = 0; i < scan_res->num; i++) wpa_bss_update_scan_res(wpa_s, scan_res->res[i], &scan_res->fetch_time); wpa_bss_update_end(wpa_s, info, new_scan); return scan_res; }
static int wnm_fetch_scan_results(struct wpa_supplicant *wpa_s) { struct wpa_scan_results *scan_res; struct wpa_bss *bss; struct wpa_ssid *ssid = wpa_s->current_ssid; u8 i, found = 0; size_t j; wpa_dbg(wpa_s, MSG_DEBUG, "WNM: Fetch current scan results from the driver for checking transition candidates"); scan_res = wpa_drv_get_scan_results2(wpa_s); if (!scan_res) { wpa_dbg(wpa_s, MSG_DEBUG, "WNM: Failed to get scan results"); return 0; } if (scan_res->fetch_time.sec == 0) os_get_reltime(&scan_res->fetch_time); filter_scan_res(wpa_s, scan_res); for (i = 0; i < wpa_s->wnm_num_neighbor_report; i++) { struct neighbor_report *nei; nei = &wpa_s->wnm_neighbor_report_elements[i]; if (nei->preference_present && nei->preference == 0) continue; for (j = 0; j < scan_res->num; j++) { struct wpa_scan_res *res; const u8 *ssid_ie; res = scan_res->res[j]; if (os_memcmp(nei->bssid, res->bssid, ETH_ALEN) != 0 || res->age > WNM_SCAN_RESULT_AGE * 1000) continue; bss = wpa_s->current_bss; ssid_ie = wpa_scan_get_ie(res, WLAN_EID_SSID); if (bss && ssid_ie && (bss->ssid_len != ssid_ie[1] || os_memcmp(bss->ssid, ssid_ie + 2, bss->ssid_len) != 0)) continue; /* Potential candidate found */ found = 1; scan_snr(res); scan_est_throughput(wpa_s, res); wpa_bss_update_scan_res(wpa_s, res, &scan_res->fetch_time); } } wpa_scan_results_free(scan_res); if (!found) { wpa_dbg(wpa_s, MSG_DEBUG, "WNM: No transition candidate matches existing scan results"); return 0; } bss = compare_scan_neighbor_results(wpa_s, WNM_SCAN_RESULT_AGE, NULL); if (!bss) { wpa_dbg(wpa_s, MSG_DEBUG, "WNM: Comparison of scan results against transition candidates did not find matches"); return 0; } /* Associate to the network */ wnm_bss_tm_connect(wpa_s, bss, ssid, 0); return 1; }