Пример #1
0
/**
 * 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_reltime(&scan_res->fetch_time);
	}
	filter_scan_res(wpa_s, scan_res);

#ifdef CONFIG_WPS
	if (wpas_wps_searching(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;
}
Пример #2
0
static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s)
{
	int prio, timeout;
	struct wpa_scan_res *selected = NULL;
	struct wpa_ssid *ssid = NULL;

	wpa_supplicant_notify_scanning(wpa_s, 0);

	if (wpa_supplicant_get_scan_results(wpa_s) < 0) {
		if (wpa_s->conf->ap_scan == 2)
			return;
		wpa_printf(MSG_DEBUG, "Failed to get scan results - try "
			   "scanning again");
		timeout = 1;
		goto req_scan;
	}

	/*
	 * Don't post the results if this was the initial cached
	 * and there were no results.
	 */
	if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1 &&
	    wpa_s->scan_res->num == 0) {
		wpa_msg(wpa_s, MSG_DEBUG, "Cached scan results are "
			"empty - not posting");
	} else {
		wpa_printf(MSG_DEBUG, "New scan results available");
		wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
		wpa_supplicant_dbus_notify_scan_results(wpa_s);
		wpas_wps_notify_scan_results(wpa_s);
	}

	if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s)))
		return;

	if (wpa_s->disconnected) {
		wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
		return;
	}

	while (selected == NULL) {
		for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
			selected = wpa_supplicant_select_bss(
				wpa_s, wpa_s->conf->pssid[prio], &ssid);
			if (selected)
				break;
		}

		if (selected == NULL && wpa_s->blacklist) {
			wpa_printf(MSG_DEBUG, "No APs found - clear blacklist "
				   "and try again");
			wpa_blacklist_clear(wpa_s);
			wpa_s->blacklist_cleared++;
		} else if (selected == NULL) {
			break;
		}
	}

	if (selected) {
		if (wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) {
			wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP
				"PBC session overlap");
			timeout = 10;
			goto req_scan;
		}

		/* Do not trigger new association unless the BSSID has changed
		 * or if reassociation is requested. If we are in process of
		 * associating with the selected BSSID, do not trigger new
		 * attempt. */
		if (wpa_s->reassociate ||
		    (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 &&
		     (wpa_s->wpa_state != WPA_ASSOCIATING ||
		      os_memcmp(selected->bssid, wpa_s->pending_bssid,
				ETH_ALEN) != 0))) {
			if (wpa_supplicant_scard_init(wpa_s, ssid)) {
				wpa_supplicant_req_scan(wpa_s, 10, 0);
				return;
			}
			wpa_supplicant_associate(wpa_s, selected, ssid);
		} else {
			wpa_printf(MSG_DEBUG, "Already associated with the "
				   "selected AP.");
		}
		rsn_preauth_scan_results(wpa_s->wpa, wpa_s->scan_res);
	} else {
		wpa_printf(MSG_DEBUG, "No suitable AP found.");
		timeout = 5;
		goto req_scan;
	}

	return;

req_scan:
	if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1) {
		/*
		 * Quick recovery if the initial scan results were not
		 * complete when fetched before the first scan request.
		 */
		wpa_s->scan_res_tried++;
		timeout = 0;
	} else if (!wpa_supplicant_enabled_networks(wpa_s->conf)) {
		/*
		 * No networks are enabled; short-circuit request so
		 * we don't wait timeout seconds before transitioning
		 * to INACTIVE state.
		 */
		wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
		return;
	}
	wpa_supplicant_req_scan(wpa_s, timeout, 0);
}
Пример #3
0
static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
					      union wpa_event_data *data)
{
	struct wpa_bss *selected;
	struct wpa_ssid *ssid = NULL;
	struct wpa_scan_results *scan_res;
	int ap = 0;

#ifdef CONFIG_AP
	if (wpa_s->ap_iface)
		ap = 1;
#endif /* CONFIG_AP */

	wpa_supplicant_notify_scanning(wpa_s, 0);

	scan_res = wpa_supplicant_get_scan_results(wpa_s,
						   data ? &data->scan_info :
						   NULL, 1);
	if (scan_res == NULL) {
		if (wpa_s->conf->ap_scan == 2 || ap)
			return;
		wpa_printf(MSG_DEBUG, "Failed to get scan results - try "
			   "scanning again");
		wpa_supplicant_req_new_scan(wpa_s, 1, 0);
		return;
	}

	if (wpa_s->scan_res_handler) {
		wpa_s->scan_res_handler(wpa_s, scan_res);
		wpa_s->scan_res_handler = NULL;
		wpa_scan_results_free(scan_res);
		return;
	}

