external/wpa_supplicant_6
Revision | da76bdd051938b49384a8ccd04971d2e0b5bf7f7 (tree) |
---|---|
Time | 2011-01-23 01:27:11 |
Author | Nicu Pavel <npavel@linu...> |
Commiter | Chih-Wei Huang |
Added a separate driver awext to emulate Android driver commands
Change-Id: I5e14cfc5dd16c9429387b5a5acc39c55edd2fa4e
@@ -144,6 +144,12 @@ OBJS_d += src/drivers/driver_hostap.c | ||
144 | 144 | CONFIG_WIRELESS_EXTENSION=y |
145 | 145 | endif |
146 | 146 | |
147 | +ifdef CONFIG_DRIVER_AWEXT | |
148 | +L_CFLAGS += -DCONFIG_DRIVER_AWEXT | |
149 | +OBJS_d += src/drivers/driver_awext.c | |
150 | +CONFIG_WIRELESS_EXTENSION=y | |
151 | +endif | |
152 | + | |
147 | 153 | ifdef CONFIG_DRIVER_WEXT |
148 | 154 | L_CFLAGS += -DCONFIG_DRIVER_WEXT |
149 | 155 | CONFIG_WIRELESS_EXTENSION=y |
@@ -0,0 +1,913 @@ | ||
1 | +/* | |
2 | + * WEXT Emulation for Android SIOCSIWPRIV ioctl with generic Linux Wireless Extensions | |
3 | + * Copyright (c) 2010, Nicu Pavel <npavel@linuxconsulting.ro> | |
4 | + * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> | |
5 | + * | |
6 | + * Code based on Jim Huang <jserv@0xlab.org> e9bd7cc3d137eb56ebd4220d4077563743ab6723 | |
7 | + * patch for 0xdroid | |
8 | + * | |
9 | + * This program is free software; you can redistribute it and/or modify | |
10 | + * it under the terms of the GNU General Public License version 2 as | |
11 | + * published by the Free Software Foundation. | |
12 | + * | |
13 | + * Alternatively, this software may be distributed under the terms of BSD | |
14 | + * license. | |
15 | + * | |
16 | + * See README and COPYING for more details. | |
17 | + * | |
18 | + */ | |
19 | + | |
20 | +#include "includes.h" | |
21 | +#include <sys/ioctl.h> | |
22 | +#include <net/if_arp.h> | |
23 | +#include <net/if.h> | |
24 | + | |
25 | +#include "wireless_copy.h" | |
26 | +#include "common.h" | |
27 | +#include "driver.h" | |
28 | +#include "l2_packet.h" | |
29 | +#include "eloop.h" | |
30 | +#include "priv_netlink.h" | |
31 | +#include "driver_awext.h" | |
32 | +#include "wpa.h" | |
33 | +#include "wpa_ctrl.h" | |
34 | +#include "wpa_supplicant_i.h" | |
35 | +#include "config_ssid.h" | |
36 | + | |
37 | +#ifdef CONFIG_CLIENT_MLME | |
38 | +#include <netpacket/packet.h> | |
39 | +#include <hostapd_ioctl.h> | |
40 | +#include <ieee80211_common.h> | |
41 | +/* from net/mac80211.h */ | |
42 | +enum { | |
43 | + MODE_IEEE80211A = 0 /* IEEE 802.11a */, | |
44 | + MODE_IEEE80211B = 1 /* IEEE 802.11b only */, | |
45 | + MODE_ATHEROS_TURBO = 2 /* Atheros Turbo mode (2x.11a at 5 GHz) */, | |
46 | + MODE_IEEE80211G = 3 /* IEEE 802.11g (and 802.11b compatibility) */, | |
47 | + MODE_ATHEROS_TURBOG = 4 /* Atheros Turbo mode (2x.11g at 2.4 GHz) */, | |
48 | + NUM_IEEE80211_MODES = 5 | |
49 | +}; | |
50 | + | |
51 | +#include "mlme.h" | |
52 | + | |
53 | +#ifndef ETH_P_ALL | |
54 | +#define ETH_P_ALL 0x0003 | |
55 | +#endif | |
56 | +#endif /* CONFIG_CLIENT_MLME */ | |
57 | + | |
58 | +struct wpa_driver_awext_data { | |
59 | + struct wpa_driver_wext_data *wext; /* structure for wext */ | |
60 | + u8 ssid[32]; | |
61 | + unsigned int ssid_len; | |
62 | +}; | |
63 | + | |
64 | +static int wpa_driver_awext_set_auth_param(struct wpa_driver_awext_data *drv, | |
65 | + int idx, u32 value) | |
66 | +{ | |
67 | + struct iwreq iwr; | |
68 | + int ret = 0; | |
69 | + | |
70 | + os_memset(&iwr, 0, sizeof(iwr)); | |
71 | + os_strncpy(iwr.ifr_name, drv->wext->ifname, IFNAMSIZ); | |
72 | + iwr.u.param.flags = idx & IW_AUTH_INDEX; | |
73 | + iwr.u.param.value = value; | |
74 | + | |
75 | + if (ioctl(drv->wext->ioctl_sock, SIOCSIWAUTH, &iwr) < 0) { | |
76 | + if (errno != EOPNOTSUPP) { | |
77 | + wpa_printf(MSG_DEBUG, "WEXT: SIOCSIWAUTH(param %d " | |
78 | + "value 0x%x) failed: %s)", | |
79 | + idx, value, strerror(errno)); | |
80 | + } | |
81 | + ret = errno == EOPNOTSUPP ? -2 : -1; | |
82 | + } | |
83 | + | |
84 | + return ret; | |
85 | +} | |
86 | + | |
87 | +static int wpa_driver_awext_set_auth_alg(void *priv, int auth_alg) | |
88 | +{ | |
89 | + struct wpa_driver_awext_data *drv = priv; | |
90 | + int algs = 0, res; | |
91 | + | |
92 | + if (auth_alg & AUTH_ALG_OPEN_SYSTEM) | |
93 | + algs |= IW_AUTH_ALG_OPEN_SYSTEM; | |
94 | + if (auth_alg & AUTH_ALG_SHARED_KEY) | |
95 | + algs |= IW_AUTH_ALG_SHARED_KEY; | |
96 | + if (auth_alg & AUTH_ALG_LEAP) | |
97 | + algs |= IW_AUTH_ALG_LEAP; | |
98 | + if (algs == 0) { | |
99 | + /* at least one algorithm should be set */ | |
100 | + algs = IW_AUTH_ALG_OPEN_SYSTEM; | |
101 | + } | |
102 | + | |
103 | + res = wpa_driver_awext_set_auth_param(drv, IW_AUTH_80211_AUTH_ALG, algs); | |
104 | + drv->wext->auth_alg_fallback = res == -2; | |
105 | + return res; | |
106 | +} | |
107 | + | |
108 | +static int wpa_driver_awext_set_gen_ie(void *priv, const u8 *ie, | |
109 | + size_t ie_len) | |
110 | +{ | |
111 | + struct wpa_driver_awext_data *drv = priv; | |
112 | + struct iwreq iwr; | |
113 | + int ret = 0; | |
114 | + | |
115 | + os_memset(&iwr, 0, sizeof(iwr)); | |
116 | + os_strncpy(iwr.ifr_name, drv->wext->ifname, IFNAMSIZ); | |
117 | + iwr.u.data.pointer = (caddr_t) ie; | |
118 | + iwr.u.data.length = ie_len; | |
119 | + | |
120 | + if (ioctl(drv->wext->ioctl_sock, SIOCSIWGENIE, &iwr) < 0) { | |
121 | + perror("ioctl[SIOCSIWGENIE]"); | |
122 | + ret = -1; | |
123 | + } | |
124 | + | |
125 | + return ret; | |
126 | +} | |
127 | + | |
128 | +static int wpa_driver_awext_cipher2wext(int cipher) | |
129 | +{ | |
130 | + switch (cipher) { | |
131 | + case CIPHER_NONE: | |
132 | + return IW_AUTH_CIPHER_NONE; | |
133 | + case CIPHER_WEP40: | |
134 | + return IW_AUTH_CIPHER_WEP40; | |
135 | + case CIPHER_TKIP: | |
136 | + return IW_AUTH_CIPHER_TKIP; | |
137 | + case CIPHER_CCMP: | |
138 | + return IW_AUTH_CIPHER_CCMP; | |
139 | + case CIPHER_WEP104: | |
140 | + return IW_AUTH_CIPHER_WEP104; | |
141 | + default: | |
142 | + return 0; | |
143 | + } | |
144 | +} | |
145 | + | |
146 | + | |
147 | +static int wpa_driver_awext_keymgmt2wext(int keymgmt) | |
148 | +{ | |
149 | + switch (keymgmt) { | |
150 | + case KEY_MGMT_802_1X: | |
151 | + case KEY_MGMT_802_1X_NO_WPA: | |
152 | + return IW_AUTH_KEY_MGMT_802_1X; | |
153 | + case KEY_MGMT_PSK: | |
154 | + return IW_AUTH_KEY_MGMT_PSK; | |
155 | + default: | |
156 | + return 0; | |
157 | + } | |
158 | +} | |
159 | + | |
160 | + | |
161 | +static int | |
162 | +wpa_driver_awext_auth_alg_fallback(struct wpa_driver_awext_data *drv, | |
163 | + struct wpa_driver_associate_params *params) | |
164 | +{ | |
165 | + struct iwreq iwr; | |
166 | + int ret = 0; | |
167 | + | |
168 | + wpa_printf(MSG_DEBUG, "WEXT: Driver did not support " | |
169 | + "SIOCSIWAUTH for AUTH_ALG, trying SIOCSIWENCODE"); | |
170 | + | |
171 | + os_memset(&iwr, 0, sizeof(iwr)); | |
172 | + os_strncpy(iwr.ifr_name, drv->wext->ifname, IFNAMSIZ); | |
173 | + /* Just changing mode, not actual keys */ | |
174 | + iwr.u.encoding.flags = 0; | |
175 | + iwr.u.encoding.pointer = (caddr_t) NULL; | |
176 | + iwr.u.encoding.length = 0; | |
177 | + | |
178 | + /* | |
179 | + * Note: IW_ENCODE_{OPEN,RESTRICTED} can be interpreted to mean two | |
180 | + * different things. Here they are used to indicate Open System vs. | |
181 | + * Shared Key authentication algorithm. However, some drivers may use | |
182 | + * them to select between open/restricted WEP encrypted (open = allow | |
183 | + * both unencrypted and encrypted frames; restricted = only allow | |
184 | + * encrypted frames). | |
185 | + */ | |
186 | + | |
187 | + if (!drv->wext->use_crypt) { | |
188 | + iwr.u.encoding.flags |= IW_ENCODE_DISABLED; | |
189 | + } else { | |
190 | + if (params->auth_alg & AUTH_ALG_OPEN_SYSTEM) | |
191 | + iwr.u.encoding.flags |= IW_ENCODE_OPEN; | |
192 | + if (params->auth_alg & AUTH_ALG_SHARED_KEY) | |
193 | + iwr.u.encoding.flags |= IW_ENCODE_RESTRICTED; | |
194 | + } | |
195 | + | |
196 | + if (ioctl(drv->wext->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) { | |
197 | + perror("ioctl[SIOCSIWENCODE]"); | |
198 | + ret = -1; | |
199 | + } | |
200 | + | |
201 | + return ret; | |
202 | +} | |
203 | + | |
204 | + | |
205 | + | |
206 | +static int | |
207 | +wpa_driver_awext_associate(void *priv, | |
208 | + struct wpa_driver_associate_params *params) | |
209 | +{ | |
210 | + struct wpa_driver_awext_data *drv = priv; | |
211 | + int ret = 0; | |
212 | + int allow_unencrypted_eapol; | |
213 | + int value, flags; | |
214 | + | |
215 | + wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); | |
216 | + | |
217 | + if (wpa_driver_awext_get_ifflags(drv, &flags) == 0) { | |
218 | + if (!(flags & IFF_UP)) { | |
219 | + wpa_driver_awext_set_ifflags(drv, flags | IFF_UP); | |
220 | + } | |
221 | + } | |
222 | + | |
223 | + /* | |
224 | + * If the driver did not support SIOCSIWAUTH, fallback to | |
225 | + * SIOCSIWENCODE here. | |
226 | + */ | |
227 | + if (drv->wext->auth_alg_fallback && | |
228 | + wpa_driver_awext_auth_alg_fallback(drv, params) < 0) | |
229 | + ret = -1; | |
230 | + | |
231 | + if (!params->bssid && | |
232 | + wpa_driver_awext_set_bssid(drv, NULL) < 0) | |
233 | + ret = -1; | |
234 | + | |
235 | + if (wpa_driver_awext_set_mode(drv, params->mode) < 0) | |
236 | + ret = -1; | |
237 | + /* TODO: should consider getting wpa version and cipher/key_mgmt suites | |
238 | + * from configuration, not from here, where only the selected suite is | |
239 | + * available */ | |
240 | + if (wpa_driver_awext_set_gen_ie(drv, params->wpa_ie, params->wpa_ie_len) | |
241 | + < 0) | |
242 | + ret = -1; | |
243 | + if (params->wpa_ie == NULL || params->wpa_ie_len == 0) | |
244 | + value = IW_AUTH_WPA_VERSION_DISABLED; | |
245 | +// else if (params->wpa_ie[0] == RSN_INFO_ELEM) | |
246 | +// value = IW_AUTH_WPA_VERSION_WPA2; | |
247 | + else | |
248 | + value = IW_AUTH_WPA_VERSION_WPA; | |
249 | + if (wpa_driver_awext_set_auth_param(drv, | |
250 | + IW_AUTH_WPA_VERSION, value) < 0) | |
251 | + ret = -1; | |
252 | + value = wpa_driver_awext_cipher2wext(params->pairwise_suite); | |
253 | + if (wpa_driver_awext_set_auth_param(drv, | |
254 | + IW_AUTH_CIPHER_PAIRWISE, value) < 0) | |
255 | + ret = -1; | |
256 | + value = wpa_driver_awext_cipher2wext(params->group_suite); | |
257 | + if (wpa_driver_awext_set_auth_param(drv, | |
258 | + IW_AUTH_CIPHER_GROUP, value) < 0) | |
259 | + ret = -1; | |
260 | + value = wpa_driver_awext_keymgmt2wext(params->key_mgmt_suite); | |
261 | + if (wpa_driver_awext_set_auth_param(drv, | |
262 | + IW_AUTH_KEY_MGMT, value) < 0) | |
263 | + ret = -1; | |
264 | + value = params->key_mgmt_suite != KEY_MGMT_NONE || | |
265 | + params->pairwise_suite != CIPHER_NONE || | |
266 | + params->group_suite != CIPHER_NONE || | |
267 | + params->wpa_ie_len; | |
268 | + if (wpa_driver_awext_set_auth_param(drv, | |
269 | + IW_AUTH_PRIVACY_INVOKED, value) < 0) | |
270 | + ret = -1; | |
271 | + | |
272 | + /* Allow unencrypted EAPOL messages even if pairwise keys are set when | |
273 | + * not using WPA. IEEE 802.1X specifies that these frames are not | |
274 | + * encrypted, but WPA encrypts them when pairwise keys are in use. */ | |
275 | + if (params->key_mgmt_suite == KEY_MGMT_802_1X || | |
276 | + params->key_mgmt_suite == KEY_MGMT_PSK) | |
277 | + allow_unencrypted_eapol = 0; | |
278 | + else | |
279 | + allow_unencrypted_eapol = 1; | |
280 | + | |
281 | + if (wpa_driver_awext_set_auth_param(drv, | |
282 | + IW_AUTH_RX_UNENCRYPTED_EAPOL, | |
283 | + allow_unencrypted_eapol) < 0) | |
284 | + ret = -1; | |
285 | + if (params->freq && wpa_driver_awext_set_freq(drv, params->freq) < 0) | |
286 | + ret = -1; | |
287 | + if (wpa_driver_awext_set_ssid(drv, params->ssid, params->ssid_len) < 0) | |
288 | + ret = -1; | |
289 | + if (params->bssid && | |
290 | + wpa_driver_awext_set_bssid(drv, params->bssid) < 0) | |
291 | + ret = -1; | |
292 | + | |
293 | + return ret; | |
294 | +} | |
295 | + | |
296 | + | |
297 | +static int wpa_driver_awext_set_countermeasures(void *priv, | |
298 | + int enabled) | |
299 | +{ | |
300 | + struct wpa_driver_awext_data *drv = priv; | |
301 | + wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); | |
302 | + return wpa_driver_awext_set_auth_param(drv, | |
303 | + IW_AUTH_TKIP_COUNTERMEASURES, | |
304 | + enabled); | |
305 | +} | |
306 | + | |
307 | +static int wpa_driver_awext_set_drop_unencrypted(void *priv, | |
308 | + int enabled) | |
309 | +{ | |
310 | + struct wpa_driver_awext_data *drv = priv; | |
311 | + wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); | |
312 | + drv->wext->use_crypt = enabled; | |
313 | + return wpa_driver_awext_set_auth_param(drv, IW_AUTH_DROP_UNENCRYPTED, | |
314 | + enabled); | |
315 | +} | |
316 | + | |
317 | +static int wpa_driver_awext_mlme(struct wpa_driver_awext_data *drv, | |
318 | + const u8 *addr, int cmd, int reason_code) | |
319 | +{ | |
320 | + struct iwreq iwr; | |
321 | + struct iw_mlme mlme; | |
322 | + int ret = 0; | |
323 | + | |
324 | + os_memset(&iwr, 0, sizeof(iwr)); | |
325 | + os_strncpy(iwr.ifr_name, drv->wext->ifname, IFNAMSIZ); | |
326 | + os_memset(&mlme, 0, sizeof(mlme)); | |
327 | + mlme.cmd = cmd; | |
328 | + mlme.reason_code = reason_code; | |
329 | + mlme.addr.sa_family = ARPHRD_ETHER; | |
330 | + os_memcpy(mlme.addr.sa_data, addr, ETH_ALEN); | |
331 | + iwr.u.data.pointer = (caddr_t) &mlme; | |
332 | + iwr.u.data.length = sizeof(mlme); | |
333 | + | |
334 | + if (ioctl(drv->wext->ioctl_sock, SIOCSIWMLME, &iwr) < 0) { | |
335 | + perror("ioctl[SIOCSIWMLME]"); | |
336 | + ret = -1; | |
337 | + } | |
338 | + | |
339 | + return ret; | |
340 | +} | |
341 | +#ifdef CONFIG_CLIENT_MLME | |
342 | +static int wpa_driver_awext_open_mlme(struct wpa_driver_awext_data *drv) | |
343 | +{ | |
344 | + int flags, ifindex, s, *i; | |
345 | + struct sockaddr_ll addr; | |
346 | + struct iwreq iwr; | |
347 | + | |
348 | + os_memset(&iwr, 0, sizeof(iwr)); | |
349 | + os_strncpy(iwr.ifr_name, drv->wext->ifname, IFNAMSIZ); | |
350 | + i = (int *) iwr.u.name; | |
351 | + *i++ = PRISM2_PARAM_USER_SPACE_MLME; | |
352 | + *i++ = 1; | |
353 | + | |
354 | + if (ioctl(drv->wext->ioctl_sock, PRISM2_IOCTL_PRISM2_PARAM, &iwr) < 0) { | |
355 | + wpa_printf(MSG_ERROR, "WEXT: Failed to configure driver to " | |
356 | + "use user space MLME"); | |
357 | + return -1; | |
358 | + } | |
359 | + | |
360 | + ifindex = if_nametoindex(drv->wext->mlmedev); | |
361 | + if (ifindex == 0) { | |
362 | + wpa_printf(MSG_ERROR, "WEXT: mlmedev='%s' not found", | |
363 | + drv->mlmedev); | |
364 | + return -1; | |
365 | + } | |
366 | + | |
367 | + if (wpa_driver_awext_get_ifflags_ifname(drv, drv->wext->mlmedev, &flags) != 0 | |
368 | + || wpa_driver_awext_set_ifflags_ifname(drv, drv->wext->mlmedev, | |
369 | + flags | IFF_UP) != 0) { | |
370 | + wpa_printf(MSG_ERROR, "WEXT: Could not set interface " | |
371 | + "'%s' UP", drv->mlmedev); | |
372 | + return -1; | |
373 | + } | |
374 | + | |
375 | + s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); | |
376 | + if (s < 0) { | |
377 | + perror("socket[PF_PACKET,SOCK_RAW]"); | |
378 | + return -1; | |
379 | + } | |
380 | + | |
381 | + os_memset(&addr, 0, sizeof(addr)); | |
382 | + addr.sll_family = AF_PACKET; | |
383 | + addr.sll_ifindex = ifindex; | |
384 | + | |
385 | + if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { | |
386 | + perror("bind(MLME)"); | |
387 | + return -1; | |
388 | + } | |
389 | + | |
390 | + if (eloop_register_read_sock(s, wpa_driver_awext_mlme_read, drv, NULL)) | |
391 | + { | |
392 | + wpa_printf(MSG_ERROR, "WEXT: Could not register MLME read " | |
393 | + "socket"); | |
394 | + close(s); | |
395 | + return -1; | |
396 | + } | |
397 | + | |
398 | + return s; | |
399 | +} | |
400 | + | |
401 | + | |
402 | +#endif /* CONFIG_CLIENT_MLME */ | |
403 | + | |
404 | +static int wpa_driver_awext_pmksa(struct wpa_driver_awext_data *drv, | |
405 | + u32 cmd, const u8 *bssid, const u8 *pmkid) | |
406 | +{ | |
407 | + struct iwreq iwr; | |
408 | + struct iw_pmksa pmksa; | |
409 | + int ret = 0; | |
410 | + | |
411 | + os_memset(&iwr, 0, sizeof(iwr)); | |
412 | + os_strncpy(iwr.ifr_name, drv->wext->ifname, IFNAMSIZ); | |
413 | + os_memset(&pmksa, 0, sizeof(pmksa)); | |
414 | + pmksa.cmd = cmd; | |
415 | + pmksa.bssid.sa_family = ARPHRD_ETHER; | |
416 | + if (bssid) | |
417 | + os_memcpy(pmksa.bssid.sa_data, bssid, ETH_ALEN); | |
418 | + if (pmkid) | |
419 | + os_memcpy(pmksa.pmkid, pmkid, IW_PMKID_LEN); | |
420 | + iwr.u.data.pointer = (caddr_t) &pmksa; | |
421 | + iwr.u.data.length = sizeof(pmksa); | |
422 | + | |
423 | + if (ioctl(drv->wext->ioctl_sock, SIOCSIWPMKSA, &iwr) < 0) { | |
424 | + if (errno != EOPNOTSUPP) | |
425 | + perror("ioctl[SIOCSIWPMKSA]"); | |
426 | + ret = -1; | |
427 | + } | |
428 | + | |
429 | + return ret; | |
430 | +} | |
431 | + | |
432 | +static int wpa_driver_awext_add_pmkid(void *priv, const u8 *bssid, | |
433 | + const u8 *pmkid) | |
434 | +{ | |
435 | + struct wpa_driver_awext_data *drv = priv; | |
436 | + return wpa_driver_awext_pmksa(drv, IW_PMKSA_ADD, bssid, pmkid); | |
437 | +} | |
438 | + | |
439 | + | |
440 | +static int wpa_driver_awext_remove_pmkid(void *priv, const u8 *bssid, | |
441 | + const u8 *pmkid) | |
442 | +{ | |
443 | + struct wpa_driver_awext_data *drv = priv; | |
444 | + return wpa_driver_awext_pmksa(drv, IW_PMKSA_REMOVE, bssid, pmkid); | |
445 | +} | |
446 | + | |
447 | + | |
448 | +static int wpa_driver_awext_flush_pmkid(void *priv) | |
449 | +{ | |
450 | + struct wpa_driver_awext_data *drv = priv; | |
451 | + return wpa_driver_awext_pmksa(drv, IW_PMKSA_FLUSH, NULL, NULL); | |
452 | +} | |
453 | + | |
454 | + | |
455 | +static int wpa_driver_awext_get_capa(void *priv, struct wpa_driver_capa *capa) | |
456 | +{ | |
457 | + struct wpa_driver_awext_data *drv = priv; | |
458 | + if (!drv->wext->has_capability) | |
459 | + return -1; | |
460 | + os_memcpy(capa, &drv->wext->capa, sizeof(*capa)); | |
461 | + return 0; | |
462 | +} | |
463 | + | |
464 | + | |
465 | +static int wpa_driver_awext_set_param(void *priv, const char *param) | |
466 | +{ | |
467 | +#ifdef CONFIG_CLIENT_MLME | |
468 | + struct wpa_driver_awext_data *drv = priv; | |
469 | + const char *pos, *pos2; | |
470 | + size_t len; | |
471 | + | |
472 | + if (param == NULL) | |
473 | + return 0; | |
474 | + | |
475 | + wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param); | |
476 | + | |
477 | + pos = os_strstr(param, "mlmedev="); | |
478 | + if (pos) { | |
479 | + pos += 8; | |
480 | + pos2 = os_strchr(pos, ' '); | |
481 | + if (pos2) | |
482 | + len = pos2 - pos; | |
483 | + else | |
484 | + len = os_strlen(pos); | |
485 | + if (len + 1 > sizeof(drv->wext->mlmedev)) | |
486 | + return -1; | |
487 | + os_memcpy(drv->wext->mlmedev, pos, len); | |
488 | + drv->wext->mlmedev[len] = '\0'; | |
489 | + wpa_printf(MSG_DEBUG, "WEXT: Using user space MLME with " | |
490 | + "mlmedev='%s'", drv->wext->mlmedev); | |
491 | + drv->wext->capa.flags |= WPA_DRIVER_FLAGS_USER_SPACE_MLME; | |
492 | + | |
493 | + drv->wext->mlme_sock = wpa_driver_awext_open_mlme(drv->wext); | |
494 | + if (drv->wext->mlme_sock < 0) | |
495 | + return -1; | |
496 | + } | |
497 | +#endif /* CONFIG_CLIENT_MLME */ | |
498 | + | |
499 | + return 0; | |
500 | +} | |
501 | + | |
502 | +static int wpa_driver_awext_deauthenticate(void *priv, const u8 *addr, | |
503 | + int reason_code) | |
504 | +{ | |
505 | + struct wpa_driver_awext_data *drv = priv; | |
506 | + wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); | |
507 | + return wpa_driver_awext_mlme(drv, addr, IW_MLME_DEAUTH, reason_code); | |
508 | +} | |
509 | + | |
510 | +static int wpa_driver_awext_disassociate(void *priv, const u8 *addr, | |
511 | + int reason_code) | |
512 | +{ | |
513 | + struct wpa_driver_awext_data *drv = priv; | |
514 | + wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); | |
515 | + return wpa_driver_awext_mlme(drv, addr, IW_MLME_DISASSOC, | |
516 | + reason_code); | |
517 | +} | |
518 | + | |
519 | +int wpa_driver_awext_get_bssid(void *priv, u8 *bssid) | |
520 | +{ | |
521 | + struct wpa_driver_awext_data *drv = priv; | |
522 | + return wpa_driver_wext_get_bssid(drv->wext, bssid); | |
523 | +} | |
524 | + | |
525 | +int wpa_driver_awext_set_bssid(void *priv, const u8 *bssid) | |
526 | +{ | |
527 | + struct wpa_driver_awext_data *drv = priv; | |
528 | + return wpa_driver_wext_set_bssid(drv->wext, bssid); | |
529 | +} | |
530 | + | |
531 | +int wpa_driver_awext_get_ssid(void *priv, u8 *ssid) | |
532 | +{ | |
533 | + struct wpa_driver_awext_data *drv = priv; | |
534 | + return wpa_driver_wext_get_ssid(drv->wext, ssid); | |
535 | +} | |
536 | + | |
537 | +int wpa_driver_awext_set_ssid(void *priv, const u8 *ssid, size_t ssid_len) | |
538 | +{ | |
539 | + struct wpa_driver_awext_data *drv = priv; | |
540 | + | |
541 | + if (ssid_len > 32) | |
542 | + return -1; | |
543 | + | |
544 | + os_memset(drv->ssid, 0, 32); | |
545 | + os_memcpy(drv->ssid, ssid, ssid_len); | |
546 | + drv->ssid_len = ssid_len; | |
547 | + | |
548 | + return wpa_driver_wext_set_ssid(drv->wext, ssid, ssid_len); | |
549 | +} | |
550 | + | |
551 | +int wpa_driver_awext_set_freq(void *priv, int freq) | |
552 | +{ | |
553 | + struct wpa_driver_awext_data *drv = priv; | |
554 | + return wpa_driver_wext_set_freq(drv->wext, freq); | |
555 | +} | |
556 | + | |
557 | +int wpa_driver_awext_get_ifflags(void *priv, int *flags) | |
558 | +{ | |
559 | + struct wpa_driver_awext_data *drv = priv; | |
560 | + return wpa_driver_wext_get_ifflags(drv->wext, flags); | |
561 | +} | |
562 | + | |
563 | +int wpa_driver_awext_set_ifflags(struct wpa_driver_awext_data *drv, int flags) | |
564 | +{ | |
565 | + return wpa_driver_wext_set_ifflags(drv->wext, flags); | |
566 | +} | |
567 | + | |
568 | +void * wpa_driver_awext_init(void *ctx, const char *ifname) | |
569 | +{ | |
570 | + struct wpa_driver_awext_data *drv; | |
571 | + drv = os_zalloc(sizeof(*drv)); | |
572 | + if (drv == NULL) | |
573 | + return NULL; | |
574 | + drv->wext = wpa_driver_wext_init(ctx, ifname); | |
575 | + if (drv->wext == NULL) | |
576 | + { | |
577 | + os_free(drv); | |
578 | + return NULL; | |
579 | + } | |
580 | + | |
581 | + drv->wext->ctx = ctx; | |
582 | + | |
583 | + os_strncpy(drv->wext->ifname, ifname, sizeof(drv->wext->ifname)); | |
584 | + drv->wext->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); | |
585 | + if (drv->wext->ioctl_sock < 0) | |
586 | + { | |
587 | + wpa_driver_wext_deinit(drv->wext); | |
588 | + os_free(drv); | |
589 | + return NULL; | |
590 | + } | |
591 | + | |
592 | + return drv; | |
593 | +} | |
594 | + | |
595 | +void wpa_driver_awext_deinit(void *priv) | |
596 | +{ | |
597 | + struct wpa_driver_awext_data *drv = priv; | |
598 | + wpa_driver_wext_deinit(drv->wext); | |
599 | + close(drv->wext->ioctl_sock); | |
600 | + os_free(drv); | |
601 | +} | |
602 | + | |
603 | +void wpa_driver_awext_scan_timeout(void *eloop_ctx, void *timeout_ctx) | |
604 | +{ | |
605 | + return wpa_driver_wext_scan_timeout(eloop_ctx, timeout_ctx); | |
606 | +} | |
607 | + | |
608 | +int wpa_driver_awext_scan(void *priv, const u8 *ssid, size_t ssid_len) | |
609 | +{ | |
610 | + struct wpa_driver_awext_data *drv = priv; | |
611 | + return wpa_driver_wext_scan(drv->wext, ssid, ssid_len); | |
612 | +} | |
613 | + | |
614 | +struct wpa_scan_result * wpa_driver_awext_get_scan_results(void *priv) | |
615 | +{ | |
616 | + struct wpa_driver_awext_data *drv = priv; | |
617 | + return wpa_driver_wext_get_scan_results(drv->wext); | |
618 | +} | |
619 | + | |
620 | +int wpa_driver_awext_set_key(void *priv, wpa_alg alg, | |
621 | + const u8 *addr, int key_idx, | |
622 | + int set_tx, const u8 *seq, size_t seq_len, | |
623 | + const u8 *key, size_t key_len) | |
624 | +{ | |
625 | + struct wpa_driver_awext_data *drv = priv; | |
626 | + return wpa_driver_wext_set_key(drv->wext, alg, addr, key_idx, set_tx, seq, seq_len, key, key_len); | |
627 | +} | |
628 | + | |
629 | +int wpa_driver_awext_set_mode(void *priv, int mode) | |
630 | +{ | |
631 | + struct wpa_driver_awext_data *drv = priv; | |
632 | + return wpa_driver_wext_set_mode(drv->wext, mode); | |
633 | +} | |
634 | + | |
635 | +int wpa_driver_awext_alternative_ifindex(struct wpa_driver_awext_data *drv, | |
636 | + const char *ifname) | |
637 | +{ | |
638 | + return wpa_driver_wext_alternative_ifindex(drv->wext, ifname); | |
639 | +} | |
640 | + | |
641 | +int wpa_driver_awext_set_operstate(void *priv, int state) | |
642 | +{ | |
643 | + struct wpa_driver_awext_data *drv = priv; | |
644 | + return wpa_driver_wext_set_operstate(drv->wext, state); | |
645 | +} | |
646 | + | |
647 | +int wpa_driver_awext_set_channel(void *priv, wpa_hw_mode phymode, int chan, | |
648 | + int freq) | |
649 | +{ | |
650 | + struct wpa_driver_awext_data *drv = priv; | |
651 | + return wpa_driver_awext_set_freq(drv->wext, freq); | |
652 | +} | |
653 | + | |
654 | +int wpa_driver_awext_get_version(struct wpa_driver_awext_data *drv) | |
655 | +{ | |
656 | + return wpa_driver_wext_get_version(drv->wext); | |
657 | +} | |
658 | + | |
659 | +int wpa_driver_awext_set_wpa(void *priv, int enabled) | |
660 | +{ | |
661 | + struct wpa_driver_awext_data *drv = priv; | |
662 | + return wpa_driver_awext_set_auth_param(drv, IW_AUTH_WPA_ENABLED, enabled); | |
663 | +} | |
664 | + | |
665 | +#ifdef ANDROID | |
666 | +static int wpa_driver_priv_driver_cmd(void *priv, char *cmd, char *buf, size_t buf_len) | |
667 | +{ | |
668 | + | |
669 | + struct wpa_driver_awext_data *drv = priv; | |
670 | + int ret = -1; | |
671 | + int flags; | |
672 | + | |
673 | + wpa_printf(MSG_DEBUG, "AWEXT: %s %s", __func__, cmd); | |
674 | + | |
675 | + if (os_strcasecmp(cmd, "start") == 0) { | |
676 | + wpa_printf(MSG_DEBUG,"Start command"); | |
677 | + return (ret); | |
678 | + } | |
679 | + | |
680 | + if (os_strcasecmp(cmd, "stop") == 0) { | |
681 | + wpa_printf(MSG_DEBUG,"Stop command"); | |
682 | + if ((wpa_driver_awext_get_ifflags(drv, &flags) == 0) && | |
683 | + (flags & IFF_UP)) { | |
684 | + wpa_printf(MSG_ERROR, "WEXT: %s when iface is UP", cmd); | |
685 | + wpa_driver_awext_set_ifflags(drv, flags & ~IFF_UP); | |
686 | + } | |
687 | + | |
688 | + } | |
689 | + else if (os_strcasecmp(cmd, "reload") == 0) { | |
690 | + wpa_printf(MSG_DEBUG,"Reload command"); | |
691 | + wpa_msg(drv->wext->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED"); | |
692 | + return ret; | |
693 | + } | |
694 | + else if (os_strcasecmp(cmd, "macaddr") == 0) { | |
695 | + struct ifreq ifr; | |
696 | + os_memset(&ifr, 0, sizeof(ifr)); | |
697 | + os_strncpy(ifr.ifr_name, drv->wext->ifname, IFNAMSIZ); | |
698 | + | |
699 | + if (ioctl(drv->wext->ioctl_sock, SIOCGIFHWADDR, &ifr) < 0) { | |
700 | + perror("ioctl[SIOCGIFHWADDR]"); | |
701 | + ret = -1; | |
702 | + } else { | |
703 | + u8 *macaddr = (u8 *) ifr.ifr_hwaddr.sa_data; | |
704 | + ret = snprintf(buf, buf_len, "Macaddr = " MACSTR "\n", | |
705 | + MAC2STR(macaddr)); | |
706 | + } | |
707 | + } | |
708 | + else if (os_strcasecmp(cmd, "scan-passive") == 0) { | |
709 | + wpa_printf(MSG_DEBUG,"Scan Passive command"); | |
710 | + } | |
711 | + else if (os_strcasecmp(cmd, "scan-active") == 0) { | |
712 | + wpa_printf(MSG_DEBUG,"Scan Active command"); | |
713 | + } | |
714 | + else if (os_strcasecmp(cmd, "linkspeed") == 0) { | |
715 | + struct iwreq wrq; | |
716 | + unsigned int linkspeed; | |
717 | + os_strncpy(wrq.ifr_name, drv->wext->ifname, IFNAMSIZ); | |
718 | + wpa_printf(MSG_DEBUG,"Link Speed command"); | |
719 | + if (ioctl(drv->wext->ioctl_sock, SIOCGIWRATE, &wrq) < 0) { | |
720 | + perror("ioctl[SIOCGIWRATE]"); | |
721 | + ret = -1; | |
722 | + } else { | |
723 | + linkspeed = wrq.u.bitrate.value / 1000000; | |
724 | + ret = snprintf(buf, buf_len, "LinkSpeed %d\n", linkspeed); | |
725 | + } | |
726 | + } | |
727 | + else if (os_strncasecmp(cmd, "scan-channels", 13) == 0) { | |
728 | + } | |
729 | + else if ((os_strcasecmp(cmd, "rssi") == 0) || (os_strcasecmp(cmd, "rssi-approx") == 0)) { | |
730 | + struct iwreq wrq; | |
731 | + struct iw_statistics stats; | |
732 | + signed int rssi; | |
733 | + wpa_printf(MSG_DEBUG, ">>>. DRIVER AWEXT RSSI "); | |
734 | + wrq.u.data.pointer = (caddr_t) &stats; | |
735 | + wrq.u.data.length = sizeof(stats); | |
736 | + wrq.u.data.flags = 1; /* Clear updated flag */ | |
737 | + strncpy(wrq.ifr_name, drv->wext->ifname, IFNAMSIZ); | |
738 | + | |
739 | + if (ioctl(drv->wext->ioctl_sock, SIOCGIWSTATS, &wrq) < 0) { | |
740 | + perror("ioctl[SIOCGIWSTATS]"); | |
741 | + ret = -1; | |
742 | + } else { | |
743 | + if (stats.qual.updated & IW_QUAL_DBM) { | |
744 | + /* Values in dBm, stored in u8 with range 63 : -192 */ | |
745 | + rssi = ( stats.qual.level > 63 ) ? | |
746 | + stats.qual.level - 0x100 : | |
747 | + stats.qual.level; | |
748 | + } else { | |
749 | + rssi = stats.qual.level; | |
750 | + } | |
751 | + | |
752 | + if (drv->ssid_len != 0 && drv->ssid_len < buf_len) { | |
753 | + os_memcpy((void *) buf, (void *) (drv->ssid), | |
754 | + drv->ssid_len ); | |
755 | + ret = drv->ssid_len; | |
756 | + ret += snprintf(&buf[ret], buf_len-ret, | |
757 | + " rssi %d\n", rssi); | |
758 | + if (ret < (int)buf_len) { | |
759 | + return( ret ); | |
760 | + } | |
761 | + ret = -1; | |
762 | + } | |
763 | + } | |
764 | + } | |
765 | + else if (os_strncasecmp(cmd, "powermode", 9) == 0) { | |
766 | + } | |
767 | + else if (os_strncasecmp(cmd, "getpower", 8) == 0) { | |
768 | + } | |
769 | + else if (os_strncasecmp(cmd, "get-rts-threshold", 17) == 0) { | |
770 | + struct iwreq wrq; | |
771 | + unsigned int rtsThreshold; | |
772 | + | |
773 | + strncpy(wrq.ifr_name, drv->wext->ifname, IFNAMSIZ); | |
774 | + | |
775 | + if (ioctl(drv->wext->ioctl_sock, SIOCGIWRTS, &wrq) < 0) { | |
776 | + perror("ioctl[SIOCGIWRTS]"); | |
777 | + ret = -1; | |
778 | + } else { | |
779 | + rtsThreshold = wrq.u.rts.value; | |
780 | + wpa_printf(MSG_DEBUG,"Get RTS Threshold command = %d", | |
781 | + rtsThreshold); | |
782 | + ret = snprintf(buf, buf_len, "rts-threshold = %u\n", | |
783 | + rtsThreshold); | |
784 | + if (ret < (int)buf_len) { | |
785 | + return( ret ); | |
786 | + } | |
787 | + } | |
788 | + } | |
789 | + else if (os_strncasecmp(cmd, "set-rts-threshold", 17) == 0) { | |
790 | + struct iwreq wrq; | |
791 | + unsigned int rtsThreshold; | |
792 | + char *cp = cmd + 17; | |
793 | + char *endp; | |
794 | + | |
795 | + strncpy(wrq.ifr_name, drv->wext->ifname, IFNAMSIZ); | |
796 | + | |
797 | + if (*cp != '\0') { | |
798 | + rtsThreshold = (unsigned int)strtol(cp, &endp, 0); | |
799 | + if (endp != cp) { | |
800 | + wrq.u.rts.value = rtsThreshold; | |
801 | + wrq.u.rts.fixed = 1; | |
802 | + wrq.u.rts.disabled = 0; | |
803 | + | |
804 | + if (ioctl(drv->wext->ioctl_sock, SIOCSIWRTS, &wrq) < 0) { | |
805 | + perror("ioctl[SIOCGIWRTS]"); | |
806 | + ret = -1; | |
807 | + } else { | |
808 | + rtsThreshold = wrq.u.rts.value; | |
809 | + wpa_printf(MSG_DEBUG,"Set RTS Threshold command = %d", rtsThreshold); | |
810 | + ret = 0; | |
811 | + } | |
812 | + } | |
813 | + } | |
814 | + } | |
815 | + else if (os_strcasecmp(cmd, "btcoexscan-start") == 0) { | |
816 | + } | |
817 | + else if (os_strcasecmp(cmd, "btcoexscan-stop") == 0) { | |
818 | + } | |
819 | + else if (os_strcasecmp(cmd, "rxfilter-start") == 0) { | |
820 | + wpa_printf(MSG_DEBUG,"Rx Data Filter Start command"); | |
821 | + } | |
822 | + else if (os_strcasecmp(cmd, "rxfilter-stop") == 0) { | |
823 | + wpa_printf(MSG_DEBUG,"Rx Data Filter Stop command"); | |
824 | + } | |
825 | + else if (os_strcasecmp(cmd, "rxfilter-statistics") == 0) { | |
826 | + } | |
827 | + else if (os_strncasecmp(cmd, "rxfilter-add", 12) == 0 ) { | |
828 | + } | |
829 | + else if (os_strncasecmp(cmd, "rxfilter-remove",15) == 0) { | |
830 | + } | |
831 | + else if (os_strcasecmp(cmd, "snr") == 0) { | |
832 | + struct iwreq wrq; | |
833 | + struct iw_statistics stats; | |
834 | + int snr, rssi, noise; | |
835 | + | |
836 | + wrq.u.data.pointer = (caddr_t) &stats; | |
837 | + wrq.u.data.length = sizeof(stats); | |
838 | + wrq.u.data.flags = 1; /* Clear updated flag */ | |
839 | + strncpy(wrq.ifr_name, drv->wext->ifname, IFNAMSIZ); | |
840 | + | |
841 | + if (ioctl(drv->wext->ioctl_sock, SIOCGIWSTATS, &wrq) < 0) { | |
842 | + perror("ioctl[SIOCGIWSTATS]"); | |
843 | + ret = -1; | |
844 | + } else { | |
845 | + if (stats.qual.updated & IW_QUAL_DBM) { | |
846 | + /* Values in dBm, stored in u8 with range 63 : -192 */ | |
847 | + rssi = ( stats.qual.level > 63 ) ? | |
848 | + stats.qual.level - 0x100 : | |
849 | + stats.qual.level; | |
850 | + noise = ( stats.qual.noise > 63 ) ? | |
851 | + stats.qual.noise - 0x100 : | |
852 | + stats.qual.noise; | |
853 | + } else { | |
854 | + rssi = stats.qual.level; | |
855 | + noise = stats.qual.noise; | |
856 | + } | |
857 | + | |
858 | + snr = rssi - noise; | |
859 | + | |
860 | + ret = snprintf(buf, buf_len, "snr = %u\n", (unsigned int)snr); | |
861 | + if (ret < (int)buf_len) { | |
862 | + return( ret ); | |
863 | + } | |
864 | + } | |
865 | + } | |
866 | + else if (os_strncasecmp(cmd, "btcoexmode", 10) == 0) { | |
867 | + } | |
868 | + else if( os_strcasecmp(cmd, "btcoexstat") == 0 ) { | |
869 | + } | |
870 | + else { | |
871 | + wpa_printf(MSG_DEBUG,"Unsupported command"); | |
872 | + } | |
873 | + return (ret); | |
874 | +} | |
875 | +#endif | |
876 | + | |
877 | +const struct wpa_driver_ops wpa_driver_awext_ops = { | |
878 | + .name = "awext", | |
879 | + .desc = "Android wireless extensions emulation", | |
880 | + .get_bssid = wpa_driver_awext_get_bssid, | |
881 | + .get_ssid = wpa_driver_awext_get_ssid, | |
882 | + .set_wpa = wpa_driver_awext_set_wpa, | |
883 | + .set_key = wpa_driver_awext_set_key, | |
884 | + .set_countermeasures = wpa_driver_awext_set_countermeasures, | |
885 | + .set_drop_unencrypted = wpa_driver_awext_set_drop_unencrypted, | |
886 | + .scan = wpa_driver_awext_scan, | |
887 | + .get_scan_results2 = wpa_driver_awext_get_scan_results, | |
888 | + .deauthenticate = wpa_driver_awext_deauthenticate, | |
889 | + .disassociate = wpa_driver_awext_disassociate, | |
890 | + .associate = wpa_driver_awext_associate, | |
891 | + .set_auth_alg = wpa_driver_awext_set_auth_alg, | |
892 | + .init = wpa_driver_awext_init, | |
893 | + .deinit = wpa_driver_awext_deinit, | |
894 | + | |
895 | + .set_param = wpa_driver_awext_set_param, | |
896 | + .add_pmkid = wpa_driver_awext_add_pmkid, | |
897 | + .remove_pmkid = wpa_driver_awext_remove_pmkid, | |
898 | + .flush_pmkid = wpa_driver_awext_flush_pmkid, | |
899 | + .get_capa = wpa_driver_awext_get_capa, | |
900 | + .set_operstate = wpa_driver_awext_set_operstate, | |
901 | +#ifdef CONFIG_CLIENT_MLME | |
902 | + .get_hw_feature_data = wpa_driver_awext_get_hw_feature_data, | |
903 | + .set_channel = wpa_driver_awext_set_channel, | |
904 | + .set_ssid = wpa_driver_awext_set_ssid, | |
905 | + .set_bssid = wpa_driver_awext_set_bssid, | |
906 | + .send_mlme = wpa_driver_awext_send_mlme, | |
907 | + .mlme_add_sta = wpa_driver_awext_mlme_add_sta, | |
908 | + .mlme_remove_sta = wpa_driver_awext_mlme_remove_sta, | |
909 | +#endif /* CONFIG_CLIENT_MLME */ | |
910 | +#ifdef ANDROID | |
911 | + .driver_cmd = wpa_driver_priv_driver_cmd, | |
912 | +#endif | |
913 | +}; |
@@ -0,0 +1,57 @@ | ||
1 | +/* | |
2 | + * WPA Supplicant - driver_wext exported functions | |
3 | + * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi> | |
4 | + * | |
5 | + * This program is free software; you can redistribute it and/or modify | |
6 | + * it under the terms of the GNU General Public License version 2 as | |
7 | + * published by the Free Software Foundation. | |
8 | + * | |
9 | + * Alternatively, this software may be distributed under the terms of BSD | |
10 | + * license. | |
11 | + * | |
12 | + * See README and COPYING for more details. | |
13 | + */ | |
14 | + | |
15 | +#ifndef DRIVER_AWEXT_H | |
16 | +#define DRIVER_AWEXT_H | |
17 | + | |
18 | +#include "driver_wext.h" | |
19 | + | |
20 | +struct wpa_driver_awext_data; | |
21 | + | |
22 | +int wpa_driver_awext_get_ifflags(void *priv, int *flags); | |
23 | +int wpa_driver_awext_set_ifflags(struct wpa_driver_awext_data *drv, int flags); | |
24 | +int wpa_driver_awext_get_bssid(void *priv, u8 *bssid); | |
25 | +int wpa_driver_awext_set_bssid(void *priv, const u8 *bssid); | |
26 | +int wpa_driver_awext_get_ssid(void *priv, u8 *ssid); | |
27 | +int wpa_driver_awext_set_ssid(void *priv, const u8 *ssid, size_t ssid_len); | |
28 | +int wpa_driver_awext_set_freq(void *priv, int freq); | |
29 | +int wpa_driver_awext_set_mode(void *priv, int mode); | |
30 | +int wpa_driver_awext_set_key(void *priv, wpa_alg alg, | |
31 | + const u8 *addr, int key_idx, | |
32 | + int set_tx, const u8 *seq, size_t seq_len, | |
33 | + const u8 *key, size_t key_len); | |
34 | +int wpa_driver_awext_scan(void *priv, const u8 *ssid, size_t ssid_len); | |
35 | +struct wpa_scan_result * wpa_driver_awext_get_scan_results(void *priv); | |
36 | + | |
37 | +void wpa_driver_awext_scan_timeout(void *eloop_ctx, void *timeout_ctx); | |
38 | + | |
39 | +int wpa_driver_awext_alternative_ifindex(struct wpa_driver_awext_data *drv, | |
40 | + const char *ifname); | |
41 | + | |
42 | +void * wpa_driver_awext_init(void *ctx, const char *ifname); | |
43 | +void wpa_driver_awext_deinit(void *priv); | |
44 | + | |
45 | +int wpa_driver_awext_set_operstate(void *priv, int state); | |
46 | +int wpa_driver_awext_get_version(struct wpa_driver_awext_data *drv); | |
47 | + | |
48 | +#ifdef ANDROID | |
49 | +#define WEXT_NUMBER_SCAN_CHANNELS_FCC 11 | |
50 | +#define WEXT_NUMBER_SCAN_CHANNELS_ETSI 13 | |
51 | +#define WEXT_NUMBER_SCAN_CHANNELS_MKK1 14 | |
52 | + | |
53 | +#define WPA_DRIVER_WEXT_WAIT_US 400000 | |
54 | +#define MAX_DRV_CMD_SIZE 248 | |
55 | +#endif | |
56 | + | |
57 | +#endif /* DRIVER_AWEXT_H */ |
@@ -15,6 +15,9 @@ | ||
15 | 15 | #include "includes.h" |
16 | 16 | |
17 | 17 | |
18 | +#ifdef CONFIG_DRIVER_AWEXT | |
19 | +extern struct wpa_driver_ops wpa_driver_awext_ops; /* driver_awext.c */ | |
20 | +#endif /* CONFIG_DRIVER_AWEXT */ | |
18 | 21 | #ifdef CONFIG_DRIVER_WEXT |
19 | 22 | extern struct wpa_driver_ops wpa_driver_wext_ops; /* driver_wext.c */ |
20 | 23 | #endif /* CONFIG_DRIVER_WEXT */ |
@@ -81,6 +84,9 @@ extern struct wpa_driver_ops wpa_driver_custom_ops; | ||
81 | 84 | |
82 | 85 | struct wpa_driver_ops *wpa_supplicant_drivers[] = |
83 | 86 | { |
87 | +#ifdef CONFIG_DRIVER_AWEXT | |
88 | + &wpa_driver_awext_ops, | |
89 | +#endif /* CONFIG_DRIVER_AWEXT */ | |
84 | 90 | #ifdef CONFIG_DRIVER_WEXT |
85 | 91 | &wpa_driver_wext_ops, |
86 | 92 | #endif /* CONFIG_DRIVER_WEXT */ |