1252190Srpaulo/*
2252190Srpaulo * WPA Supplicant - auto scan exponential module
3252190Srpaulo * Copyright (c) 2012, Intel Corporation. All rights reserved.
4252190Srpaulo *
5252190Srpaulo * This software may be distributed under the terms of the BSD license.
6252190Srpaulo * See README for more details.
7252190Srpaulo */
8252190Srpaulo
9252190Srpaulo#include "includes.h"
10252190Srpaulo
11252190Srpaulo#include "common.h"
12252190Srpaulo#include "wpa_supplicant_i.h"
13252190Srpaulo#include "autoscan.h"
14252190Srpaulo
15252190Srpaulostruct autoscan_exponential_data {
16252190Srpaulo	struct wpa_supplicant *wpa_s;
17252190Srpaulo	int base;
18252190Srpaulo	int limit;
19252190Srpaulo	int interval;
20252190Srpaulo};
21252190Srpaulo
22252190Srpaulo
23252190Srpaulostatic int
24252190Srpauloautoscan_exponential_get_params(struct autoscan_exponential_data *data,
25252190Srpaulo				const char *params)
26252190Srpaulo{
27252190Srpaulo	const char *pos;
28252190Srpaulo
29252190Srpaulo	if (params == NULL)
30252190Srpaulo		return -1;
31252190Srpaulo
32252190Srpaulo	data->base = atoi(params);
33252190Srpaulo
34252190Srpaulo	pos = os_strchr(params, ':');
35252190Srpaulo	if (pos == NULL)
36252190Srpaulo		return -1;
37252190Srpaulo
38252190Srpaulo	pos++;
39252190Srpaulo	data->limit = atoi(pos);
40252190Srpaulo
41252190Srpaulo	return 0;
42252190Srpaulo}
43252190Srpaulo
44252190Srpaulo
45252190Srpaulostatic void * autoscan_exponential_init(struct wpa_supplicant *wpa_s,
46252190Srpaulo					const char *params)
47252190Srpaulo{
48252190Srpaulo	struct autoscan_exponential_data *data;
49252190Srpaulo
50252190Srpaulo	data = os_zalloc(sizeof(struct autoscan_exponential_data));
51252190Srpaulo	if (data == NULL)
52252190Srpaulo		return NULL;
53252190Srpaulo
54252190Srpaulo	if (autoscan_exponential_get_params(data, params) < 0) {
55252190Srpaulo		os_free(data);
56252190Srpaulo		return NULL;
57252190Srpaulo	}
58252190Srpaulo
59252190Srpaulo	wpa_printf(MSG_DEBUG, "autoscan exponential: base exponential is %d "
60252190Srpaulo		   "and limit is %d", data->base, data->limit);
61252190Srpaulo
62252190Srpaulo	data->wpa_s = wpa_s;
63252190Srpaulo
64252190Srpaulo	return data;
65252190Srpaulo}
66252190Srpaulo
67252190Srpaulo
68252190Srpaulostatic void autoscan_exponential_deinit(void *priv)
69252190Srpaulo{
70252190Srpaulo	struct autoscan_exponential_data *data = priv;
71252190Srpaulo
72252190Srpaulo	os_free(data);
73252190Srpaulo}
74252190Srpaulo
75252190Srpaulo
76252190Srpaulostatic int autoscan_exponential_notify_scan(void *priv,
77252190Srpaulo					    struct wpa_scan_results *scan_res)
78252190Srpaulo{
79252190Srpaulo	struct autoscan_exponential_data *data = priv;
80252190Srpaulo
81252190Srpaulo	wpa_printf(MSG_DEBUG, "autoscan exponential: scan result "
82252190Srpaulo		   "notification");
83252190Srpaulo
84252190Srpaulo	if (data->interval >= data->limit)
85252190Srpaulo		return data->limit;
86252190Srpaulo
87252190Srpaulo	if (data->interval <= 0)
88252190Srpaulo		data->interval = data->base;
89252190Srpaulo	else {
90252190Srpaulo		data->interval = data->interval * data->base;
91252190Srpaulo		if (data->interval > data->limit)
92252190Srpaulo			return data->limit;
93252190Srpaulo	}
94252190Srpaulo
95252190Srpaulo	return data->interval;
96252190Srpaulo}
97252190Srpaulo
98252190Srpaulo
99252190Srpauloconst struct autoscan_ops autoscan_exponential_ops = {
100252190Srpaulo	.name = "exponential",
101252190Srpaulo	.init = autoscan_exponential_init,
102252190Srpaulo	.deinit = autoscan_exponential_deinit,
103252190Srpaulo	.notify_scan = autoscan_exponential_notify_scan,
104252190Srpaulo};
105