1*03f9172cSAndroid Build Coastguard Worker /*
2*03f9172cSAndroid Build Coastguard Worker * WPA Supplicant - auto scan
3*03f9172cSAndroid Build Coastguard Worker * Copyright (c) 2012, Intel Corporation. All rights reserved.
4*03f9172cSAndroid Build Coastguard Worker * Copyright 2015 Intel Deutschland GmbH
5*03f9172cSAndroid Build Coastguard Worker *
6*03f9172cSAndroid Build Coastguard Worker * This software may be distributed under the terms of the BSD license.
7*03f9172cSAndroid Build Coastguard Worker * See README for more details.
8*03f9172cSAndroid Build Coastguard Worker */
9*03f9172cSAndroid Build Coastguard Worker
10*03f9172cSAndroid Build Coastguard Worker #include "includes.h"
11*03f9172cSAndroid Build Coastguard Worker
12*03f9172cSAndroid Build Coastguard Worker #include "common.h"
13*03f9172cSAndroid Build Coastguard Worker #include "config.h"
14*03f9172cSAndroid Build Coastguard Worker #include "wpa_supplicant_i.h"
15*03f9172cSAndroid Build Coastguard Worker #include "bss.h"
16*03f9172cSAndroid Build Coastguard Worker #include "scan.h"
17*03f9172cSAndroid Build Coastguard Worker #include "autoscan.h"
18*03f9172cSAndroid Build Coastguard Worker
19*03f9172cSAndroid Build Coastguard Worker
20*03f9172cSAndroid Build Coastguard Worker static const struct autoscan_ops * autoscan_modules[] = {
21*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_AUTOSCAN_EXPONENTIAL
22*03f9172cSAndroid Build Coastguard Worker &autoscan_exponential_ops,
23*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_AUTOSCAN_EXPONENTIAL */
24*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_AUTOSCAN_PERIODIC
25*03f9172cSAndroid Build Coastguard Worker &autoscan_periodic_ops,
26*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_AUTOSCAN_PERIODIC */
27*03f9172cSAndroid Build Coastguard Worker NULL
28*03f9172cSAndroid Build Coastguard Worker };
29*03f9172cSAndroid Build Coastguard Worker
30*03f9172cSAndroid Build Coastguard Worker
request_scan(struct wpa_supplicant * wpa_s)31*03f9172cSAndroid Build Coastguard Worker static void request_scan(struct wpa_supplicant *wpa_s)
32*03f9172cSAndroid Build Coastguard Worker {
33*03f9172cSAndroid Build Coastguard Worker wpa_s->scan_req = MANUAL_SCAN_REQ;
34*03f9172cSAndroid Build Coastguard Worker
35*03f9172cSAndroid Build Coastguard Worker if (wpa_supplicant_req_sched_scan(wpa_s))
36*03f9172cSAndroid Build Coastguard Worker wpa_supplicant_req_scan(wpa_s, wpa_s->scan_interval, 0);
37*03f9172cSAndroid Build Coastguard Worker }
38*03f9172cSAndroid Build Coastguard Worker
39*03f9172cSAndroid Build Coastguard Worker
autoscan_init(struct wpa_supplicant * wpa_s,int req_scan)40*03f9172cSAndroid Build Coastguard Worker int autoscan_init(struct wpa_supplicant *wpa_s, int req_scan)
41*03f9172cSAndroid Build Coastguard Worker {
42*03f9172cSAndroid Build Coastguard Worker const char *name = wpa_s->conf->autoscan;
43*03f9172cSAndroid Build Coastguard Worker const char *params;
44*03f9172cSAndroid Build Coastguard Worker size_t nlen;
45*03f9172cSAndroid Build Coastguard Worker int i;
46*03f9172cSAndroid Build Coastguard Worker const struct autoscan_ops *ops = NULL;
47*03f9172cSAndroid Build Coastguard Worker struct sched_scan_plan *scan_plans;
48*03f9172cSAndroid Build Coastguard Worker
49*03f9172cSAndroid Build Coastguard Worker /* Give preference to scheduled scan plans if supported/configured */
50*03f9172cSAndroid Build Coastguard Worker if (wpa_s->sched_scan_plans) {
51*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_DEBUG,
52*03f9172cSAndroid Build Coastguard Worker "autoscan: sched_scan_plans set - use it instead");
53*03f9172cSAndroid Build Coastguard Worker return 0;
54*03f9172cSAndroid Build Coastguard Worker }
55*03f9172cSAndroid Build Coastguard Worker
56*03f9172cSAndroid Build Coastguard Worker if (wpa_s->autoscan && wpa_s->autoscan_priv) {
57*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_DEBUG, "autoscan: Already initialized");
58*03f9172cSAndroid Build Coastguard Worker return 0;
59*03f9172cSAndroid Build Coastguard Worker }
60*03f9172cSAndroid Build Coastguard Worker
61*03f9172cSAndroid Build Coastguard Worker if (name == NULL)
62*03f9172cSAndroid Build Coastguard Worker return 0;
63*03f9172cSAndroid Build Coastguard Worker
64*03f9172cSAndroid Build Coastguard Worker params = os_strchr(name, ':');
65*03f9172cSAndroid Build Coastguard Worker if (params == NULL) {
66*03f9172cSAndroid Build Coastguard Worker params = "";
67*03f9172cSAndroid Build Coastguard Worker nlen = os_strlen(name);
68*03f9172cSAndroid Build Coastguard Worker } else {
69*03f9172cSAndroid Build Coastguard Worker nlen = params - name;
70*03f9172cSAndroid Build Coastguard Worker params++;
71*03f9172cSAndroid Build Coastguard Worker }
72*03f9172cSAndroid Build Coastguard Worker
73*03f9172cSAndroid Build Coastguard Worker for (i = 0; autoscan_modules[i]; i++) {
74*03f9172cSAndroid Build Coastguard Worker if (os_strncmp(name, autoscan_modules[i]->name, nlen) == 0) {
75*03f9172cSAndroid Build Coastguard Worker ops = autoscan_modules[i];
76*03f9172cSAndroid Build Coastguard Worker break;
77*03f9172cSAndroid Build Coastguard Worker }
78*03f9172cSAndroid Build Coastguard Worker }
79*03f9172cSAndroid Build Coastguard Worker
80*03f9172cSAndroid Build Coastguard Worker if (ops == NULL) {
81*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_ERROR, "autoscan: Could not find module "
82*03f9172cSAndroid Build Coastguard Worker "matching the parameter '%s'", name);
83*03f9172cSAndroid Build Coastguard Worker return -1;
84*03f9172cSAndroid Build Coastguard Worker }
85*03f9172cSAndroid Build Coastguard Worker
86*03f9172cSAndroid Build Coastguard Worker scan_plans = os_malloc(sizeof(*wpa_s->sched_scan_plans));
87*03f9172cSAndroid Build Coastguard Worker if (!scan_plans)
88*03f9172cSAndroid Build Coastguard Worker return -1;
89*03f9172cSAndroid Build Coastguard Worker
90*03f9172cSAndroid Build Coastguard Worker wpa_s->autoscan_params = NULL;
91*03f9172cSAndroid Build Coastguard Worker
92*03f9172cSAndroid Build Coastguard Worker wpa_s->autoscan_priv = ops->init(wpa_s, params);
93*03f9172cSAndroid Build Coastguard Worker if (!wpa_s->autoscan_priv) {
94*03f9172cSAndroid Build Coastguard Worker os_free(scan_plans);
95*03f9172cSAndroid Build Coastguard Worker return -1;
96*03f9172cSAndroid Build Coastguard Worker }
97*03f9172cSAndroid Build Coastguard Worker
98*03f9172cSAndroid Build Coastguard Worker scan_plans[0].interval = 5;
99*03f9172cSAndroid Build Coastguard Worker scan_plans[0].iterations = 0;
100*03f9172cSAndroid Build Coastguard Worker os_free(wpa_s->sched_scan_plans);
101*03f9172cSAndroid Build Coastguard Worker wpa_s->sched_scan_plans = scan_plans;
102*03f9172cSAndroid Build Coastguard Worker wpa_s->sched_scan_plans_num = 1;
103*03f9172cSAndroid Build Coastguard Worker wpa_s->autoscan = ops;
104*03f9172cSAndroid Build Coastguard Worker
105*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_DEBUG, "autoscan: Initialized module '%s' with "
106*03f9172cSAndroid Build Coastguard Worker "parameters '%s'", ops->name, params);
107*03f9172cSAndroid Build Coastguard Worker if (!req_scan)
108*03f9172cSAndroid Build Coastguard Worker return 0;
109*03f9172cSAndroid Build Coastguard Worker
110*03f9172cSAndroid Build Coastguard Worker /*
111*03f9172cSAndroid Build Coastguard Worker * Cancelling existing scan requests, if any.
112*03f9172cSAndroid Build Coastguard Worker */
113*03f9172cSAndroid Build Coastguard Worker wpa_supplicant_cancel_sched_scan(wpa_s);
114*03f9172cSAndroid Build Coastguard Worker wpa_supplicant_cancel_scan(wpa_s);
115*03f9172cSAndroid Build Coastguard Worker
116*03f9172cSAndroid Build Coastguard Worker /*
117*03f9172cSAndroid Build Coastguard Worker * Firing first scan, which will lead to call autoscan_notify_scan.
118*03f9172cSAndroid Build Coastguard Worker */
119*03f9172cSAndroid Build Coastguard Worker request_scan(wpa_s);
120*03f9172cSAndroid Build Coastguard Worker
121*03f9172cSAndroid Build Coastguard Worker return 0;
122*03f9172cSAndroid Build Coastguard Worker }
123*03f9172cSAndroid Build Coastguard Worker
124*03f9172cSAndroid Build Coastguard Worker
autoscan_deinit(struct wpa_supplicant * wpa_s)125*03f9172cSAndroid Build Coastguard Worker void autoscan_deinit(struct wpa_supplicant *wpa_s)
126*03f9172cSAndroid Build Coastguard Worker {
127*03f9172cSAndroid Build Coastguard Worker if (wpa_s->autoscan && wpa_s->autoscan_priv) {
128*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_DEBUG, "autoscan: Deinitializing module '%s'",
129*03f9172cSAndroid Build Coastguard Worker wpa_s->autoscan->name);
130*03f9172cSAndroid Build Coastguard Worker wpa_s->autoscan->deinit(wpa_s->autoscan_priv);
131*03f9172cSAndroid Build Coastguard Worker wpa_s->autoscan = NULL;
132*03f9172cSAndroid Build Coastguard Worker wpa_s->autoscan_priv = NULL;
133*03f9172cSAndroid Build Coastguard Worker
134*03f9172cSAndroid Build Coastguard Worker wpa_s->scan_interval = 5;
135*03f9172cSAndroid Build Coastguard Worker
136*03f9172cSAndroid Build Coastguard Worker os_free(wpa_s->sched_scan_plans);
137*03f9172cSAndroid Build Coastguard Worker wpa_s->sched_scan_plans = NULL;
138*03f9172cSAndroid Build Coastguard Worker wpa_s->sched_scan_plans_num = 0;
139*03f9172cSAndroid Build Coastguard Worker }
140*03f9172cSAndroid Build Coastguard Worker }
141*03f9172cSAndroid Build Coastguard Worker
142*03f9172cSAndroid Build Coastguard Worker
autoscan_notify_scan(struct wpa_supplicant * wpa_s,struct wpa_scan_results * scan_res)143*03f9172cSAndroid Build Coastguard Worker int autoscan_notify_scan(struct wpa_supplicant *wpa_s,
144*03f9172cSAndroid Build Coastguard Worker struct wpa_scan_results *scan_res)
145*03f9172cSAndroid Build Coastguard Worker {
146*03f9172cSAndroid Build Coastguard Worker int interval;
147*03f9172cSAndroid Build Coastguard Worker
148*03f9172cSAndroid Build Coastguard Worker if (wpa_s->autoscan && wpa_s->autoscan_priv) {
149*03f9172cSAndroid Build Coastguard Worker interval = wpa_s->autoscan->notify_scan(wpa_s->autoscan_priv,
150*03f9172cSAndroid Build Coastguard Worker scan_res);
151*03f9172cSAndroid Build Coastguard Worker
152*03f9172cSAndroid Build Coastguard Worker if (interval <= 0)
153*03f9172cSAndroid Build Coastguard Worker return -1;
154*03f9172cSAndroid Build Coastguard Worker
155*03f9172cSAndroid Build Coastguard Worker wpa_s->scan_interval = interval;
156*03f9172cSAndroid Build Coastguard Worker wpa_s->sched_scan_plans[0].interval = interval;
157*03f9172cSAndroid Build Coastguard Worker
158*03f9172cSAndroid Build Coastguard Worker request_scan(wpa_s);
159*03f9172cSAndroid Build Coastguard Worker }
160*03f9172cSAndroid Build Coastguard Worker
161*03f9172cSAndroid Build Coastguard Worker return 0;
162*03f9172cSAndroid Build Coastguard Worker }
163