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