Line data Source code
1 : /*
2 : * Common driver-related functions
3 : * Copyright (c) 2003-2011, 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 "includes.h"
10 : #include "utils/common.h"
11 : #include "driver.h"
12 :
13 2827 : void wpa_scan_results_free(struct wpa_scan_results *res)
14 : {
15 : size_t i;
16 :
17 2827 : if (res == NULL)
18 2827 : return;
19 :
20 6571 : for (i = 0; i < res->num; i++)
21 3744 : os_free(res->res[i]);
22 2827 : os_free(res->res);
23 2827 : os_free(res);
24 : }
25 :
26 :
27 68800 : const char * event_to_string(enum wpa_event_type event)
28 : {
29 : #define E2S(n) case EVENT_ ## n: return #n
30 68800 : switch (event) {
31 2477 : E2S(ASSOC);
32 13 : E2S(DISASSOC);
33 6 : E2S(MICHAEL_MIC_FAILURE);
34 2830 : E2S(SCAN_RESULTS);
35 15 : E2S(ASSOCINFO);
36 253 : E2S(INTERFACE_STATUS);
37 0 : E2S(PMKID_CANDIDATE);
38 0 : E2S(STKSTART);
39 0 : E2S(TDLS);
40 113 : E2S(FT_RESPONSE);
41 21 : E2S(IBSS_RSN_START);
42 2380 : E2S(AUTH);
43 2382 : E2S(DEAUTH);
44 15 : E2S(ASSOC_REJECT);
45 21 : E2S(AUTH_TIMED_OUT);
46 1 : E2S(ASSOC_TIMED_OUT);
47 0 : E2S(WPS_BUTTON_PUSHED);
48 8237 : E2S(TX_STATUS);
49 32 : E2S(RX_FROM_UNKNOWN);
50 19871 : E2S(RX_MGMT);
51 1516 : E2S(REMAIN_ON_CHANNEL);
52 1429 : E2S(CANCEL_REMAIN_ON_CHANNEL);
53 0 : E2S(RX_PROBE_REQ);
54 0 : E2S(NEW_STA);
55 6584 : E2S(EAPOL_RX);
56 5 : E2S(SIGNAL_CHANGE);
57 14 : E2S(INTERFACE_ENABLED);
58 28 : E2S(INTERFACE_DISABLED);
59 8362 : E2S(CHANNEL_LIST_CHANGED);
60 6 : E2S(INTERFACE_UNAVAILABLE);
61 0 : E2S(BEST_CHANNEL);
62 22 : E2S(UNPROT_DEAUTH);
63 19 : E2S(UNPROT_DISASSOC);
64 0 : E2S(STATION_LOW_ACK);
65 2 : E2S(IBSS_PEER_LOST);
66 0 : E2S(DRIVER_GTK_REKEY);
67 0 : E2S(SCHED_SCAN_STOPPED);
68 1 : E2S(DRIVER_CLIENT_POLL_OK);
69 9154 : E2S(EAPOL_TX_STATUS);
70 35 : E2S(CH_SWITCH);
71 0 : E2S(WNM);
72 0 : E2S(CONNECT_FAILED_REASON);
73 31 : E2S(DFS_RADAR_DETECTED);
74 5 : E2S(DFS_CAC_FINISHED);
75 6 : E2S(DFS_CAC_ABORTED);
76 0 : E2S(DFS_NOP_FINISHED);
77 40 : E2S(SURVEY);
78 2820 : E2S(SCAN_STARTED);
79 4 : E2S(AVOID_FREQUENCIES);
80 50 : E2S(NEW_PEER_CANDIDATE);
81 0 : E2S(ACS_CHANNEL_SELECTED);
82 : }
83 :
84 0 : return "UNKNOWN";
85 : #undef E2S
86 : }
87 :
88 :
89 61 : const char * channel_width_to_string(enum chan_width width)
90 : {
91 61 : switch (width) {
92 : case CHAN_WIDTH_20_NOHT:
93 12 : return "20 MHz (no HT)";
94 : case CHAN_WIDTH_20:
95 38 : return "20 MHz";
96 : case CHAN_WIDTH_40:
97 7 : return "40 MHz";
98 : case CHAN_WIDTH_80:
99 1 : return "80 MHz";
100 : case CHAN_WIDTH_80P80:
101 1 : return "80+80 MHz";
102 : case CHAN_WIDTH_160:
103 2 : return "160 MHz";
104 : default:
105 0 : return "unknown";
106 : }
107 : }
108 :
109 :
110 51 : int ht_supported(const struct hostapd_hw_modes *mode)
111 : {
112 51 : if (!(mode->flags & HOSTAPD_MODE_FLAG_HT_INFO_KNOWN)) {
113 : /*
114 : * The driver did not indicate whether it supports HT. Assume
115 : * it does to avoid connection issues.
116 : */
117 0 : return 1;
118 : }
119 :
120 : /*
121 : * IEEE Std 802.11n-2009 20.1.1:
122 : * An HT non-AP STA shall support all EQM rates for one spatial stream.
123 : */
124 51 : return mode->mcs_set[0] == 0xff;
125 : }
126 :
127 :
128 3 : int vht_supported(const struct hostapd_hw_modes *mode)
129 : {
130 3 : if (!(mode->flags & HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN)) {
131 : /*
132 : * The driver did not indicate whether it supports VHT. Assume
133 : * it does to avoid connection issues.
134 : */
135 0 : return 1;
136 : }
137 :
138 : /*
139 : * A VHT non-AP STA shall support MCS 0-7 for one spatial stream.
140 : * TODO: Verify if this complies with the standard
141 : */
142 3 : return (mode->vht_mcs_set[0] & 0x3) != 3;
143 : }
144 :
145 :
146 0 : static int wpa_check_wowlan_trigger(const char *start, const char *trigger,
147 : int capa_trigger, u8 *param_trigger)
148 : {
149 0 : if (os_strcmp(start, trigger) != 0)
150 0 : return 0;
151 0 : if (!capa_trigger)
152 0 : return 0;
153 :
154 0 : *param_trigger = 1;
155 0 : return 1;
156 : }
157 :
158 :
159 : struct wowlan_triggers *
160 949 : wpa_get_wowlan_triggers(const char *wowlan_triggers,
161 : const struct wpa_driver_capa *capa)
162 : {
163 : struct wowlan_triggers *triggers;
164 : char *start, *end, *buf;
165 : int last;
166 :
167 949 : if (!wowlan_triggers)
168 949 : return NULL;
169 :
170 0 : buf = os_strdup(wowlan_triggers);
171 0 : if (buf == NULL)
172 0 : return NULL;
173 :
174 0 : triggers = os_zalloc(sizeof(*triggers));
175 0 : if (triggers == NULL)
176 0 : goto out;
177 :
178 : #define CHECK_TRIGGER(trigger) \
179 : wpa_check_wowlan_trigger(start, #trigger, \
180 : capa->wowlan_triggers.trigger, \
181 : &triggers->trigger)
182 :
183 0 : start = buf;
184 0 : while (*start != '\0') {
185 0 : while (isblank(*start))
186 0 : start++;
187 0 : if (*start == '\0')
188 0 : break;
189 0 : end = start;
190 0 : while (!isblank(*end) && *end != '\0')
191 0 : end++;
192 0 : last = *end == '\0';
193 0 : *end = '\0';
194 :
195 0 : if (!CHECK_TRIGGER(any) &&
196 0 : !CHECK_TRIGGER(disconnect) &&
197 0 : !CHECK_TRIGGER(magic_pkt) &&
198 0 : !CHECK_TRIGGER(gtk_rekey_failure) &&
199 0 : !CHECK_TRIGGER(eap_identity_req) &&
200 0 : !CHECK_TRIGGER(four_way_handshake) &&
201 0 : !CHECK_TRIGGER(rfkill_release)) {
202 0 : wpa_printf(MSG_DEBUG,
203 : "Unknown/unsupported wowlan trigger '%s'",
204 : start);
205 0 : os_free(triggers);
206 0 : triggers = NULL;
207 0 : goto out;
208 : }
209 :
210 0 : if (last)
211 0 : break;
212 0 : start = end + 1;
213 : }
214 : #undef CHECK_TRIGGER
215 :
216 : out:
217 0 : os_free(buf);
218 0 : return triggers;
219 : }
|