]>
Commit | Line | Data |
---|---|---|
b47750be | 1 | # Test cases for automatic channel selection with hostapd |
a1eabc74 | 2 | # Copyright (c) 2013-2015, Jouni Malinen <j@w1.fi> |
b47750be JM |
3 | # |
4 | # This software may be distributed under the terms of the BSD license. | |
5 | # See README for more details. | |
6 | ||
7 | import logging | |
8 | logger = logging.getLogger() | |
ce5d69ac | 9 | import time |
b47750be JM |
10 | |
11 | import hostapd | |
a1eabc74 | 12 | from utils import skip_with_fips |
0860b219 | 13 | from test_ap_ht import clear_scan_cache |
b47750be | 14 | |
19ec6070 JM |
15 | def force_prev_ap_on_24g(ap): |
16 | # For now, make sure the last operating channel was on 2.4 GHz band to get | |
17 | # sufficient survey data from mac80211_hwsim. | |
afc26df2 | 18 | hostapd.add_ap(ap, { "ssid": "open" }) |
19ec6070 | 19 | time.sleep(0.1) |
1728a2e7 | 20 | hostapd.remove_bss(ap) |
19ec6070 JM |
21 | |
22 | def force_prev_ap_on_5g(ap): | |
23 | # For now, make sure the last operating channel was on 5 GHz band to get | |
24 | # sufficient survey data from mac80211_hwsim. | |
afc26df2 JD |
25 | hostapd.add_ap(ap, { "ssid": "open", "hw_mode": "a", |
26 | "channel": "36", "country_code": "US" }) | |
19ec6070 | 27 | time.sleep(0.1) |
1728a2e7 | 28 | hostapd.remove_bss(ap) |
19ec6070 | 29 | |
b47750be JM |
30 | def wait_acs(hapd): |
31 | ev = hapd.wait_event(["ACS-STARTED", "ACS-COMPLETED", "ACS-FAILED", | |
b0159308 | 32 | "AP-ENABLED", "AP-DISABLED"], timeout=5) |
b47750be JM |
33 | if not ev: |
34 | raise Exception("ACS start timed out") | |
35 | if "ACS-STARTED" not in ev: | |
b0159308 | 36 | raise Exception("Unexpected ACS event: " + ev) |
b47750be JM |
37 | |
38 | state = hapd.get_status_field("state") | |
39 | if state != "ACS": | |
40 | raise Exception("Unexpected interface state") | |
41 | ||
b0159308 JM |
42 | ev = hapd.wait_event(["ACS-COMPLETED", "ACS-FAILED", "AP-ENABLED", |
43 | "AP-DISABLED"], timeout=20) | |
b47750be JM |
44 | if not ev: |
45 | raise Exception("ACS timed out") | |
46 | if "ACS-COMPLETED" not in ev: | |
b0159308 | 47 | raise Exception("Unexpected ACS event: " + ev) |
b47750be | 48 | |
b0159308 | 49 | ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=5) |
b47750be JM |
50 | if not ev: |
51 | raise Exception("AP setup timed out") | |
b0159308 JM |
52 | if "AP-ENABLED" not in ev: |
53 | raise Exception("Unexpected ACS event: " + ev) | |
b47750be JM |
54 | |
55 | state = hapd.get_status_field("state") | |
56 | if state != "ENABLED": | |
57 | raise Exception("Unexpected interface state") | |
58 | ||
59 | def test_ap_acs(dev, apdev): | |
60 | """Automatic channel selection""" | |
19ec6070 | 61 | force_prev_ap_on_24g(apdev[0]) |
b47750be JM |
62 | params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678") |
63 | params['channel'] = '0' | |
8b8a1864 | 64 | hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) |
b47750be JM |
65 | wait_acs(hapd) |
66 | ||
67 | freq = hapd.get_status_field("freq") | |
68 | if int(freq) < 2400: | |
69 | raise Exception("Unexpected frequency") | |
70 | ||
71 | dev[0].connect("test-acs", psk="12345678", scan_freq=freq) | |
72 | ||
75e41ab7 JM |
73 | def test_ap_acs_chanlist(dev, apdev): |
74 | """Automatic channel selection with chanlist set""" | |
75 | force_prev_ap_on_24g(apdev[0]) | |
76 | params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678") | |
77 | params['channel'] = '0' | |
78 | params['chanlist'] = '1 6 11' | |
8b8a1864 | 79 | hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) |
75e41ab7 JM |
80 | wait_acs(hapd) |
81 | ||
82 | freq = hapd.get_status_field("freq") | |
83 | if int(freq) < 2400: | |
84 | raise Exception("Unexpected frequency") | |
85 | ||
86 | dev[0].connect("test-acs", psk="12345678", scan_freq=freq) | |
87 | ||
b47750be JM |
88 | def test_ap_multi_bss_acs(dev, apdev): |
89 | """hostapd start with a multi-BSS configuration file using ACS""" | |
a1eabc74 | 90 | skip_with_fips(dev[0]) |
19ec6070 | 91 | force_prev_ap_on_24g(apdev[0]) |
ce5d69ac JM |
92 | |
93 | # start the actual test | |
50e49cd2 | 94 | hapd = hostapd.add_iface(apdev[0], 'multi-bss-acs.conf') |
b47750be JM |
95 | hapd.enable() |
96 | wait_acs(hapd) | |
97 | ||
98 | freq = hapd.get_status_field("freq") | |
99 | if int(freq) < 2400: | |
100 | raise Exception("Unexpected frequency") | |
101 | ||
102 | dev[0].connect("bss-1", key_mgmt="NONE", scan_freq=freq) | |
103 | dev[1].connect("bss-2", psk="12345678", scan_freq=freq) | |
104 | dev[2].connect("bss-3", psk="qwertyuiop", scan_freq=freq) | |
b0159308 JM |
105 | |
106 | def test_ap_acs_40mhz(dev, apdev): | |
107 | """Automatic channel selection for 40 MHz channel""" | |
cb3c0d96 | 108 | clear_scan_cache(apdev[0]) |
19ec6070 | 109 | force_prev_ap_on_24g(apdev[0]) |
b0159308 JM |
110 | params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678") |
111 | params['channel'] = '0' | |
112 | params['ht_capab'] = '[HT40+]' | |
8b8a1864 | 113 | hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) |
b0159308 JM |
114 | wait_acs(hapd) |
115 | ||
116 | freq = hapd.get_status_field("freq") | |
117 | if int(freq) < 2400: | |
118 | raise Exception("Unexpected frequency") | |
119 | sec = hapd.get_status_field("secondary_channel") | |
120 | if int(sec) == 0: | |
121 | raise Exception("Secondary channel not set") | |
122 | ||
123 | dev[0].connect("test-acs", psk="12345678", scan_freq=freq) | |
124 | ||
5f45caae JM |
125 | def test_ap_acs_40mhz_minus(dev, apdev): |
126 | """Automatic channel selection for HT40- channel""" | |
127 | clear_scan_cache(apdev[0]) | |
128 | force_prev_ap_on_24g(apdev[0]) | |
129 | params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678") | |
130 | params['channel'] = '0' | |
131 | params['ht_capab'] = '[HT40-]' | |
132 | params['acs_num_scans'] = '1' | |
133 | params['chanlist'] = '1 11' | |
134 | hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) | |
135 | ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10) | |
136 | if not ev: | |
137 | raise Exception("ACS start timed out") | |
138 | # HT40- is not currently supported in hostapd ACS, so do not try to connect | |
139 | # or verify that this operation succeeded. | |
140 | ||
b0159308 JM |
141 | def test_ap_acs_5ghz(dev, apdev): |
142 | """Automatic channel selection on 5 GHz""" | |
143 | try: | |
9d7fdac5 | 144 | hapd = None |
19ec6070 | 145 | force_prev_ap_on_5g(apdev[0]) |
b0159308 JM |
146 | params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678") |
147 | params['hw_mode'] = 'a' | |
148 | params['channel'] = '0' | |
149 | params['country_code'] = 'US' | |
8b8a1864 | 150 | hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) |
19ec6070 JM |
151 | wait_acs(hapd) |
152 | freq = hapd.get_status_field("freq") | |
153 | if int(freq) < 5000: | |
154 | raise Exception("Unexpected frequency") | |
155 | ||
156 | dev[0].connect("test-acs", psk="12345678", scan_freq=freq) | |
b0159308 JM |
157 | |
158 | finally: | |
9d7fdac5 JM |
159 | dev[0].request("DISCONNECT") |
160 | if hapd: | |
161 | hapd.request("DISABLE") | |
a548c37b | 162 | hostapd.cmd_execute(apdev[0], ['iw', 'reg', 'set', '00']) |
9d7fdac5 | 163 | dev[0].flush_scan_cache() |
b0159308 JM |
164 | |
165 | def test_ap_acs_5ghz_40mhz(dev, apdev): | |
166 | """Automatic channel selection on 5 GHz for 40 MHz channel""" | |
167 | try: | |
9d7fdac5 | 168 | hapd = None |
19ec6070 | 169 | force_prev_ap_on_5g(apdev[0]) |
b0159308 JM |
170 | params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678") |
171 | params['hw_mode'] = 'a' | |
172 | params['channel'] = '0' | |
173 | params['ht_capab'] = '[HT40+]' | |
174 | params['country_code'] = 'US' | |
8b8a1864 | 175 | hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) |
19ec6070 JM |
176 | wait_acs(hapd) |
177 | freq = hapd.get_status_field("freq") | |
178 | if int(freq) < 5000: | |
179 | raise Exception("Unexpected frequency") | |
180 | ||
181 | sec = hapd.get_status_field("secondary_channel") | |
182 | if int(sec) == 0: | |
183 | raise Exception("Secondary channel not set") | |
184 | ||
185 | dev[0].connect("test-acs", psk="12345678", scan_freq=freq) | |
b0159308 JM |
186 | |
187 | finally: | |
9d7fdac5 JM |
188 | dev[0].request("DISCONNECT") |
189 | if hapd: | |
190 | hapd.request("DISABLE") | |
a548c37b | 191 | hostapd.cmd_execute(apdev[0], ['iw', 'reg', 'set', '00']) |
9d7fdac5 | 192 | dev[0].flush_scan_cache() |
b0159308 JM |
193 | |
194 | def test_ap_acs_vht(dev, apdev): | |
195 | """Automatic channel selection for VHT""" | |
196 | try: | |
9d7fdac5 | 197 | hapd = None |
19ec6070 | 198 | force_prev_ap_on_5g(apdev[0]) |
b0159308 JM |
199 | params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678") |
200 | params['hw_mode'] = 'a' | |
201 | params['channel'] = '0' | |
202 | params['ht_capab'] = '[HT40+]' | |
203 | params['country_code'] = 'US' | |
204 | params['ieee80211ac'] = '1' | |
205 | params['vht_oper_chwidth'] = '1' | |
8b8a1864 | 206 | hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) |
19ec6070 JM |
207 | wait_acs(hapd) |
208 | freq = hapd.get_status_field("freq") | |
209 | if int(freq) < 5000: | |
210 | raise Exception("Unexpected frequency") | |
211 | ||
212 | sec = hapd.get_status_field("secondary_channel") | |
213 | if int(sec) == 0: | |
214 | raise Exception("Secondary channel not set") | |
215 | ||
216 | dev[0].connect("test-acs", psk="12345678", scan_freq=freq) | |
b0159308 JM |
217 | |
218 | finally: | |
9d7fdac5 JM |
219 | dev[0].request("DISCONNECT") |
220 | if hapd: | |
221 | hapd.request("DISABLE") | |
a548c37b | 222 | hostapd.cmd_execute(apdev[0], ['iw', 'reg', 'set', '00']) |
9d7fdac5 | 223 | dev[0].flush_scan_cache() |
65013c93 | 224 | |
31b398e0 JM |
225 | def test_ap_acs_vht40(dev, apdev): |
226 | """Automatic channel selection for VHT40""" | |
227 | try: | |
228 | hapd = None | |
229 | force_prev_ap_on_5g(apdev[0]) | |
230 | params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678") | |
231 | params['hw_mode'] = 'a' | |
232 | params['channel'] = '0' | |
233 | params['ht_capab'] = '[HT40+]' | |
234 | params['country_code'] = 'US' | |
235 | params['ieee80211ac'] = '1' | |
236 | params['vht_oper_chwidth'] = '0' | |
237 | params['acs_num_scans'] = '1' | |
238 | params['chanlist'] = '36 149' | |
239 | hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) | |
240 | wait_acs(hapd) | |
241 | freq = hapd.get_status_field("freq") | |
242 | if int(freq) < 5000: | |
243 | raise Exception("Unexpected frequency") | |
244 | ||
245 | sec = hapd.get_status_field("secondary_channel") | |
246 | if int(sec) == 0: | |
247 | raise Exception("Secondary channel not set") | |
248 | ||
249 | dev[0].connect("test-acs", psk="12345678", scan_freq=freq) | |
250 | ||
251 | finally: | |
252 | dev[0].request("DISCONNECT") | |
253 | if hapd: | |
254 | hapd.request("DISABLE") | |
255 | hostapd.cmd_execute(apdev[0], ['iw', 'reg', 'set', '00']) | |
256 | dev[0].flush_scan_cache() | |
257 | ||
65013c93 JM |
258 | def test_ap_acs_bias(dev, apdev): |
259 | """Automatic channel selection with bias values""" | |
19ec6070 | 260 | force_prev_ap_on_24g(apdev[0]) |
65013c93 JM |
261 | params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678") |
262 | params['channel'] = '0' | |
263 | params['acs_chan_bias'] = '1:0.8 3:1.2 6:0.7 11:0.8' | |
8b8a1864 | 264 | hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) |
65013c93 JM |
265 | wait_acs(hapd) |
266 | ||
267 | freq = hapd.get_status_field("freq") | |
268 | if int(freq) < 2400: | |
269 | raise Exception("Unexpected frequency") | |
270 | ||
271 | dev[0].connect("test-acs", psk="12345678", scan_freq=freq) | |
5f37d1b3 JM |
272 | |
273 | def test_ap_acs_survey(dev, apdev): | |
274 | """Automatic channel selection using acs_survey parameter""" | |
275 | force_prev_ap_on_24g(apdev[0]) | |
276 | params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678") | |
277 | params['channel'] = 'acs_survey' | |
278 | params['acs_num_scans'] = '1' | |
279 | hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) | |
280 | wait_acs(hapd) | |
281 | ||
282 | freq = hapd.get_status_field("freq") | |
283 | if int(freq) < 2400: | |
284 | raise Exception("Unexpected frequency") | |
285 | ||
286 | dev[0].connect("test-acs", psk="12345678", scan_freq=freq) |