	if (ap) {
		wpa_printf(MSG_DEBUG, "Ignore scan results in AP mode");
		wpa_scan_results_free(scan_res);
		return;
	}

	wpa_printf(MSG_DEBUG, "New scan results available");
	wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
	wpas_notify_scan_results(wpa_s);

	wpas_notify_scan_done(wpa_s, 1);

	if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s))) {
		wpa_scan_results_free(scan_res);
		return;
	}

	if (wpa_s->disconnected) {
		wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
		wpa_scan_results_free(scan_res);
		return;
	}

	wpa_supplicant_rsn_preauth_scan_results(wpa_s, scan_res);

	selected = wpa_supplicant_pick_network(wpa_s, scan_res, &ssid);

	if (selected) {
		int skip;
		skip = !wpa_supplicant_need_to_roam(wpa_s, selected, ssid,
						    scan_res);
		wpa_scan_results_free(scan_res);
		if (skip)
			return;
		wpa_supplicant_connect(wpa_s, selected, ssid);
	} else {
		wpa_scan_results_free(scan_res);
		wpa_printf(MSG_DEBUG, "No suitable network found");
		ssid = wpa_supplicant_pick_new_network(wpa_s);
		if (ssid) {
			wpa_printf(MSG_DEBUG, "Setup a new network");
			wpa_supplicant_associate(wpa_s, NULL, ssid);
		} else {
			int timeout_sec = 5;
			int timeout_usec = 0;
#ifdef CONFIG_P2P
			if (wpa_s->p2p_in_provisioning) {
				/*
				 * Use shorter wait during P2P Provisioning
				 * state to speed up group formation.
				 */
				timeout_sec = 0;
				timeout_usec = 250000;
			}
#endif /* CONFIG_P2P */
			wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
						    timeout_usec);
		}
	}
}
Пример #4
0
static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
					      union wpa_event_data *data)
{
	//struct wpa_bss *selected;
	//struct wpa_ssid *ssid = NULL;
	struct wpa_scan_results *scan_res;

	wpa_supplicant_notify_scanning(wpa_s, 0);
                
	scan_res = wpa_supplicant_get_scan_results(wpa_s,
						   data ? &data->scan_info :
						   NULL, 1);
        
        ros_scan_completed(wpa_s, scan_res);

	if (scan_res == NULL) {
		if (wpa_s->conf->ap_scan == 2)
			return;
		wpa_printf(MSG_DEBUG, "Failed to get scan results - don't bother try "
			   "scanning again");
		//wpa_supplicant_req_new_scan(wpa_s, 1, 0);
		return;
	}

	if (wpa_s->scan_res_handler) {
		wpa_s->scan_res_handler(wpa_s, scan_res);
		wpa_s->scan_res_handler = NULL;
		wpa_scan_results_free(scan_res);
		return;
	}

	/*
	 * Don't post the results if this was the initial cached
	 * and there were no results.
	 */
	if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1 &&
	    scan_res->num == 0) {
		wpa_msg(wpa_s, MSG_DEBUG, "Cached scan results are "
			"empty - not posting");
	} else {
		wpa_printf(MSG_DEBUG, "New scan results available");
		wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
		wpas_notify_scan_results(wpa_s);
	}

	wpas_notify_scan_done(wpa_s, 1);

	if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s))) {
		wpa_scan_results_free(scan_res);
		return;
	}

	if (wpa_s->disconnected) {
		wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
		wpa_scan_results_free(scan_res);
		return;
	}

	if (bgscan_notify_scan(wpa_s) == 1) {
		wpa_scan_results_free(scan_res);
		return;
	}

	wpa_supplicant_rsn_preauth_scan_results(wpa_s, scan_res);

	/*selected = wpa_supplicant_pick_network(wpa_s, scan_res, &ssid);

	if (selected) {
		int skip;
                wpa_s->more_bss_to_try = 1;
		skip = !wpa_supplicant_need_to_roam(wpa_s, selected, ssid,
						    scan_res);
		wpa_scan_results_free(scan_res);
		if (skip)
			return;
		wpa_supplicant_connect(wpa_s, selected, ssid);
	} else {
                wpa_s->more_bss_to_try = 0;
		wpa_scan_results_free(scan_res);
		wpa_printf(MSG_DEBUG, "No suitable network found");
		ssid = wpa_supplicant_pick_new_network(wpa_s);
		if (ssid) {
			wpa_printf(MSG_DEBUG, "Setup a new network");
			wpa_supplicant_associate(wpa_s, NULL, ssid);
		} else {
			int timeout_sec = 1;
			int timeout_usec = 0;
			wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
						    timeout_usec);
		}
	} */
}