]>
Commit | Line | Data |
---|---|---|
aea855d7 JM |
1 | /* |
2 | * Common driver-related functions | |
68855672 | 3 | * Copyright (c) 2003-2017, Jouni Malinen <j@w1.fi> |
aea855d7 | 4 | * |
0f3d578e JM |
5 | * This software may be distributed under the terms of the BSD license. |
6 | * See README for more details. | |
aea855d7 JM |
7 | */ |
8 | ||
9 | #include "includes.h" | |
10 | #include "utils/common.h" | |
11 | #include "driver.h" | |
12 | ||
13 | void wpa_scan_results_free(struct wpa_scan_results *res) | |
14 | { | |
15 | size_t i; | |
16 | ||
17 | if (res == NULL) | |
18 | return; | |
19 | ||
20 | for (i = 0; i < res->num; i++) | |
21 | os_free(res->res[i]); | |
22 | os_free(res->res); | |
23 | os_free(res); | |
24 | } | |
6c3771d7 BG |
25 | |
26 | ||
27 | const char * event_to_string(enum wpa_event_type event) | |
28 | { | |
9d77a392 | 29 | #define E2S(n) case EVENT_ ## n: return #n |
6c3771d7 | 30 | switch (event) { |
9d77a392 JM |
31 | E2S(ASSOC); |
32 | E2S(DISASSOC); | |
33 | E2S(MICHAEL_MIC_FAILURE); | |
34 | E2S(SCAN_RESULTS); | |
35 | E2S(ASSOCINFO); | |
36 | E2S(INTERFACE_STATUS); | |
37 | E2S(PMKID_CANDIDATE); | |
9d77a392 JM |
38 | E2S(TDLS); |
39 | E2S(FT_RESPONSE); | |
40 | E2S(IBSS_RSN_START); | |
41 | E2S(AUTH); | |
42 | E2S(DEAUTH); | |
43 | E2S(ASSOC_REJECT); | |
44 | E2S(AUTH_TIMED_OUT); | |
45 | E2S(ASSOC_TIMED_OUT); | |
9d77a392 JM |
46 | E2S(WPS_BUTTON_PUSHED); |
47 | E2S(TX_STATUS); | |
48 | E2S(RX_FROM_UNKNOWN); | |
49 | E2S(RX_MGMT); | |
9d77a392 JM |
50 | E2S(REMAIN_ON_CHANNEL); |
51 | E2S(CANCEL_REMAIN_ON_CHANNEL); | |
9d77a392 JM |
52 | E2S(RX_PROBE_REQ); |
53 | E2S(NEW_STA); | |
54 | E2S(EAPOL_RX); | |
55 | E2S(SIGNAL_CHANGE); | |
56 | E2S(INTERFACE_ENABLED); | |
57 | E2S(INTERFACE_DISABLED); | |
58 | E2S(CHANNEL_LIST_CHANGED); | |
59 | E2S(INTERFACE_UNAVAILABLE); | |
60 | E2S(BEST_CHANNEL); | |
61 | E2S(UNPROT_DEAUTH); | |
62 | E2S(UNPROT_DISASSOC); | |
63 | E2S(STATION_LOW_ACK); | |
9d77a392 JM |
64 | E2S(IBSS_PEER_LOST); |
65 | E2S(DRIVER_GTK_REKEY); | |
66 | E2S(SCHED_SCAN_STOPPED); | |
67 | E2S(DRIVER_CLIENT_POLL_OK); | |
dd840f79 | 68 | E2S(EAPOL_TX_STATUS); |
1b487b8b | 69 | E2S(CH_SWITCH); |
95f556f3 | 70 | E2S(CH_SWITCH_STARTED); |
a884be9d | 71 | E2S(WNM); |
3140803b | 72 | E2S(CONNECT_FAILED_REASON); |
04be54fa SW |
73 | E2S(DFS_RADAR_DETECTED); |
74 | E2S(DFS_CAC_FINISHED); | |
75 | E2S(DFS_CAC_ABORTED); | |
76 | E2S(DFS_NOP_FINISHED); | |
0185007c | 77 | E2S(SURVEY); |
a5f40eff | 78 | E2S(SCAN_STARTED); |
253f2e37 | 79 | E2S(AVOID_FREQUENCIES); |
a52024c9 | 80 | E2S(NEW_PEER_CANDIDATE); |
16689c7c | 81 | E2S(ACS_CHANNEL_SELECTED); |
480994da | 82 | E2S(DFS_CAC_STARTED); |
a6f5b193 | 83 | E2S(P2P_LO_STOP); |
68855672 | 84 | E2S(BEACON_LOSS); |
62c8c7f7 | 85 | E2S(DFS_PRE_CAC_EXPIRED); |
ba71cb82 | 86 | E2S(EXTERNAL_AUTH); |
0a20bd7d | 87 | E2S(PORT_AUTHORIZED); |
e8ada160 | 88 | E2S(STATION_OPMODE_CHANGED); |
77a020a1 | 89 | E2S(INTERFACE_MAC_CHANGED); |
1952b626 | 90 | E2S(WDS_STA_INTERFACE_STATUS); |
6c3771d7 BG |
91 | } |
92 | ||
93 | return "UNKNOWN"; | |
9d77a392 | 94 | #undef E2S |
6c3771d7 | 95 | } |
7a4a93b9 DW |
96 | |
97 | ||
98 | const char * channel_width_to_string(enum chan_width width) | |
99 | { | |
100 | switch (width) { | |
101 | case CHAN_WIDTH_20_NOHT: | |
102 | return "20 MHz (no HT)"; | |
103 | case CHAN_WIDTH_20: | |
104 | return "20 MHz"; | |
105 | case CHAN_WIDTH_40: | |
106 | return "40 MHz"; | |
107 | case CHAN_WIDTH_80: | |
108 | return "80 MHz"; | |
109 | case CHAN_WIDTH_80P80: | |
110 | return "80+80 MHz"; | |
111 | case CHAN_WIDTH_160: | |
112 | return "160 MHz"; | |
113 | default: | |
114 | return "unknown"; | |
115 | } | |
116 | } | |
3eafc494 JM |
117 | |
118 | ||
d706e0d7 MV |
119 | int channel_width_to_int(enum chan_width width) |
120 | { | |
121 | switch (width) { | |
122 | case CHAN_WIDTH_20_NOHT: | |
123 | case CHAN_WIDTH_20: | |
124 | return 20; | |
125 | case CHAN_WIDTH_40: | |
126 | return 40; | |
127 | case CHAN_WIDTH_80: | |
128 | return 80; | |
129 | case CHAN_WIDTH_80P80: | |
130 | case CHAN_WIDTH_160: | |
131 | return 160; | |
132 | default: | |
133 | return 0; | |
134 | } | |
135 | } | |
136 | ||
137 | ||
3eafc494 JM |
138 | int ht_supported(const struct hostapd_hw_modes *mode) |
139 | { | |
140 | if (!(mode->flags & HOSTAPD_MODE_FLAG_HT_INFO_KNOWN)) { | |
141 | /* | |
142 | * The driver did not indicate whether it supports HT. Assume | |
143 | * it does to avoid connection issues. | |
144 | */ | |
145 | return 1; | |
146 | } | |
147 | ||
148 | /* | |
149 | * IEEE Std 802.11n-2009 20.1.1: | |
150 | * An HT non-AP STA shall support all EQM rates for one spatial stream. | |
151 | */ | |
152 | return mode->mcs_set[0] == 0xff; | |
153 | } | |
154 | ||
155 | ||
156 | int vht_supported(const struct hostapd_hw_modes *mode) | |
157 | { | |
158 | if (!(mode->flags & HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN)) { | |
159 | /* | |
160 | * The driver did not indicate whether it supports VHT. Assume | |
161 | * it does to avoid connection issues. | |
162 | */ | |
163 | return 1; | |
164 | } | |
165 | ||
166 | /* | |
167 | * A VHT non-AP STA shall support MCS 0-7 for one spatial stream. | |
168 | * TODO: Verify if this complies with the standard | |
169 | */ | |
170 | return (mode->vht_mcs_set[0] & 0x3) != 3; | |
171 | } | |
88cb27c7 DS |
172 | |
173 | ||
174 | static int wpa_check_wowlan_trigger(const char *start, const char *trigger, | |
175 | int capa_trigger, u8 *param_trigger) | |
176 | { | |
177 | if (os_strcmp(start, trigger) != 0) | |
178 | return 0; | |
179 | if (!capa_trigger) | |
180 | return 0; | |
181 | ||
182 | *param_trigger = 1; | |
183 | return 1; | |
184 | } | |
185 | ||
186 | ||
187 | struct wowlan_triggers * | |
188 | wpa_get_wowlan_triggers(const char *wowlan_triggers, | |
189 | const struct wpa_driver_capa *capa) | |
190 | { | |
191 | struct wowlan_triggers *triggers; | |
192 | char *start, *end, *buf; | |
193 | int last; | |
194 | ||
195 | if (!wowlan_triggers) | |
196 | return NULL; | |
197 | ||
198 | buf = os_strdup(wowlan_triggers); | |
199 | if (buf == NULL) | |
200 | return NULL; | |
201 | ||
202 | triggers = os_zalloc(sizeof(*triggers)); | |
203 | if (triggers == NULL) | |
204 | goto out; | |
205 | ||
206 | #define CHECK_TRIGGER(trigger) \ | |
207 | wpa_check_wowlan_trigger(start, #trigger, \ | |
208 | capa->wowlan_triggers.trigger, \ | |
209 | &triggers->trigger) | |
210 | ||
211 | start = buf; | |
212 | while (*start != '\0') { | |
640b0b93 | 213 | while (isblank((unsigned char) *start)) |
88cb27c7 DS |
214 | start++; |
215 | if (*start == '\0') | |
216 | break; | |
217 | end = start; | |
640b0b93 | 218 | while (!isblank((unsigned char) *end) && *end != '\0') |
88cb27c7 DS |
219 | end++; |
220 | last = *end == '\0'; | |
221 | *end = '\0'; | |
222 | ||
223 | if (!CHECK_TRIGGER(any) && | |
224 | !CHECK_TRIGGER(disconnect) && | |
225 | !CHECK_TRIGGER(magic_pkt) && | |
226 | !CHECK_TRIGGER(gtk_rekey_failure) && | |
227 | !CHECK_TRIGGER(eap_identity_req) && | |
228 | !CHECK_TRIGGER(four_way_handshake) && | |
229 | !CHECK_TRIGGER(rfkill_release)) { | |
230 | wpa_printf(MSG_DEBUG, | |
231 | "Unknown/unsupported wowlan trigger '%s'", | |
232 | start); | |
233 | os_free(triggers); | |
234 | triggers = NULL; | |
235 | goto out; | |
236 | } | |
237 | ||
238 | if (last) | |
239 | break; | |
240 | start = end + 1; | |
241 | } | |
242 | #undef CHECK_TRIGGER | |
243 | ||
244 | out: | |
245 | os_free(buf); | |
246 | return triggers; | |
247 | } | |
4d7aab78 EL |
248 | |
249 | ||
250 | const char * driver_flag_to_string(u64 flag) | |
251 | { | |
252 | #define DF2S(x) case WPA_DRIVER_FLAGS_ ## x: return #x | |
253 | switch (flag) { | |
254 | DF2S(DRIVER_IE); | |
255 | DF2S(SET_KEYS_AFTER_ASSOC); | |
256 | DF2S(DFS_OFFLOAD); | |
436ee2fd AS |
257 | DF2S(4WAY_HANDSHAKE_PSK); |
258 | DF2S(4WAY_HANDSHAKE_8021X); | |
4d7aab78 EL |
259 | DF2S(WIRED); |
260 | DF2S(SME); | |
261 | DF2S(AP); | |
262 | DF2S(SET_KEYS_AFTER_ASSOC_DONE); | |
263 | DF2S(HT_2040_COEX); | |
264 | DF2S(P2P_CONCURRENT); | |
265 | DF2S(P2P_DEDICATED_INTERFACE); | |
266 | DF2S(P2P_CAPABLE); | |
267 | DF2S(AP_TEARDOWN_SUPPORT); | |
268 | DF2S(P2P_MGMT_AND_NON_P2P); | |
269 | DF2S(SANE_ERROR_CODES); | |
270 | DF2S(OFFCHANNEL_TX); | |
271 | DF2S(EAPOL_TX_STATUS); | |
272 | DF2S(DEAUTH_TX_STATUS); | |
273 | DF2S(BSS_SELECTION); | |
274 | DF2S(TDLS_SUPPORT); | |
275 | DF2S(TDLS_EXTERNAL_SETUP); | |
276 | DF2S(PROBE_RESP_OFFLOAD); | |
277 | DF2S(AP_UAPSD); | |
278 | DF2S(INACTIVITY_TIMER); | |
279 | DF2S(AP_MLME); | |
280 | DF2S(SAE); | |
281 | DF2S(OBSS_SCAN); | |
282 | DF2S(IBSS); | |
283 | DF2S(RADAR); | |
284 | DF2S(DEDICATED_P2P_DEVICE); | |
285 | DF2S(QOS_MAPPING); | |
286 | DF2S(AP_CSA); | |
287 | DF2S(MESH); | |
288 | DF2S(ACS_OFFLOAD); | |
289 | DF2S(KEY_MGMT_OFFLOAD); | |
290 | DF2S(TDLS_CHANNEL_SWITCH); | |
291 | DF2S(HT_IBSS); | |
292 | DF2S(VHT_IBSS); | |
293 | DF2S(SUPPORT_HW_MODE_ANY); | |
294 | DF2S(OFFCHANNEL_SIMULTANEOUS); | |
295 | DF2S(FULL_AP_CLIENT_STATE); | |
296 | DF2S(P2P_LISTEN_OFFLOAD); | |
8518326b MK |
297 | DF2S(SUPPORT_FILS); |
298 | DF2S(BEACON_RATE_LEGACY); | |
299 | DF2S(BEACON_RATE_HT); | |
300 | DF2S(BEACON_RATE_VHT); | |
301 | DF2S(MGMT_TX_RANDOM_TA); | |
302 | DF2S(MGMT_TX_RANDOM_TA_CONNECTED); | |
303 | DF2S(SCHED_SCAN_RELATIVE_RSSI); | |
304 | DF2S(HE_CAPABILITIES); | |
305 | DF2S(FILS_SK_OFFLOAD); | |
306 | DF2S(OCE_STA); | |
307 | DF2S(OCE_AP); | |
308 | DF2S(OCE_STA_CFON); | |
309 | DF2S(MFP_OPTIONAL); | |
4d7aab78 EL |
310 | } |
311 | return "UNKNOWN"; | |
312 | #undef DF2S | |
313 | } |