104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/*
204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * WPA Supplicant - auto scan
304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Copyright (c) 2012, Intel Corporation. All rights reserved.
404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt *
504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * This software may be distributed under the terms of the BSD license.
604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * See README for more details.
704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */
804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "includes.h"
1004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
1104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "common.h"
1204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "config.h"
1304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "wpa_supplicant_i.h"
1404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "bss.h"
1504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "scan.h"
1604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "autoscan.h"
1704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
1804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_AUTOSCAN_EXPONENTIAL
1904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtextern const struct autoscan_ops autoscan_exponential_ops;
2004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_AUTOSCAN_EXPONENTIAL */
2104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
2204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_AUTOSCAN_PERIODIC
2304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtextern const struct autoscan_ops autoscan_periodic_ops;
2404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_AUTOSCAN_PERIODIC */
2504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
2604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic const struct autoscan_ops * autoscan_modules[] = {
2704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_AUTOSCAN_EXPONENTIAL
2804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	&autoscan_exponential_ops,
2904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_AUTOSCAN_EXPONENTIAL */
3004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_AUTOSCAN_PERIODIC
3104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	&autoscan_periodic_ops,
3204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_AUTOSCAN_PERIODIC */
3304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	NULL
3404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt};
3504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
3604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
3704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void request_scan(struct wpa_supplicant *wpa_s)
3804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
39d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_s->scan_req = MANUAL_SCAN_REQ;
4004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
4104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_supplicant_req_sched_scan(wpa_s))
4204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_req_scan(wpa_s, wpa_s->scan_interval, 0);
4304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
4404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
4504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
4604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint autoscan_init(struct wpa_supplicant *wpa_s, int req_scan)
4704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
4804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	const char *name = wpa_s->conf->autoscan;
4904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	const char *params;
5004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	size_t nlen;
5104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int i;
5204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	const struct autoscan_ops *ops = NULL;
5304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
5404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->autoscan && wpa_s->autoscan_priv)
5504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 0;
5604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
5704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (name == NULL)
5804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 0;
5904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
6004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	params = os_strchr(name, ':');
6104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (params == NULL) {
6204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		params = "";
6304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		nlen = os_strlen(name);
6404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else {
6504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		nlen = params - name;
6604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		params++;
6704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
6804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
6904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	for (i = 0; autoscan_modules[i]; i++) {
7004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (os_strncmp(name, autoscan_modules[i]->name, nlen) == 0) {
7104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			ops = autoscan_modules[i];
7204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			break;
7304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
7404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
7504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
7604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ops == NULL) {
7704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_ERROR, "autoscan: Could not find module "
7804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   "matching the parameter '%s'", name);
7904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
8004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
8104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
8204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->autoscan_params = NULL;
8304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
8404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->autoscan_priv = ops->init(wpa_s, params);
8504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->autoscan_priv == NULL)
8604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
8704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->autoscan = ops;
8804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
8904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_printf(MSG_DEBUG, "autoscan: Initialized module '%s' with "
9004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		   "parameters '%s'", ops->name, params);
9104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!req_scan)
9204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 0;
9304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
9404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	/*
9504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	 * Cancelling existing scan requests, if any.
9604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	 */
9704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_supplicant_cancel_sched_scan(wpa_s);
9804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_supplicant_cancel_scan(wpa_s);
9904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
10004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	/*
10104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	 * Firing first scan, which will lead to call autoscan_notify_scan.
10204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	 */
10304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	request_scan(wpa_s);
10404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
10504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
10604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
10704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
10804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
10904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid autoscan_deinit(struct wpa_supplicant *wpa_s)
11004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
11104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->autoscan && wpa_s->autoscan_priv) {
11204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "autoscan: Deinitializing module '%s'",
11304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   wpa_s->autoscan->name);
11404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->autoscan->deinit(wpa_s->autoscan_priv);
11504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->autoscan = NULL;
11604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->autoscan_priv = NULL;
11704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
11804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->scan_interval = 5;
11904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->sched_scan_interval = 0;
12004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
12104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
12204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
12304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
12404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint autoscan_notify_scan(struct wpa_supplicant *wpa_s,
12504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			 struct wpa_scan_results *scan_res)
12604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
12704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int interval;
12804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
12904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->autoscan && wpa_s->autoscan_priv) {
13004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		interval = wpa_s->autoscan->notify_scan(wpa_s->autoscan_priv,
13104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt							scan_res);
13204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
13304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (interval <= 0)
13404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return -1;
13504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
13604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->scan_interval = interval;
13704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->sched_scan_interval = interval;
13804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
13904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		request_scan(wpa_s);
14004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
14104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
14204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
14304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
144