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
7import logging
8logger = logging.getLogger()
9import time
10
11import hostapd
12from utils import *
13from test_dfs import wait_dfs_event
14
15def 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.
18    hostapd.add_ap(ap, {"ssid": "open"})
19    time.sleep(0.1)
20    hostapd.remove_bss(ap)
21
22def 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.
25    hostapd.add_ap(ap, {"ssid": "open", "hw_mode": "a",
26                        "channel": "36", "country_code": "US"})
27    time.sleep(0.1)
28    hostapd.remove_bss(ap)
29
30def wait_acs(hapd, return_after_acs=False):
31    ev = hapd.wait_event(["ACS-STARTED", "ACS-COMPLETED", "ACS-FAILED",
32                          "AP-ENABLED", "AP-DISABLED"], timeout=5)
33    if not ev:
34        raise Exception("ACS start timed out")
35    if "ACS-STARTED" not in ev:
36        raise Exception("Unexpected ACS event: " + ev)
37
38    state = hapd.get_status_field("state")
39    if state != "ACS":
40        raise Exception("Unexpected interface state %s (expected ACS)" % state)
41
42    ev = hapd.wait_event(["ACS-COMPLETED", "ACS-FAILED", "AP-ENABLED",
43                          "AP-DISABLED"], timeout=20)
44    if not ev:
45        raise Exception("ACS timed out")
46    if "ACS-COMPLETED" not in ev:
47        raise Exception("Unexpected ACS event: " + ev)
48
49    if return_after_acs:
50        return
51
52    ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=5)
53    if not ev:
54        raise Exception("AP setup timed out")
55    if "AP-ENABLED" not in ev:
56        raise Exception("Unexpected ACS event: " + ev)
57
58    state = hapd.get_status_field("state")
59    if state != "ENABLED":
60        raise Exception("Unexpected interface state %s (expected ENABLED)" % state)
61
62def test_ap_acs(dev, apdev):
63    """Automatic channel selection"""
64    force_prev_ap_on_24g(apdev[0])
65    params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
66    params['channel'] = '0'
67    hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
68    wait_acs(hapd)
69
70    freq = hapd.get_status_field("freq")
71    if int(freq) < 2400:
72        raise Exception("Unexpected frequency")
73
74    dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
75
76def test_ap_acs_chanlist(dev, apdev):
77    """Automatic channel selection with chanlist set"""
78    force_prev_ap_on_24g(apdev[0])
79    params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
80    params['channel'] = '0'
81    params['chanlist'] = '1 6 11'
82    hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
83    wait_acs(hapd)
84
85    freq = hapd.get_status_field("freq")
86    if int(freq) < 2400:
87        raise Exception("Unexpected frequency")
88
89    dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
90
91def test_ap_acs_freqlist(dev, apdev):
92    """Automatic channel selection with freqlist set"""
93    run_ap_acs_freqlist(dev, apdev, [2412, 2437, 2462])
94
95def test_ap_acs_freqlist2(dev, apdev):
96    """Automatic channel selection with freqlist set"""
97    run_ap_acs_freqlist(dev, apdev, [2417, 2432, 2457])
98
99def run_ap_acs_freqlist(dev, apdev, freqlist):
100    force_prev_ap_on_24g(apdev[0])
101    params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
102    params['channel'] = '0'
103    params['freqlist'] = ','.join([str(x) for x in freqlist])
104    hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
105    wait_acs(hapd)
106
107    freq = int(hapd.get_status_field("freq"))
108    if freq not in freqlist:
109        raise Exception("Unexpected frequency: %d" % freq)
110
111    dev[0].connect("test-acs", psk="12345678", scan_freq=str(freq))
112
113def test_ap_acs_invalid_chanlist(dev, apdev):
114    """Automatic channel selection with invalid chanlist"""
115    force_prev_ap_on_24g(apdev[0])
116    params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
117    params['channel'] = '0'
118    params['chanlist'] = '15-18'
119    hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
120    res = hapd.request("ENABLE")
121    if "OK" in res:
122        raise Exception("ENABLE command succeeded unexpectedly")
123
124def test_ap_multi_bss_acs(dev, apdev):
125    """hostapd start with a multi-BSS configuration file using ACS"""
126    skip_with_fips(dev[0])
127    check_sae_capab(dev[2])
128    force_prev_ap_on_24g(apdev[0])
129
130    # start the actual test
131    hapd = hostapd.add_iface(apdev[0], 'multi-bss-acs.conf')
132    hapd.enable()
133    wait_acs(hapd)
134
135    freq = hapd.get_status_field("freq")
136    if int(freq) < 2400:
137        raise Exception("Unexpected frequency")
138
139    dev[0].connect("bss-1", key_mgmt="NONE", scan_freq=freq)
140    dev[1].connect("bss-2", psk="12345678", scan_freq=freq)
141    dev[2].set("sae_groups", "")
142    dev[2].connect("bss-3", key_mgmt="SAE", psk="qwertyuiop", scan_freq=freq)
143
144def test_ap_acs_40mhz(dev, apdev):
145    """Automatic channel selection for 40 MHz channel"""
146    run_ap_acs_40mhz(dev, apdev, '[HT40+]')
147
148def test_ap_acs_40mhz_plus_or_minus(dev, apdev):
149    """Automatic channel selection for 40 MHz channel (plus or minus)"""
150    run_ap_acs_40mhz(dev, apdev, '[HT40+][HT40-]')
151
152def run_ap_acs_40mhz(dev, apdev, ht_capab):
153    clear_scan_cache(apdev[0])
154    force_prev_ap_on_24g(apdev[0])
155    params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
156    params['channel'] = '0'
157    params['ht_capab'] = ht_capab
158    hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
159    wait_acs(hapd)
160
161    freq = hapd.get_status_field("freq")
162    if int(freq) < 2400:
163        raise Exception("Unexpected frequency")
164    sec = hapd.get_status_field("secondary_channel")
165    if int(sec) == 0:
166        raise Exception("Secondary channel not set")
167
168    dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
169
170def test_ap_acs_40mhz_minus(dev, apdev):
171    """Automatic channel selection for HT40- channel"""
172    clear_scan_cache(apdev[0])
173    force_prev_ap_on_24g(apdev[0])
174    params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
175    params['channel'] = '0'
176    params['ht_capab'] = '[HT40-]'
177    params['acs_num_scans'] = '1'
178    params['chanlist'] = '1 11'
179    hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
180    ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10)
181    if not ev:
182        raise Exception("ACS start timed out")
183    # HT40- is not currently supported in hostapd ACS, so do not try to connect
184    # or verify that this operation succeeded.
185
186def test_ap_acs_5ghz(dev, apdev):
187    """Automatic channel selection on 5 GHz"""
188    try:
189        hapd = None
190        force_prev_ap_on_5g(apdev[0])
191        params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
192        params['hw_mode'] = 'a'
193        params['channel'] = '0'
194        params['country_code'] = 'US'
195        hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
196        wait_acs(hapd)
197        freq = hapd.get_status_field("freq")
198        if int(freq) < 5000:
199            raise Exception("Unexpected frequency")
200
201        dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
202        dev[0].wait_regdom(country_ie=True)
203    finally:
204        clear_regdom(hapd, dev)
205
206def test_ap_acs_5ghz_40mhz(dev, apdev):
207    """Automatic channel selection on 5 GHz for 40 MHz channel"""
208    try:
209        hapd = None
210        force_prev_ap_on_5g(apdev[0])
211        params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
212        params['hw_mode'] = 'a'
213        params['channel'] = '0'
214        params['ht_capab'] = '[HT40+]'
215        params['country_code'] = 'US'
216        hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
217        wait_acs(hapd)
218        freq = hapd.get_status_field("freq")
219        if int(freq) < 5000:
220            raise Exception("Unexpected frequency")
221
222        sec = hapd.get_status_field("secondary_channel")
223        if int(sec) == 0:
224            raise Exception("Secondary channel not set")
225
226        dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
227        dev[0].wait_regdom(country_ie=True)
228    finally:
229        clear_regdom(hapd, dev)
230
231def test_ap_acs_vht(dev, apdev):
232    """Automatic channel selection for VHT"""
233    try:
234        hapd = None
235        force_prev_ap_on_5g(apdev[0])
236        params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
237        params['hw_mode'] = 'a'
238        params['channel'] = '0'
239        params['ht_capab'] = '[HT40+]'
240        params['country_code'] = 'US'
241        params['ieee80211ac'] = '1'
242        params['vht_oper_chwidth'] = '1'
243        hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
244        wait_acs(hapd)
245        freq = hapd.get_status_field("freq")
246        if int(freq) < 5000:
247            raise Exception("Unexpected frequency")
248
249        sec = hapd.get_status_field("secondary_channel")
250        if int(sec) == 0:
251            raise Exception("Secondary channel not set")
252
253        dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
254        dev[0].wait_regdom(country_ie=True)
255    finally:
256        clear_regdom(hapd, dev)
257
258def test_ap_acs_vht40(dev, apdev):
259    """Automatic channel selection for VHT40"""
260    try:
261        hapd = None
262        force_prev_ap_on_5g(apdev[0])
263        params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
264        params['hw_mode'] = 'a'
265        params['channel'] = '0'
266        params['ht_capab'] = '[HT40+]'
267        params['country_code'] = 'US'
268        params['ieee80211ac'] = '1'
269        params['vht_oper_chwidth'] = '0'
270        params['acs_num_scans'] = '1'
271        params['chanlist'] = '36 149'
272        hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
273        wait_acs(hapd)
274        freq = hapd.get_status_field("freq")
275        if int(freq) < 5000:
276            raise Exception("Unexpected frequency")
277
278        sec = hapd.get_status_field("secondary_channel")
279        if int(sec) == 0:
280            raise Exception("Secondary channel not set")
281
282        dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
283        dev[0].wait_regdom(country_ie=True)
284    finally:
285        clear_regdom(hapd, dev)
286
287def test_ap_acs_vht80p80(dev, apdev):
288    """Automatic channel selection for VHT 80+80"""
289    try:
290        hapd = None
291        force_prev_ap_on_5g(apdev[0])
292        params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
293        params['hw_mode'] = 'a'
294        params['channel'] = '0'
295        params['ht_capab'] = '[HT40+]'
296        params['country_code'] = 'US'
297        params['ieee80211ac'] = '1'
298        params['vht_oper_chwidth'] = '3'
299        hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
300        ev = hapd.wait_event(["ACS-COMPLETED"], timeout=20)
301        if ev is None:
302            raise Exception("ACS did not complete")
303        # ACS for 80+80 is not yet supported, so the AP setup itself will fail.
304        # Do not try to connection before this gets fully supported.
305        ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10)
306        if ev is None:
307            raise Exception("AP enabled/disabled not reported")
308    finally:
309        clear_regdom(hapd, dev)
310
311def test_ap_acs_vht160(dev, apdev):
312    """Automatic channel selection for VHT160"""
313    try:
314        hapd = None
315        force_prev_ap_on_5g(apdev[0])
316        params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
317        params['hw_mode'] = 'a'
318        params['channel'] = '0'
319        params['ht_capab'] = '[HT40+]'
320        params['country_code'] = 'ZA'
321        params['ieee80211ac'] = '1'
322        params['vht_oper_chwidth'] = '2'
323        params['ieee80211d'] = '1'
324        params['ieee80211h'] = '1'
325        params['chanlist'] = '100'
326        params['acs_num_scans'] = '1'
327        hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
328        ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10)
329        if not ev:
330            raise Exception("ACS start timed out")
331        # VHT160 is not currently supported in hostapd ACS, so do not try to
332        # enforce successful AP start.
333        if "AP-ENABLED" in ev:
334            freq = hapd.get_status_field("freq")
335            if int(freq) < 5000:
336                raise Exception("Unexpected frequency")
337            dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
338            dev[0].wait_regdom(country_ie=True)
339    finally:
340        clear_regdom(hapd, dev)
341
342def test_ap_acs_vht160_scan_disable(dev, apdev):
343    """Automatic channel selection for VHT160 and DISABLE during scan"""
344    force_prev_ap_on_5g(apdev[0])
345    params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
346    params['hw_mode'] = 'a'
347    params['channel'] = '0'
348    params['ht_capab'] = '[HT40+]'
349    params['country_code'] = 'ZA'
350    params['ieee80211ac'] = '1'
351    params['vht_oper_chwidth'] = '2'
352    params["vht_oper_centr_freq_seg0_idx"] = "114"
353    params['ieee80211d'] = '1'
354    params['ieee80211h'] = '1'
355    hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
356    time.sleep(3)
357    clear_regdom(hapd, dev)
358
359def test_ap_acs_bias(dev, apdev):
360    """Automatic channel selection with bias values"""
361    force_prev_ap_on_24g(apdev[0])
362    params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
363    params['channel'] = '0'
364    params['acs_chan_bias'] = '1:0.8 3:1.2 6:0.7 11:0.8'
365    hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
366    wait_acs(hapd)
367
368    freq = hapd.get_status_field("freq")
369    if int(freq) < 2400:
370        raise Exception("Unexpected frequency")
371
372    dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
373
374def test_ap_acs_survey(dev, apdev):
375    """Automatic channel selection using acs_survey parameter"""
376    force_prev_ap_on_24g(apdev[0])
377    params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
378    params['channel'] = 'acs_survey'
379    params['acs_num_scans'] = '1'
380    hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
381    wait_acs(hapd)
382
383    freq = hapd.get_status_field("freq")
384    if int(freq) < 2400:
385        raise Exception("Unexpected frequency")
386
387    dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
388
389def test_ap_acs_errors(dev, apdev):
390    """Automatic channel selection failures"""
391    clear_scan_cache(apdev[0])
392    force_prev_ap_on_24g(apdev[0])
393    params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
394    params['channel'] = '0'
395    params['acs_num_scans'] = '2'
396    params['chanlist'] = '1'
397    hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
398
399    with alloc_fail(hapd, 1, "acs_request_scan"):
400        if "FAIL" not in hapd.request("ENABLE"):
401            raise Exception("Unexpected success for ENABLE")
402
403    hapd.dump_monitor()
404    with fail_test(hapd, 1, "acs_request_scan"):
405        if "FAIL" not in hapd.request("ENABLE"):
406            raise Exception("Unexpected success for ENABLE")
407
408    hapd.dump_monitor()
409    with fail_test(hapd, 1, "acs_scan_complete"):
410        hapd.enable()
411        ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10)
412        if not ev:
413            raise Exception("ACS start timed out")
414
415    hapd.dump_monitor()
416    with fail_test(hapd, 1, "acs_request_scan;acs_scan_complete"):
417        hapd.enable()
418        ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10)
419        if not ev:
420            raise Exception("ACS start timed out")
421
422@long_duration_test
423def test_ap_acs_dfs(dev, apdev):
424    """Automatic channel selection, HT scan, and DFS"""
425    try:
426        hapd = None
427        force_prev_ap_on_5g(apdev[0])
428        params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
429        params['hw_mode'] = 'a'
430        params['channel'] = '0'
431        params['ht_capab'] = '[HT40+]'
432        params['country_code'] = 'US'
433        params['ieee80211d'] = '1'
434        params['ieee80211h'] = '1'
435        params['acs_num_scans'] = '1'
436        params['chanlist'] = '52 56 60 64'
437        hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
438        wait_acs(hapd, return_after_acs=True)
439
440        wait_dfs_event(hapd, "DFS-CAC-START", 5)
441        ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
442        if "success=1" not in ev:
443            raise Exception("CAC failed")
444
445        ev = hapd.wait_event(["AP-ENABLED"], timeout=5)
446        if not ev:
447            raise Exception("AP setup timed out")
448
449        state = hapd.get_status_field("state")
450        if state != "ENABLED":
451            raise Exception("Unexpected interface state")
452
453        freq = int(hapd.get_status_field("freq"))
454        if freq not in [5260, 5280, 5300, 5320]:
455            raise Exception("Unexpected frequency: %d" % freq)
456
457        dev[0].connect("test-acs", psk="12345678", scan_freq=str(freq))
458        dev[0].wait_regdom(country_ie=True)
459    finally:
460        if hapd:
461            hapd.request("DISABLE")
462        dev[0].disconnect_and_stop_scan()
463        hostapd.cmd_execute(apdev[0], ['iw', 'reg', 'set', '00'])
464        dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5)
465        dev[0].flush_scan_cache()
466
467def test_ap_acs_exclude_dfs(dev, apdev, params):
468    """Automatic channel selection, exclude DFS"""
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['ieee80211d'] = '1'
478        params['ieee80211h'] = '1'
479        params['acs_num_scans'] = '1'
480        params['acs_exclude_dfs'] = '1'
481        hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
482        wait_acs(hapd)
483
484        state = hapd.get_status_field("state")
485        if state != "ENABLED":
486            raise Exception("Unexpected interface state")
487
488        freq = int(hapd.get_status_field("freq"))
489        if freq in [5260, 5280, 5300, 5320,
490                    5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680]:
491            raise Exception("Unexpected frequency: %d" % freq)
492
493        dev[0].connect("test-acs", psk="12345678", scan_freq=str(freq))
494        dev[0].wait_regdom(country_ie=True)
495    finally:
496        if hapd:
497            hapd.request("DISABLE")
498        dev[0].disconnect_and_stop_scan()
499        hostapd.cmd_execute(apdev[0], ['iw', 'reg', 'set', '00'])
500        dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5)
501        dev[0].flush_scan_cache()
502
503@long_duration_test
504def test_ap_acs_vht160_dfs(dev, apdev):
505    """Automatic channel selection 160 MHz, HT scan, and DFS"""
506    try:
507        hapd = None
508        force_prev_ap_on_5g(apdev[0])
509        params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
510        params['hw_mode'] = 'a'
511        params['channel'] = '0'
512        params['ht_capab'] = '[HT40+]'
513        params['country_code'] = 'US'
514        params['ieee80211ac'] = '1'
515        params['vht_oper_chwidth'] = '2'
516        params['ieee80211d'] = '1'
517        params['ieee80211h'] = '1'
518        params['acs_num_scans'] = '1'
519        hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
520        wait_acs(hapd, return_after_acs=True)
521
522        wait_dfs_event(hapd, "DFS-CAC-START", 5)
523        ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
524        if "success=1" not in ev:
525            raise Exception("CAC failed")
526
527        ev = hapd.wait_event(["AP-ENABLED"], timeout=5)
528        if not ev:
529            raise Exception("AP setup timed out")
530
531        state = hapd.get_status_field("state")
532        if state != "ENABLED":
533            raise Exception("Unexpected interface state")
534
535        freq = int(hapd.get_status_field("freq"))
536        if freq not in [5180, 5500]:
537            raise Exception("Unexpected frequency: %d" % freq)
538
539        dev[0].connect("test-acs", psk="12345678", scan_freq=str(freq))
540        dev[0].wait_regdom(country_ie=True)
541    finally:
542        if hapd:
543            hapd.request("DISABLE")
544        dev[0].disconnect_and_stop_scan()
545        hostapd.cmd_execute(apdev[0], ['iw', 'reg', 'set', '00'])
546        dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5)
547        dev[0].flush_scan_cache()
548
549def test_ap_acs_hw_mode_any(dev, apdev):
550    """Automatic channel selection with hw_mode=any"""
551    force_prev_ap_on_24g(apdev[0])
552    params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
553    params['channel'] = '0'
554    params['hw_mode'] = 'any'
555    hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
556    wait_acs(hapd)
557
558    freq = hapd.get_status_field("freq")
559    if int(freq) < 2400:
560        raise Exception("Unexpected frequency")
561
562    dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
563
564def test_ap_acs_hw_mode_any_5ghz(dev, apdev):
565    """Automatic channel selection with hw_mode=any and 5 GHz"""
566    try:
567        hapd = None
568        force_prev_ap_on_5g(apdev[0])
569        params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
570        params['hw_mode'] = 'any'
571        params['channel'] = '0'
572        params['country_code'] = 'US'
573        params['acs_chan_bias'] = '36:0.7 40:0.7 44:0.7 48:0.7'
574        hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
575        wait_acs(hapd)
576        freq = hapd.get_status_field("freq")
577        if int(freq) < 5000:
578            raise Exception("Unexpected frequency")
579
580        dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
581        dev[0].wait_regdom(country_ie=True)
582    finally:
583        clear_regdom(hapd, dev)
584
585def test_ap_acs_with_fallback_to_20(dev, apdev):
586    """Automatic channel selection with fallback to 20 MHz"""
587    force_prev_ap_on_24g(apdev[0])
588    params = {"ssid": "legacy-20",
589              "channel": "7", "ieee80211n": "0"}
590    hostapd.add_ap(apdev[1], params)
591    params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
592    params['channel'] = '0'
593    params['acs_chan_bias'] = '6:0.1'
594    params['ht_capab'] = '[HT40+]'
595    hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
596    wait_acs(hapd)
597
598    freq = hapd.get_status_field("freq")
599    if int(freq) < 2400:
600        raise Exception("Unexpected frequency")
601
602    dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
603    sig = dev[0].request("SIGNAL_POLL").splitlines()
604    logger.info("SIGNAL_POLL: " + str(sig))
605    if "WIDTH=20 MHz" not in sig:
606        raise Exception("Station did not report 20 MHz bandwidth")
607
608def test_ap_acs_rx_during(dev, apdev):
609    """Automatic channel selection and RX during ACS"""
610    force_prev_ap_on_24g(apdev[0])
611    params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
612    params['channel'] = '0'
613    params['chanlist'] = '1 6 11'
614    hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
615
616    time.sleep(0.1)
617    hapd.set("ext_mgmt_frame_handling", "1")
618    bssid = hapd.own_addr().replace(':', '')
619    addr = "020304050607"
620    broadcast = 6*"ff"
621
622    probereq = "40000000" + broadcast + addr + broadcast + "1000"
623    probereq += "0000" + "010802040b160c121824" + "32043048606c" + "030100"
624    if "OK" not in hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=%s" % probereq):
625        raise Exception("MGMT_RX_PROCESS failed")
626
627    probereq = "40000000" + broadcast + addr + broadcast + "1000"
628    probereq += "0000" + "010102"
629    if "OK" not in hapd.request("MGMT_RX_PROCESS freq=2437 datarate=0 ssi_signal=-30 frame=%s" % probereq):
630        raise Exception("MGMT_RX_PROCESS failed")
631
632    auth = "b0003a01" + bssid + addr + bssid + '1000000001000000'
633    if "OK" not in hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=%s" % auth):
634        raise Exception("MGMT_RX_PROCESS failed")
635    hapd.set("ext_mgmt_frame_handling", "0")
636
637    time.sleep(0.2)
638    try:
639        for i in range(3):
640            dev[i].request("SCAN_INTERVAL 1")
641            dev[i].connect("test-acs", psk="12345678",
642                           scan_freq="2412 2437 2462", wait_connect=False)
643        wait_acs(hapd)
644        for i in range(3):
645            dev[i].wait_connected()
646    finally:
647        for i in range(3):
648            dev[i].request("SCAN_INTERVAL 5")
649
650def test_ap_acs_he_24g(dev, apdev):
651    """Automatic channel selection on 2.4 GHz with HE"""
652    clear_scan_cache(apdev[0])
653    force_prev_ap_on_24g(apdev[0])
654
655    params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
656    params['channel'] = '0'
657    params['ieee80211ax'] = '1'
658    params['ht_capab'] = '[HT40+]'
659    hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
660    wait_acs(hapd)
661
662    freq = hapd.get_status_field("freq")
663    if int(freq) < 2400:
664        raise Exception("Unexpected frequency")
665
666    dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
667
668def test_ap_acs_he_24g_overlap(dev, apdev):
669    """Automatic channel selection on 2.4 GHz with HE (overlap)"""
670    clear_scan_cache(apdev[0])
671    force_prev_ap_on_24g(apdev[0])
672
673    params = {"ssid": "overlapping",
674              "channel": "6", "ieee80211n": "1"}
675    hostapd.add_ap(apdev[1], params)
676
677    params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
678    params['channel'] = '0'
679    params['ieee80211ax'] = '1'
680    params['ht_capab'] = '[HT40+]'
681    hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
682    wait_acs(hapd)
683
684    freq = hapd.get_status_field("freq")
685    if int(freq) < 2400:
686        raise Exception("Unexpected frequency")
687
688    dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
689