• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * WPA Supplicant / main() function for UNIX like OSes and MinGW
3  * Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "common.h"
10 #include "wpa_supplicant_i.h"
11 #include "wpa_supplicant_if.h"
12 #include "wifi_api.h"
13 #include "eloop.h"
14 #ifdef CONFIG_P2P
15 #include "p2p_supplicant.h"
16 #endif /* CONFIG_P2P */
17 #include "securec.h"
18 #ifdef LOS_INLINE_FUNC_CROP
19 #include "drivers/driver.h"
20 #endif /* LOS_INLINE_FUNC_CROP */
21 #ifdef CONFIG_WAPI
22 #include "wapi_api.h"
23 #endif /* CONFIG_WAPI */
24 
25 unsigned int g_wpa_event;
26 unsigned int g_softap_event;
27 #ifdef LOS_CONFIG_P2P
28 unsigned int g_p2p_event;
29 #endif /* LOS_CONFIG_P2P */
30 #ifdef CONFIG_DRIVER_SOC
31 static struct wpa_global *g_wpa_global = NULL;
32 static struct wpa_interface *g_wpa_iface = NULL;
33 #endif /* CONFIG_DRIVER_SOC */
34 
wpa_supplicant_get_wpa_global(void)35 struct wpa_global * wpa_supplicant_get_wpa_global(void)
36 {
37 	return g_wpa_global;
38 }
39 
wpa_supplicant_global_deinit()40 void wpa_supplicant_global_deinit()
41 {
42 	os_free(g_wpa_iface);
43 	g_wpa_iface = NULL;
44 	g_wpa_global = NULL;
45 	wpa_error_log0(MSG_ERROR, "wpa_supplicant_exit\n");
46 }
47 
wpa_supplicant_main_init(const char * ifname,struct ext_wifi_dev ** wifi_dev,struct wpa_global ** global)48 static int wpa_supplicant_main_init(const char *ifname, struct ext_wifi_dev **wifi_dev, struct wpa_global **global)
49 {
50 	if (ifname == NULL) {
51 		wpa_error_log0(MSG_ERROR, "wpa_supplicant_main: ifname is null \n");
52 		(void)os_event_write(g_wpa_event, WPA_EVENT_WPA_START_ERROR);
53 		return EXT_WIFI_FAIL;
54 	}
55 	wpa_debug_level = MSG_DEBUG;
56 	wpa_printf(MSG_DEBUG, "wpa_supplicant_main: ifname = %s", ifname);
57 	*wifi_dev = los_get_wifi_dev_by_name(ifname);
58 	if (*wifi_dev == NULL) {
59 		wpa_error_log0(MSG_ERROR, "wpa_supplicant_main: los_get_wifi_dev_by_name failed \n");
60 		(void)os_event_write(g_wpa_event, WPA_EVENT_WPA_START_ERROR);
61 		return EXT_WIFI_FAIL;
62 	}
63 	*global = wpa_supplicant_init();
64 	if (*global == NULL) {
65 		(void)os_event_write(g_wpa_event, WPA_EVENT_WPA_START_ERROR);
66 		return EXT_WIFI_FAIL;
67 	}
68 	return EXT_WIFI_OK;
69 }
70 
wpa_supplicant_main(const char * ifname)71 void wpa_supplicant_main(const char *ifname)
72 {
73 	struct wpa_interface *ifaces     = NULL;
74 	struct wpa_interface *iface      = NULL;
75 	struct wpa_global *global        = NULL;
76 	struct ext_wifi_dev *wifi_dev    = NULL;
77 	char driver[MAX_DRIVER_NAME_LEN] = {"soc"};
78 	int iface_count;
79 	int exitcode = EXT_WIFI_OK;
80 	int ret;
81 	wpa_error_log0(MSG_ERROR, "---> wpa_supplicant_main enter.");
82 
83 	ret = wpa_supplicant_main_init(ifname, &wifi_dev, &global);
84 	if (ret != EXT_WIFI_OK)
85 		return;
86 
87 	ifaces = os_zalloc(sizeof(struct wpa_interface));
88 	if (ifaces == NULL)
89 		goto OUT;
90 	iface = ifaces;
91 	iface_count = 1;
92 	iface->ifname = ifname;
93 	iface->driver = driver;
94 
95 #ifdef CONFIG_DRIVER_SOC
96 	g_wpa_global = global;
97 	g_wpa_iface = ifaces;
98 #endif /* CONFIG_DRIVER_SOC */
99 
100 	for (int i = 0; (exitcode == EXT_WIFI_OK) && (i < iface_count); i++) {
101 		struct wpa_supplicant *wpa_s = wpa_supplicant_add_iface(global, &ifaces[i], NULL);
102 		if (wpa_s == NULL) {
103 			exitcode = EXT_WIFI_FAIL;
104 			break;
105 		}
106 		unsigned int int_save;
107 		os_task_lock(&int_save);
108 		wifi_dev->priv = wpa_s;
109 		os_task_unlock(int_save);
110 		wpa_error_buf(MSG_ERROR, "wpa_supplicant_main: wifi_dev: ifname = %s\n", wifi_dev->ifname, strlen(wifi_dev->ifname));
111 	}
112 	if (wifi_dev->iftype == EXT_WIFI_IFTYPE_STATION) {
113 		g_connecting_ssid = NULL;
114 
115 #ifdef CONFIG_WAPI
116 		if (wapi_init_iface((struct wpa_supplicant *)(wifi_dev->priv))) {
117 			wpa_error_buf(MSG_ERROR, "wpa_supplicant_main: wifi_dev: ifname = %s\n",
118 				wifi_dev->ifname, strlen(wifi_dev->ifname));
119 			exitcode = EXT_WIFI_FAIL;
120 		}
121 #endif /* CONFIG_WAPI */
122 	}
123 
124 	if (exitcode == EXT_WIFI_OK) {
125 		exitcode = wpa_supplicant_run(global);
126 		if (exitcode != EXT_WIFI_FAIL) {
127 			(void)os_event_write(g_wpa_event, WPA_EVENT_WPA_START_OK);
128 			return;
129 		}
130 	}
131 
132 OUT:
133 	wpa_supplicant_deinit(global);
134 #ifdef CONFIG_DRIVER_SOC
135 	g_wpa_global = NULL;
136 	g_wpa_iface = NULL;
137 #endif
138 	unsigned int int_save;
139 	os_task_lock(&int_save);
140 	if (wifi_dev != NULL)
141 		wifi_dev->priv = NULL;
142 	os_task_unlock(int_save);
143 
144 	os_free(ifaces);
145 	// send sta start failed event
146 	(void)os_event_write(g_wpa_event, WPA_EVENT_WPA_START_ERROR);
147 	return;
148 }
149 
150 
wpa_check_reconnect_timeout_match(const struct wpa_supplicant * wpa_s)151  int wpa_check_reconnect_timeout_match(const struct wpa_supplicant *wpa_s)
152 {
153 	int ret;
154 	if ((wpa_s == NULL) || (wpa_is_sta(wpa_s) == WPA_FLAG_OFF))
155 		return 0;
156 	if ((g_reconnect_set.enable == WPA_FLAG_OFF) ||
157 	    (g_reconnect_set.pending_flag == WPA_FLAG_ON)) {
158 		return 0;
159 	}
160 	ret = ((wpa_s->wpa_state >= WPA_ASSOCIATING) && (wpa_s->wpa_state != WPA_COMPLETED)) ||
161 	       ((wpa_s->wpa_state == WPA_COMPLETED) && (wpa_s->current_ssid != NULL) &&
162 	       (g_reconnect_set.current_ssid == wpa_s->current_ssid));
163 	return ret;
164 }
165 
wpa_supplicant_reconnect_restart(void * eloop_ctx,void * timeout_ctx)166 void wpa_supplicant_reconnect_restart(void *eloop_ctx, void *timeout_ctx)
167 {
168 	(void)timeout_ctx;
169 	struct wpa_supplicant *wpa_s = eloop_ctx;
170 	if ((wpa_s == NULL) || (wpa_is_sta(wpa_s) == WPA_FLAG_OFF)) {
171 		wpa_error_log0(MSG_ERROR, "wpa_supplicant_reconnect_restart input NULL ptr!");
172 		return;
173 	}
174 	if ((g_reconnect_set.enable == WPA_FLAG_OFF) || (g_connecting_ssid == NULL)) {
175 		wpa_error_log0(MSG_ERROR, "reconnect policy disabled!");
176 		return;
177 	}
178 	if (wpa_s->wpa_state < WPA_AUTHENTICATING) {
179 		g_reconnect_set.pending_flag = WPA_FLAG_ON;
180 		g_connecting_flag = WPA_FLAG_ON;
181 		wpa_supplicant_select_network(wpa_s, g_connecting_ssid);
182 		wpa_error_log0(MSG_ERROR, "wpa_supplicant_reconnect_restart!");
183 	}
184 
185 	if (g_reconnect_set.timeout > 0)
186 		(void)eloop_register_timeout(g_reconnect_set.timeout, 0, wpa_supplicant_reconnect_timeout, wpa_s, NULL);
187 }
188 
wpa_supplicant_reconnect_timeout(void * eloop_ctx,void * timeout_ctx)189 void wpa_supplicant_reconnect_timeout(void *eloop_ctx, void *timeout_ctx)
190 {
191 	(void)timeout_ctx;
192 	struct wpa_supplicant *wpa_s = eloop_ctx;
193 	if ((wpa_s == NULL) || (wpa_is_sta(wpa_s) == WPA_FLAG_OFF)) {
194 		wpa_error_log0(MSG_ERROR, "wpa_supplicant_reconnect_timeout input NULL ptr!");
195 		return;
196 	}
197 	if (g_reconnect_set.enable == WPA_FLAG_OFF) {
198 		wpa_error_log0(MSG_ERROR, "reconnect policy disabled!");
199 		return;
200 	}
201 	if ((wpa_s->wpa_state != WPA_COMPLETED) && (g_reconnect_set.pending_flag)) {
202 		wpas_request_disconnection(wpa_s);
203 		g_connecting_flag = WPA_FLAG_OFF;
204 		wpa_error_log0(MSG_ERROR, "wpa reconnect timeout, try to connect next period!");
205 	}
206 	g_reconnect_set.pending_flag = WPA_FLAG_OFF;
207 	if (++g_reconnect_set.try_count >= g_reconnect_set.max_try_count) {
208 		g_reconnect_set.current_ssid = NULL;
209 		wpa_error_log0(MSG_ERROR, "wpa reconnect timeout, do not try to connect any more !");
210 		return;
211 	}
212 	if (g_reconnect_set.period > 0)
213 		(void)eloop_register_timeout(g_reconnect_set.period, 0, wpa_supplicant_reconnect_restart, wpa_s, NULL);
214 }
215 
216 #ifndef EXT_CODE_CROP
217 static ext_wifi_event g_disconnect_delay_report_events = { 0 };
218 
wpa_send_disconnect_delay_report_events(void)219 void wpa_send_disconnect_delay_report_events(void)
220 {
221 	g_disconnect_delay_report_events.event = EXT_WIFI_EVT_DISCONNECTED;
222 	if ((g_wpa_event_cb != NULL) && !is_zero_ether_addr(g_disconnect_delay_report_events.info.wifi_disconnected.bssid))
223 		wifi_new_task_event_cb(&g_disconnect_delay_report_events);
224 	(void)os_memset(&g_disconnect_delay_report_events, 0, sizeof(ext_wifi_event));
225 }
226 
wpa_save_disconnect_event(const struct wpa_supplicant * wpa_s,const u8 * bssid,u16 reason_code)227 void wpa_save_disconnect_event(const struct wpa_supplicant *wpa_s, const u8 *bssid, u16 reason_code)
228 {
229 	unsigned char *old_bssid = g_disconnect_delay_report_events.info.wifi_disconnected.bssid;
230 	if ((wpa_s == NULL) || (wpa_is_sta(wpa_s) == WPA_FLAG_OFF) || (bssid == NULL))
231 		return;
232 	if ((!is_zero_ether_addr(old_bssid)) && (os_memcmp(old_bssid, bssid, ETH_ALEN) != 0))
233 		return;
234 	(void)os_memset(&g_disconnect_delay_report_events, 0, sizeof(ext_wifi_event));
235 	g_disconnect_delay_report_events.event = EXT_WIFI_EVT_DISCONNECTED;
236 	(void)os_memcpy(g_disconnect_delay_report_events.info.wifi_disconnected.ifname,
237 	              wpa_s->ifname, WIFI_IFNAME_MAX_SIZE);
238 	(void)os_memcpy(g_disconnect_delay_report_events.info.wifi_disconnected.bssid, bssid, ETH_ALEN);
239 	g_disconnect_delay_report_events.info.wifi_disconnected.reason_code = reason_code;
240 }
241 
wpa_sta_delay_report_deinit(const struct ext_wifi_dev * wifi_dev)242 void wpa_sta_delay_report_deinit(const struct ext_wifi_dev *wifi_dev)
243 {
244 	if ((wifi_dev == NULL) || (wifi_dev->iftype != EXT_WIFI_IFTYPE_STATION))
245 		return;
246 	g_sta_delay_report_flag = WPA_FLAG_OFF;
247 	(void)os_memset(&g_disconnect_delay_report_events, 0, sizeof(ext_wifi_event));
248 }
249 #endif
250 
wpa_is_sta(const struct wpa_supplicant * wpa_s)251 int wpa_is_sta(const struct wpa_supplicant *wpa_s)
252 {
253 	struct ext_wifi_dev *wifi_dev = los_get_wifi_dev_by_priv(wpa_s);
254 	if ((wifi_dev != NULL) && (wifi_dev->iftype == EXT_WIFI_IFTYPE_STATION)) {
255 		return WPA_FLAG_ON;
256 	}
257 	return WPA_FLAG_OFF;
258 }
259 
260 #ifndef CONFIG_ROAM_EXTRA_SUPPORT
wpa_clear_passphrase(struct wpa_supplicant * wpa_s)261 void wpa_clear_passphrase(struct wpa_supplicant *wpa_s)
262 {
263 	struct wpa_ssid *ssid = wpa_s->current_ssid;
264 	if ((ssid != NULL) && (ssid->passphrase != NULL)) {
265 		/* 对passphrase进行清空操作会导致wpa3回连失败,先将密码置0,然后设置*字符 */
266 		if (ssid->passphrase[0] != '*') {
267 			os_memset(ssid->passphrase, 0, strlen(ssid->passphrase));
268 			os_memcpy(ssid->passphrase, "********", strlen("********"));
269 		} else {
270 			os_memset(ssid->passphrase, 0, strlen(ssid->passphrase));
271 			os_memcpy(ssid->passphrase, "a*******", strlen("a*******"));
272 		}
273 
274 	}
275 }
276 #endif
277 
278 #ifdef LOS_INLINE_FUNC_CROP
wpa_drv_get_bssid(struct wpa_supplicant * wpa_s,u8 * bssid)279 int wpa_drv_get_bssid(struct wpa_supplicant *wpa_s, u8 *bssid)
280 {
281 	if ((wpa_s != NULL) && (wpa_s->driver != NULL) && (wpa_s->driver->get_bssid != NULL))
282 		return wpa_s->driver->get_bssid(wpa_s->drv_priv, bssid);
283 	return -1;
284 }
285 
wpa_drv_get_ssid(struct wpa_supplicant * wpa_s,u8 * ssid)286 int wpa_drv_get_ssid(struct wpa_supplicant *wpa_s, u8 *ssid)
287 {
288 	if ((wpa_s != NULL) && (wpa_s->driver != NULL) && (wpa_s->driver->get_ssid != NULL))
289 		return wpa_s->driver->get_ssid(wpa_s->drv_priv, ssid);
290 	return -1;
291 }
292 
wpa_drv_set_key(struct wpa_supplicant * wpa_s,enum wpa_alg alg,const u8 * addr,int key_idx,int set_tx,const u8 * seq,size_t seq_len,const u8 * key,size_t key_len)293 int wpa_drv_set_key(struct wpa_supplicant *wpa_s,
294 				  enum wpa_alg alg, const u8 *addr,
295 				  int key_idx, int set_tx,
296 				  const u8 *seq, size_t seq_len,
297 				  const u8 *key, size_t key_len)
298 {
299 	struct wpa_driver_set_key_params params;
300 
301 	unsigned int idx = (unsigned int)key_idx;
302 
303 	os_memset(&params, 0, sizeof(params));
304 
305 	if ((wpa_s == NULL) || (wpa_s->driver == NULL) || (wpa_s->driver->get_ssid == NULL))
306 		return -1;
307 
308 	if (alg != WPA_ALG_NONE) {
309 		if (idx <= 6)
310 			wpa_s->keys_cleared &= ~BIT(idx);
311 		else
312 			wpa_s->keys_cleared = 0;
313 	}
314 	if (wpa_s->driver->set_key) {
315         params.ifname = wpa_s->ifname;
316         params.alg = alg;
317         params.addr = addr;
318         params.key_idx = key_idx;
319         params.set_tx = set_tx;
320         params.seq = seq;
321         params.seq_len = seq_len;
322         params.key = key;
323         params.key_len = key_len;
324 
325 		return wpa_s->driver->set_key(wpa_s->drv_priv, &params);
326 	}
327 	return -1;
328 }
329 #endif /* LOS_INLINE_FUNC_CROP */
330