xref: /aosp_15_r20/external/wpa_supplicant_8/wpa_supplicant/autoscan.c (revision 03f9172ca588f91df233974f4258bab95191f931)
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