]> git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_ap_acs.py
3cade3ca4ef82b57739f63e69ed2d83981d5dc62
[thirdparty/hostap.git] / tests / hwsim / test_ap_acs.py
1 # Test cases for automatic channel selection with hostapd
2 # Copyright (c) 2013-2018, Jouni Malinen <j@w1.fi>
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()
9 import time
10
11 import hostapd
12 from utils import skip_with_fips, alloc_fail, fail_test, HwsimSkip, clear_regdom
13 from test_ap_ht import clear_scan_cache
14 from test_dfs import wait_dfs_event
15
16 def force_prev_ap_on_24g(ap):
17 # For now, make sure the last operating channel was on 2.4 GHz band to get
18 # sufficient survey data from mac80211_hwsim.
19 hostapd.add_ap(ap, {"ssid": "open"})
20 time.sleep(0.1)
21 hostapd.remove_bss(ap)
22
23 def force_prev_ap_on_5g(ap):
24 # For now, make sure the last operating channel was on 5 GHz band to get
25 # sufficient survey data from mac80211_hwsim.
26 hostapd.add_ap(ap, {"ssid": "open", "hw_mode": "a",
27 "channel": "36", "country_code": "US"})
28 time.sleep(0.1)
29 hostapd.remove_bss(ap)
30
31 def wait_acs(hapd, return_after_acs=False):
32 ev = hapd.wait_event(["ACS-STARTED", "ACS-COMPLETED", "ACS-FAILED",
33 "AP-ENABLED", "AP-DISABLED"], timeout=5)
34 if not ev:
35 raise Exception("ACS start timed out")
36 if "ACS-STARTED" not in ev:
37 raise Exception("Unexpected ACS event: " + ev)
38
39 state = hapd.get_status_field("state")
40 if state != "ACS":
41 raise Exception("Unexpected interface state")
42
43 ev = hapd.wait_event(["ACS-COMPLETED", "ACS-FAILED", "AP-ENABLED",
44 "AP-DISABLED"], timeout=20)
45 if not ev:
46 raise Exception("ACS timed out")
47 if "ACS-COMPLETED" not in ev:
48 raise Exception("Unexpected ACS event: " + ev)
49
50 if return_after_acs:
51 return
52
53 ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=5)
54 if not ev:
55 raise Exception("AP setup timed out")
56 if "AP-ENABLED" not in ev:
57 raise Exception("Unexpected ACS event: " + ev)
58
59 state = hapd.get_status_field("state")
60 if state != "ENABLED":
61 raise Exception("Unexpected interface state")
62
63 def test_ap_acs(dev, apdev):
64 """Automatic channel selection"""
65 force_prev_ap_on_24g(apdev[0])
66 params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
67 params['channel'] = '0'
68 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
69 wait_acs(hapd)
70
71 freq = hapd.get_status_field("freq")
72 if int(freq) < 2400:
73 raise Exception("Unexpected frequency")
74
75 dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
76
77 def test_ap_acs_chanlist(dev, apdev):
78 """Automatic channel selection with chanlist set"""
79 force_prev_ap_on_24g(apdev[0])
80 params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
81 params['channel'] = '0'
82 params['chanlist'] = '1 6 11'
83 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
84 wait_acs(hapd)
85
86 freq = hapd.get_status_field("freq")
87 if int(freq) < 2400:
88 raise Exception("Unexpected frequency")
89
90 dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
91
92 def test_ap_acs_freqlist(dev, apdev):
93 """Automatic channel selection with freqlist set"""
94 force_prev_ap_on_24g(apdev[0])
95 params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
96 params['channel'] = '0'
97 params['freqlist'] = '2412 2437 2462'
98 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
99 wait_acs(hapd)
100
101 freq = int(hapd.get_status_field("freq"))
102 if freq not in [2412, 2437, 2462]:
103 raise Exception("Unexpected frequency: " + freq)
104
105 dev[0].connect("test-acs", psk="12345678", scan_freq=str(freq))
106
107 def test_ap_acs_invalid_chanlist(dev, apdev):
108 """Automatic channel selection with invalid chanlist"""
109 force_prev_ap_on_24g(apdev[0])
110 params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
111 params['channel'] = '0'
112 params['chanlist'] = '15-18'
113 hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
114 res = hapd.request("ENABLE")
115 if "OK" in res:
116 raise Exception("ENABLE command succeeded unexpectedly")
117
118 def test_ap_multi_bss_acs(dev, apdev):
119 """hostapd start with a multi-BSS configuration file using ACS"""
120 skip_with_fips(dev[0])
121 force_prev_ap_on_24g(apdev[0])
122
123 # start the actual test
124 hapd = hostapd.add_iface(apdev[0], 'multi-bss-acs.conf')
125 hapd.enable()
126 wait_acs(hapd)
127
128 freq = hapd.get_status_field("freq")
129 if int(freq) < 2400:
130 raise Exception("Unexpected frequency")
131
132 dev[0].connect("bss-1", key_mgmt="NONE", scan_freq=freq)
133 dev[1].connect("bss-2", psk="12345678", scan_freq=freq)
134 dev[2].connect("bss-3", psk="qwertyuiop", scan_freq=freq)
135
136 def test_ap_acs_40mhz(dev, apdev):
137 """Automatic channel selection for 40 MHz channel"""
138 clear_scan_cache(apdev[0])
139 force_prev_ap_on_24g(apdev[0])
140 params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
141 params['channel'] = '0'
142 params['ht_capab'] = '[HT40+]'
143 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
144 wait_acs(hapd)
145
146 freq = hapd.get_status_field("freq")
147 if int(freq) < 2400:
148 raise Exception("Unexpected frequency")
149 sec = hapd.get_status_field("secondary_channel")
150 if int(sec) == 0:
151 raise Exception("Secondary channel not set")
152
153 dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
154
155 def test_ap_acs_40mhz_minus(dev, apdev):
156 """Automatic channel selection for HT40- channel"""
157 clear_scan_cache(apdev[0])
158 force_prev_ap_on_24g(apdev[0])
159 params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
160 params['channel'] = '0'
161 params['ht_capab'] = '[HT40-]'
162 params['acs_num_scans'] = '1'
163 params['chanlist'] = '1 11'
164 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
165 ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10)
166 if not ev:
167 raise Exception("ACS start timed out")
168 # HT40- is not currently supported in hostapd ACS, so do not try to connect
169 # or verify that this operation succeeded.
170
171 def test_ap_acs_5ghz(dev, apdev):
172 """Automatic channel selection on 5 GHz"""
173 try:
174 hapd = None
175 force_prev_ap_on_5g(apdev[0])
176 params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
177 params['hw_mode'] = 'a'
178 params['channel'] = '0'
179 params['country_code'] = 'US'
180 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
181 wait_acs(hapd)
182 freq = hapd.get_status_field("freq")
183 if int(freq) < 5000:
184 raise Exception("Unexpected frequency")
185
186 dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
187 dev[0].wait_regdom(country_ie=True)
188 finally:
189 clear_regdom(hapd, dev)
190
191 def test_ap_acs_5ghz_40mhz(dev, apdev):
192 """Automatic channel selection on 5 GHz for 40 MHz channel"""
193 try:
194 hapd = None
195 force_prev_ap_on_5g(apdev[0])
196 params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
197 params['hw_mode'] = 'a'
198 params['channel'] = '0'
199 params['ht_capab'] = '[HT40+]'
200 params['country_code'] = 'US'
201 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
202 wait_acs(hapd)
203 freq = hapd.get_status_field("freq")
204 if int(freq) < 5000:
205 raise Exception("Unexpected frequency")
206
207 sec = hapd.get_status_field("secondary_channel")
208 if int(sec) == 0:
209 raise Exception("Secondary channel not set")
210
211 dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
212 dev[0].wait_regdom(country_ie=True)
213 finally:
214 clear_regdom(hapd, dev)
215
216 def test_ap_acs_vht(dev, apdev):
217 """Automatic channel selection for VHT"""
218 try:
219 hapd = None
220 force_prev_ap_on_5g(apdev[0])
221 params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
222 params['hw_mode'] = 'a'
223 params['channel'] = '0'
224 params['ht_capab'] = '[HT40+]'
225 params['country_code'] = 'US'
226 params['ieee80211ac'] = '1'
227 params['vht_oper_chwidth'] = '1'
228 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
229 wait_acs(hapd)
230 freq = hapd.get_status_field("freq")
231 if int(freq) < 5000:
232 raise Exception("Unexpected frequency")
233
234 sec = hapd.get_status_field("secondary_channel")
235 if int(sec) == 0:
236 raise Exception("Secondary channel not set")
237
238 dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
239 dev[0].wait_regdom(country_ie=True)
240 finally:
241 clear_regdom(hapd, dev)
242
243 def test_ap_acs_vht40(dev, apdev):
244 """Automatic channel selection for VHT40"""
245 try:
246 hapd = None
247 force_prev_ap_on_5g(apdev[0])
248 params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
249 params['hw_mode'] = 'a'
250 params['channel'] = '0'
251 params['ht_capab'] = '[HT40+]'
252 params['country_code'] = 'US'
253 params['ieee80211ac'] = '1'
254 params['vht_oper_chwidth'] = '0'
255 params['acs_num_scans'] = '1'
256 params['chanlist'] = '36 149'
257 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
258 wait_acs(hapd)
259 freq = hapd.get_status_field("freq")
260 if int(freq) < 5000:
261 raise Exception("Unexpected frequency")
262
263 sec = hapd.get_status_field("secondary_channel")
264 if int(sec) == 0:
265 raise Exception("Secondary channel not set")
266
267 dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
268 dev[0].wait_regdom(country_ie=True)
269 finally:
270 clear_regdom(hapd, dev)
271
272 def test_ap_acs_vht160(dev, apdev):
273 """Automatic channel selection for VHT160"""
274 try:
275 hapd = None
276 force_prev_ap_on_5g(apdev[0])
277 params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
278 params['hw_mode'] = 'a'
279 params['channel'] = '0'
280 params['ht_capab'] = '[HT40+]'
281 params['country_code'] = 'ZA'
282 params['ieee80211ac'] = '1'
283 params['vht_oper_chwidth'] = '2'
284 params['ieee80211d'] = '1'
285 params['ieee80211h'] = '1'
286 params['chanlist'] = '100'
287 params['acs_num_scans'] = '1'
288 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
289 ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10)
290 if not ev:
291 raise Exception("ACS start timed out")
292 # VHT160 is not currently supported in hostapd ACS, so do not try to
293 # enforce successful AP start.
294 if "AP-ENABLED" in ev:
295 freq = hapd.get_status_field("freq")
296 if int(freq) < 5000:
297 raise Exception("Unexpected frequency")
298 dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
299 dev[0].wait_regdom(country_ie=True)
300 finally:
301 clear_regdom(hapd, dev)
302
303 def test_ap_acs_vht160_scan_disable(dev, apdev):
304 """Automatic channel selection for VHT160 and DISABLE during scan"""
305 force_prev_ap_on_5g(apdev[0])
306 params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
307 params['hw_mode'] = 'a'
308 params['channel'] = '0'
309 params['ht_capab'] = '[HT40+]'
310 params['country_code'] = 'ZA'
311 params['ieee80211ac'] = '1'
312 params['vht_oper_chwidth'] = '2'
313 params["vht_oper_centr_freq_seg0_idx"] = "114"
314 params['ieee80211d'] = '1'
315 params['ieee80211h'] = '1'
316 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
317 time.sleep(3)
318 clear_regdom(hapd, dev)
319
320 def test_ap_acs_bias(dev, apdev):
321 """Automatic channel selection with bias values"""
322 force_prev_ap_on_24g(apdev[0])
323 params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
324 params['channel'] = '0'
325 params['acs_chan_bias'] = '1:0.8 3:1.2 6:0.7 11:0.8'
326 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
327 wait_acs(hapd)
328
329 freq = hapd.get_status_field("freq")
330 if int(freq) < 2400:
331 raise Exception("Unexpected frequency")
332
333 dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
334
335 def test_ap_acs_survey(dev, apdev):
336 """Automatic channel selection using acs_survey parameter"""
337 force_prev_ap_on_24g(apdev[0])
338 params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
339 params['channel'] = 'acs_survey'
340 params['acs_num_scans'] = '1'
341 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
342 wait_acs(hapd)
343
344 freq = hapd.get_status_field("freq")
345 if int(freq) < 2400:
346 raise Exception("Unexpected frequency")
347
348 dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
349
350 def test_ap_acs_errors(dev, apdev):
351 """Automatic channel selection failures"""
352 clear_scan_cache(apdev[0])
353 force_prev_ap_on_24g(apdev[0])
354 params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
355 params['channel'] = '0'
356 params['acs_num_scans'] = '2'
357 params['chanlist'] = '1'
358 hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
359
360 with alloc_fail(hapd, 1, "acs_request_scan"):
361 if "FAIL" not in hapd.request("ENABLE"):
362 raise Exception("Unexpected success for ENABLE")
363
364 hapd.dump_monitor()
365 with fail_test(hapd, 1, "acs_request_scan"):
366 if "FAIL" not in hapd.request("ENABLE"):
367 raise Exception("Unexpected success for ENABLE")
368
369 hapd.dump_monitor()
370 with fail_test(hapd, 1, "acs_scan_complete"):
371 hapd.enable()
372 ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10)
373 if not ev:
374 raise Exception("ACS start timed out")
375
376 hapd.dump_monitor()
377 with fail_test(hapd, 1, "acs_request_scan;acs_scan_complete"):
378 hapd.enable()
379 ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10)
380 if not ev:
381 raise Exception("ACS start timed out")
382
383 def test_ap_acs_dfs(dev, apdev, params):
384 """Automatic channel selection, HT scan, and DFS [long]"""
385 if not params['long']:
386 raise HwsimSkip("Skip test case with long duration due to --long not specified")
387 try:
388 hapd = None
389 force_prev_ap_on_5g(apdev[0])
390 params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
391 params['hw_mode'] = 'a'
392 params['channel'] = '0'
393 params['ht_capab'] = '[HT40+]'
394 params['country_code'] = 'US'
395 params['ieee80211d'] = '1'
396 params['ieee80211h'] = '1'
397 params['acs_num_scans'] = '1'
398 params['chanlist'] = '52 56 60 64'
399 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
400 wait_acs(hapd, return_after_acs=True)
401
402 wait_dfs_event(hapd, "DFS-CAC-START", 5)
403 ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
404 if "success=1" not in ev:
405 raise Exception("CAC failed")
406
407 ev = hapd.wait_event(["AP-ENABLED"], timeout=5)
408 if not ev:
409 raise Exception("AP setup timed out")
410
411 state = hapd.get_status_field("state")
412 if state != "ENABLED":
413 raise Exception("Unexpected interface state")
414
415 freq = int(hapd.get_status_field("freq"))
416 if freq not in [5260, 5280, 5300, 5320]:
417 raise Exception("Unexpected frequency: %d" % freq)
418
419 dev[0].connect("test-acs", psk="12345678", scan_freq=str(freq))
420 dev[0].wait_regdom(country_ie=True)
421 finally:
422 if hapd:
423 hapd.request("DISABLE")
424 dev[0].disconnect_and_stop_scan()
425 hostapd.cmd_execute(apdev[0], ['iw', 'reg', 'set', '00'])
426 dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5)
427 dev[0].flush_scan_cache()
428
429 def test_ap_acs_exclude_dfs(dev, apdev, params):
430 """Automatic channel selection, exclude DFS"""
431 try:
432 hapd = None
433 force_prev_ap_on_5g(apdev[0])
434 params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
435 params['hw_mode'] = 'a'
436 params['channel'] = '0'
437 params['ht_capab'] = '[HT40+]'
438 params['country_code'] = 'US'
439 params['ieee80211d'] = '1'
440 params['ieee80211h'] = '1'
441 params['acs_num_scans'] = '1'
442 params['acs_exclude_dfs'] = '1'
443 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
444 wait_acs(hapd)
445
446 state = hapd.get_status_field("state")
447 if state != "ENABLED":
448 raise Exception("Unexpected interface state")
449
450 freq = int(hapd.get_status_field("freq"))
451 if freq in [5260, 5280, 5300, 5320,
452 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680]:
453 raise Exception("Unexpected frequency: %d" % freq)
454
455 dev[0].connect("test-acs", psk="12345678", scan_freq=str(freq))
456 dev[0].wait_regdom(country_ie=True)
457 finally:
458 if hapd:
459 hapd.request("DISABLE")
460 dev[0].disconnect_and_stop_scan()
461 hostapd.cmd_execute(apdev[0], ['iw', 'reg', 'set', '00'])
462 dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5)
463 dev[0].flush_scan_cache()
464
465 def test_ap_acs_vht160_dfs(dev, apdev, params):
466 """Automatic channel selection 160 MHz, HT scan, and DFS [long]"""
467 if not params['long']:
468 raise HwsimSkip("Skip test case with long duration due to --long not specified")
469 try:
470 hapd = None
471 force_prev_ap_on_5g(apdev[0])
472 params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
473 params['hw_mode'] = 'a'
474 params['channel'] = '0'
475 params['ht_capab'] = '[HT40+]'
476 params['country_code'] = 'US'
477 params['ieee80211ac'] = '1'
478 params['vht_oper_chwidth'] = '2'
479 params['ieee80211d'] = '1'
480 params['ieee80211h'] = '1'
481 params['acs_num_scans'] = '1'
482 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
483 wait_acs(hapd, return_after_acs=True)
484
485 wait_dfs_event(hapd, "DFS-CAC-START", 5)
486 ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
487 if "success=1" not in ev:
488 raise Exception("CAC failed")
489
490 ev = hapd.wait_event(["AP-ENABLED"], timeout=5)
491 if not ev:
492 raise Exception("AP setup timed out")
493
494 state = hapd.get_status_field("state")
495 if state != "ENABLED":
496 raise Exception("Unexpected interface state")
497
498 freq = int(hapd.get_status_field("freq"))
499 if freq not in [5180, 5500]:
500 raise Exception("Unexpected frequency: %d" % freq)
501
502 dev[0].connect("test-acs", psk="12345678", scan_freq=str(freq))
503 dev[0].wait_regdom(country_ie=True)
504 finally:
505 if hapd:
506 hapd.request("DISABLE")
507 dev[0].disconnect_and_stop_scan()
508 hostapd.cmd_execute(apdev[0], ['iw', 'reg', 'set', '00'])
509 dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5)
510 dev[0].flush_scan_cache()