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(¶ms, 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, ¶ms);
326 }
327 return -1;
328 }
329 #endif /* LOS_INLINE_FUNC_CROP */
330