1 # Test cases for HT operations with hostapd
2 # Copyright (c) 2013-2014, Jouni Malinen <j@w1.fi>
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
9 logger = logging.getLogger()
14 from utils import HwsimSkip, alloc_fail
16 from test_ap_csa import csa_supported
18 def clear_scan_cache(ifname):
19 subprocess.call(['ifconfig', ifname, 'up'])
20 subprocess.call(['iw', ifname, 'scan', 'freq', '2412', 'flush'])
22 subprocess.call(['ifconfig', ifname, 'down'])
24 def test_ap_ht40_scan(dev, apdev):
26 clear_scan_cache(apdev[0]['ifname'])
27 params = { "ssid": "test-ht40",
29 "ht_capab": "[HT40-]"}
30 hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
32 state = hapd.get_status_field("state")
33 if state != "HT_SCAN":
35 state = hapd.get_status_field("state")
36 if state != "HT_SCAN":
37 raise Exception("Unexpected interface state - expected HT_SCAN")
39 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
41 raise Exception("AP setup timed out")
43 state = hapd.get_status_field("state")
44 if state != "ENABLED":
45 raise Exception("Unexpected interface state - expected ENABLED")
47 freq = hapd.get_status_field("freq")
49 raise Exception("Unexpected frequency")
50 pri = hapd.get_status_field("channel")
52 raise Exception("Unexpected primary channel")
53 sec = hapd.get_status_field("secondary_channel")
55 raise Exception("Unexpected secondary channel")
57 dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
59 def test_ap_ht40_scan_conflict(dev, apdev):
60 """HT40 co-ex scan conflict"""
61 clear_scan_cache(apdev[0]['ifname'])
62 params = { "ssid": "test-ht40",
64 "ht_capab": "[HT40+]"}
65 hostapd.add_ap(apdev[1]['ifname'], params)
67 params = { "ssid": "test-ht40",
69 "ht_capab": "[HT40-]"}
70 hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
72 state = hapd.get_status_field("state")
73 if state != "HT_SCAN":
75 state = hapd.get_status_field("state")
76 if state != "HT_SCAN":
77 raise Exception("Unexpected interface state - expected HT_SCAN")
79 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
81 raise Exception("AP setup timed out")
83 state = hapd.get_status_field("state")
84 if state != "ENABLED":
85 raise Exception("Unexpected interface state - expected ENABLED")
87 freq = hapd.get_status_field("freq")
89 raise Exception("Unexpected frequency")
90 pri = hapd.get_status_field("channel")
92 raise Exception("Unexpected primary channel")
93 sec = hapd.get_status_field("secondary_channel")
95 raise Exception("Unexpected secondary channel: " + sec)
97 dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
99 def test_ap_ht40_scan_legacy_conflict(dev, apdev):
100 """HT40 co-ex scan conflict with legacy 20 MHz AP"""
101 clear_scan_cache(apdev[0]['ifname'])
102 params = { "ssid": "legacy-20",
103 "channel": "7", "ieee80211n": "0" }
104 hostapd.add_ap(apdev[1]['ifname'], params)
106 params = { "ssid": "test-ht40",
108 "ht_capab": "[HT40-]"}
109 hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
111 state = hapd.get_status_field("state")
112 if state != "HT_SCAN":
114 state = hapd.get_status_field("state")
115 if state != "HT_SCAN":
116 raise Exception("Unexpected interface state - expected HT_SCAN")
118 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
120 raise Exception("AP setup timed out")
122 state = hapd.get_status_field("state")
123 if state != "ENABLED":
124 raise Exception("Unexpected interface state - expected ENABLED")
126 freq = hapd.get_status_field("freq")
128 raise Exception("Unexpected frequency: " + freq)
129 pri = hapd.get_status_field("channel")
131 raise Exception("Unexpected primary channel: " + pri)
132 sec = hapd.get_status_field("secondary_channel")
134 raise Exception("Unexpected secondary channel: " + sec)
136 dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
138 def test_ap_ht40_scan_match(dev, apdev):
139 """HT40 co-ex scan matching configuration"""
140 clear_scan_cache(apdev[0]['ifname'])
141 params = { "ssid": "test-ht40",
143 "ht_capab": "[HT40-]"}
144 hostapd.add_ap(apdev[1]['ifname'], params)
146 params = { "ssid": "test-ht40",
148 "ht_capab": "[HT40-]"}
149 hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
151 state = hapd.get_status_field("state")
152 if state != "HT_SCAN":
154 state = hapd.get_status_field("state")
155 if state != "HT_SCAN":
156 raise Exception("Unexpected interface state - expected HT_SCAN")
158 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
160 raise Exception("AP setup timed out")
162 state = hapd.get_status_field("state")
163 if state != "ENABLED":
164 raise Exception("Unexpected interface state - expected ENABLED")
166 freq = hapd.get_status_field("freq")
168 raise Exception("Unexpected frequency")
169 pri = hapd.get_status_field("channel")
171 raise Exception("Unexpected primary channel")
172 sec = hapd.get_status_field("secondary_channel")
174 raise Exception("Unexpected secondary channel: " + sec)
176 dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
178 def test_ap_ht40_5ghz_match(dev, apdev):
179 """HT40 co-ex scan on 5 GHz with matching pri/sec channel"""
180 clear_scan_cache(apdev[0]['ifname'])
184 params = { "ssid": "test-ht40",
187 "country_code": "US",
188 "ht_capab": "[HT40+]"}
189 hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
191 params = { "ssid": "test-ht40",
194 "ht_capab": "[HT40+]"}
195 hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
197 state = hapd.get_status_field("state")
198 if state != "HT_SCAN":
200 state = hapd.get_status_field("state")
201 if state != "HT_SCAN":
202 raise Exception("Unexpected interface state - expected HT_SCAN")
204 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
206 raise Exception("AP setup timed out")
208 state = hapd.get_status_field("state")
209 if state != "ENABLED":
210 raise Exception("Unexpected interface state - expected ENABLED")
212 freq = hapd.get_status_field("freq")
214 raise Exception("Unexpected frequency")
215 pri = hapd.get_status_field("channel")
217 raise Exception("Unexpected primary channel")
218 sec = hapd.get_status_field("secondary_channel")
220 raise Exception("Unexpected secondary channel: " + sec)
222 dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
224 dev[0].request("DISCONNECT")
226 hapd.request("DISABLE")
228 hapd2.request("DISABLE")
229 subprocess.call(['iw', 'reg', 'set', '00'])
230 dev[0].flush_scan_cache()
232 def test_ap_ht40_5ghz_switch(dev, apdev):
233 """HT40 co-ex scan on 5 GHz switching pri/sec channel"""
234 clear_scan_cache(apdev[0]['ifname'])
238 params = { "ssid": "test-ht40",
241 "country_code": "US",
242 "ht_capab": "[HT40+]"}
243 hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
245 params = { "ssid": "test-ht40",
248 "ht_capab": "[HT40-]"}
249 hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
251 state = hapd.get_status_field("state")
252 if state != "HT_SCAN":
254 state = hapd.get_status_field("state")
255 if state != "HT_SCAN":
256 raise Exception("Unexpected interface state - expected HT_SCAN")
258 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
260 raise Exception("AP setup timed out")
262 state = hapd.get_status_field("state")
263 if state != "ENABLED":
264 raise Exception("Unexpected interface state - expected ENABLED")
266 freq = hapd.get_status_field("freq")
268 raise Exception("Unexpected frequency: " + freq)
269 pri = hapd.get_status_field("channel")
271 raise Exception("Unexpected primary channel: " + pri)
272 sec = hapd.get_status_field("secondary_channel")
274 raise Exception("Unexpected secondary channel: " + sec)
276 dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
278 dev[0].request("DISCONNECT")
280 hapd.request("DISABLE")
282 hapd2.request("DISABLE")
283 subprocess.call(['iw', 'reg', 'set', '00'])
285 def test_ap_ht40_5ghz_switch2(dev, apdev):
286 """HT40 co-ex scan on 5 GHz switching pri/sec channel (2)"""
287 clear_scan_cache(apdev[0]['ifname'])
291 params = { "ssid": "test-ht40",
294 "country_code": "US",
295 "ht_capab": "[HT40+]"}
296 hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
298 id = dev[0].add_network()
299 dev[0].set_network(id, "mode", "2")
300 dev[0].set_network_quoted(id, "ssid", "wpas-ap-open")
301 dev[0].set_network(id, "key_mgmt", "NONE")
302 dev[0].set_network(id, "frequency", "5200")
303 dev[0].set_network(id, "scan_freq", "5200")
304 dev[0].select_network(id)
307 params = { "ssid": "test-ht40",
310 "ht_capab": "[HT40-]"}
311 hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
313 state = hapd.get_status_field("state")
314 if state != "HT_SCAN":
316 state = hapd.get_status_field("state")
317 if state != "HT_SCAN":
318 raise Exception("Unexpected interface state - expected HT_SCAN")
320 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
322 raise Exception("AP setup timed out")
324 state = hapd.get_status_field("state")
325 if state != "ENABLED":
326 raise Exception("Unexpected interface state - expected ENABLED")
328 freq = hapd.get_status_field("freq")
330 raise Exception("Unexpected frequency: " + freq)
331 pri = hapd.get_status_field("channel")
333 raise Exception("Unexpected primary channel: " + pri)
334 sec = hapd.get_status_field("secondary_channel")
336 raise Exception("Unexpected secondary channel: " + sec)
338 dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
340 dev[0].request("DISCONNECT")
342 hapd.request("DISABLE")
344 hapd2.request("DISABLE")
345 subprocess.call(['iw', 'reg', 'set', '00'])
346 dev[0].flush_scan_cache()
348 def test_obss_scan(dev, apdev):
349 """Overlapping BSS scan request"""
350 params = { "ssid": "obss-scan",
352 "ht_capab": "[HT40-]",
353 "obss_interval": "10" }
354 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
356 params = { "ssid": "another-bss",
359 hostapd.add_ap(apdev[1]['ifname'], params)
361 dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
362 hapd.set("ext_mgmt_frame_handling", "1")
363 logger.info("Waiting for OBSS scan to occur")
364 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=15)
366 raise Exception("Timed out while waiting for OBSS scan to start")
367 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
369 raise Exception("Timed out while waiting for OBSS scan results")
371 for i in range(0, 4):
372 frame = hapd.mgmt_rx(timeout=5)
374 raise Exception("MGMT RX wait timed out")
375 if frame['subtype'] != 13:
377 payload = frame['payload']
380 (category, action, ie) = struct.unpack('BBB', payload[0:3])
386 logger.info("20/40 BSS Coexistence report received")
390 raise Exception("20/40 BSS Coexistence report not seen")
392 def test_obss_scan_40_intolerant(dev, apdev):
393 """Overlapping BSS scan request with 40 MHz intolerant AP"""
394 params = { "ssid": "obss-scan",
396 "ht_capab": "[HT40-]",
397 "obss_interval": "10" }
398 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
400 params = { "ssid": "another-bss",
402 "ht_capab": "[40-INTOLERANT]" }
403 hostapd.add_ap(apdev[1]['ifname'], params)
405 dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
406 hapd.set("ext_mgmt_frame_handling", "1")
407 logger.info("Waiting for OBSS scan to occur")
408 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=15)
410 raise Exception("Timed out while waiting for OBSS scan to start")
411 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
413 raise Exception("Timed out while waiting for OBSS scan results")
415 for i in range(0, 4):
416 frame = hapd.mgmt_rx(timeout=5)
418 raise Exception("MGMT RX wait timed out")
419 if frame['subtype'] != 13:
421 payload = frame['payload']
424 (category, action, ie) = struct.unpack('BBB', payload[0:3])
430 logger.info("20/40 BSS Coexistence report received")
434 raise Exception("20/40 BSS Coexistence report not seen")
436 def test_obss_coex_report_handling(dev, apdev):
437 """Overlapping BSS scan report handling with obss_interval=0"""
438 clear_scan_cache(apdev[0]['ifname'])
439 params = { "ssid": "obss-scan",
441 "ht_capab": "[HT40-]" }
442 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
443 bssid = apdev[0]['bssid']
444 dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
446 sec = hapd.get_status_field("secondary_channel")
448 raise Exception("AP is not using 40 MHz channel")
450 # 20/40 MHz co-ex report tests: number of invalid reports and a valid report
451 # that forces 20 MHz channel.
452 tests = [ '0400', '040048', '04004801', '0400480000', '0400490100',
453 '040048ff0000', '04004801ff49ff00', '04004801004900',
454 '0400480100490101', '0400480100490201ff',
455 '040048010449020005' ]
457 req = "MGMT_TX {} {} freq=2437 action={}".format(bssid, bssid, msg)
458 if "OK" not in dev[0].request(req):
459 raise Exception("Could not send management frame")
461 sec = hapd.get_status_field("secondary_channel")
463 raise Exception("AP did not move to 20 MHz channel")
465 def test_obss_coex_report_handling1(dev, apdev):
466 """Overlapping BSS scan report handling with obss_interval=1"""
467 clear_scan_cache(apdev[0]['ifname'])
468 params = { "ssid": "obss-scan",
470 "ht_capab": "[HT40+]",
471 "obss_interval": "1" }
472 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
473 bssid = apdev[0]['bssid']
474 dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
476 sec = hapd.get_status_field("secondary_channel")
478 raise Exception("AP is not using 40 MHz channel")
480 # 20/40 MHz co-ex report forcing 20 MHz channel
481 msg = '040048010449020005'
482 req = "MGMT_TX {} {} freq=2437 action={}".format(bssid, bssid, msg)
483 if "OK" not in dev[0].request(req):
484 raise Exception("Could not send management frame")
486 sec = hapd.get_status_field("secondary_channel")
488 raise Exception("AP did not move to 20 MHz channel")
490 # No 20/40 MHz co-ex reports forcing 20 MHz channel during next interval
492 sec = hapd.get_status_field("secondary_channel")
497 raise Exception("AP did not return to 40 MHz channel")
499 def test_olbc(dev, apdev):
501 params = { "ssid": "test-olbc",
503 "ht_capab": "[HT40-]",
504 "ap_table_expiration_time": "2" }
505 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
506 status = hapd.get_status()
507 if status['olbc'] != '0' or status['olbc_ht'] != '0':
508 raise Exception("Unexpected OLBC information")
510 params = { "ssid": "olbc-ap",
514 hostapd.add_ap(apdev[1]['ifname'], params)
516 status = hapd.get_status()
517 if status['olbc'] != '1' or status['olbc_ht'] != '1':
518 raise Exception("Missing OLBC information")
520 hapd_global = hostapd.HostapdGlobal()
521 hapd_global.remove(apdev[1]['ifname'])
523 logger.info("Waiting for OLBC state to time out")
525 for i in range(0, 15):
527 status = hapd.get_status()
528 if status['olbc'] == '0' and status['olbc_ht'] == '0':
532 raise Exception("OLBC state did nto time out")
534 def test_olbc_table_limit(dev, apdev):
535 """OLBC AP table size limit"""
536 ifname1 = apdev[0]['ifname']
537 ifname2 = apdev[0]['ifname'] + '-2'
538 ifname3 = apdev[0]['ifname'] + '-3'
539 hostapd.add_bss('phy3', ifname1, 'bss-1.conf')
540 hostapd.add_bss('phy3', ifname2, 'bss-2.conf')
541 hostapd.add_bss('phy3', ifname3, 'bss-3.conf')
543 params = { "ssid": "test-olbc",
545 "ap_table_max_size": "2" }
546 hapd = hostapd.add_ap(apdev[1]['ifname'], params)
549 with alloc_fail(hapd, 1, "ap_list_process_beacon"):
551 hapd.set("ap_table_max_size", "1")
553 hapd.set("ap_table_max_size", "0")
556 def test_olbc_5ghz(dev, apdev):
557 """OLBC detection on 5 GHz"""
561 params = { "ssid": "test-olbc",
562 "country_code": "FI",
565 "ht_capab": "[HT40+]" }
566 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
567 status = hapd.get_status()
568 if status['olbc'] != '0' or status['olbc_ht'] != '0':
569 raise Exception("Unexpected OLBC information")
571 params = { "ssid": "olbc-ap",
572 "country_code": "FI",
577 hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
581 status = hapd.get_status()
582 logger.debug('olbc_ht: ' + status['olbc_ht'])
583 if status['olbc_ht'] == '1':
587 raise Exception("Missing OLBC information")
590 hapd.request("DISABLE")
592 hapd2.request("DISABLE")
593 subprocess.call(['iw', 'reg', 'set', '00'])
595 def test_ap_require_ht(dev, apdev):
597 params = { "ssid": "require-ht",
599 hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
601 dev[1].connect("require-ht", key_mgmt="NONE", scan_freq="2412",
602 disable_ht="1", wait_connect=False)
603 dev[0].connect("require-ht", key_mgmt="NONE", scan_freq="2412")
604 ev = dev[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
606 raise Exception("Association rejection timed out")
607 if "status_code=27" not in ev:
608 raise Exception("Unexpected rejection status code")
609 dev[2].connect("require-ht", key_mgmt="NONE", scan_freq="2412",
610 ht_mcs="0x01 00 00 00 00 00 00 00 00 00",
611 disable_max_amsdu="1", ampdu_factor="2",
612 ampdu_density="1", disable_ht40="1", disable_sgi="1",
615 def test_ap_require_ht_limited_rates(dev, apdev):
616 """Require HT with limited supported rates"""
617 params = { "ssid": "require-ht",
618 "supported_rates": "60 120 240 360 480 540",
620 hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
622 dev[1].connect("require-ht", key_mgmt="NONE", scan_freq="2412",
623 disable_ht="1", wait_connect=False)
624 dev[0].connect("require-ht", key_mgmt="NONE", scan_freq="2412")
625 ev = dev[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
627 raise Exception("Association rejection timed out")
628 if "status_code=27" not in ev:
629 raise Exception("Unexpected rejection status code")
631 def test_ap_ht_capab_not_supported(dev, apdev):
632 """HT configuration with driver not supporting all ht_capab entries"""
633 params = { "ssid": "test-ht40",
635 "ht_capab": "[HT40-][LDPC][SMPS-STATIC][SMPS-DYNAMIC][GF][SHORT-GI-20][SHORT-GI-40][TX-STBC][RX-STBC1][RX-STBC12][RX-STBC123][DELAYED-BA][MAX-AMSDU-7935][DSSS_CCK-40][LSIG-TXOP-PROT]"}
636 hapd = hostapd.add_ap(apdev[0]['ifname'], params, no_enable=True)
637 if "FAIL" not in hapd.request("ENABLE"):
638 raise Exception("Unexpected ENABLE success")
640 def test_ap_ht_40mhz_intolerant_sta(dev, apdev):
641 """Associated STA indicating 40 MHz intolerant"""
642 clear_scan_cache(apdev[0]['ifname'])
643 params = { "ssid": "intolerant",
645 "ht_capab": "[HT40-]" }
646 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
647 if hapd.get_status_field("num_sta_ht40_intolerant") != "0":
648 raise Exception("Unexpected num_sta_ht40_intolerant value")
649 if hapd.get_status_field("secondary_channel") != "-1":
650 raise Exception("Unexpected secondary_channel")
652 dev[0].connect("intolerant", key_mgmt="NONE", scan_freq="2437")
653 if hapd.get_status_field("num_sta_ht40_intolerant") != "0":
654 raise Exception("Unexpected num_sta_ht40_intolerant value")
655 if hapd.get_status_field("secondary_channel") != "-1":
656 raise Exception("Unexpected secondary_channel")
658 dev[2].connect("intolerant", key_mgmt="NONE", scan_freq="2437",
661 if hapd.get_status_field("num_sta_ht40_intolerant") != "1":
662 raise Exception("Unexpected num_sta_ht40_intolerant value (expected 1)")
663 if hapd.get_status_field("secondary_channel") != "0":
664 raise Exception("Unexpected secondary_channel (did not disable 40 MHz)")
666 dev[2].request("DISCONNECT")
668 if hapd.get_status_field("num_sta_ht40_intolerant") != "0":
669 raise Exception("Unexpected num_sta_ht40_intolerant value (expected 0)")
670 if hapd.get_status_field("secondary_channel") != "-1":
671 raise Exception("Unexpected secondary_channel (did not re-enable 40 MHz)")
673 def test_ap_ht_40mhz_intolerant_ap(dev, apdev):
674 """Associated STA reports 40 MHz intolerant AP after association"""
675 clear_scan_cache(apdev[0]['ifname'])
676 params = { "ssid": "ht",
678 "ht_capab": "[HT40-]",
679 "obss_interval": "3" }
680 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
682 dev[0].connect("ht", key_mgmt="NONE", scan_freq="2437")
684 if hapd.get_status_field("secondary_channel") != "-1":
685 raise Exception("Unexpected secondary channel information")
687 logger.info("Start 40 MHz intolerant AP")
688 params = { "ssid": "intolerant",
690 "ht_capab": "[40-INTOLERANT]" }
691 hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
693 logger.info("Waiting for co-ex report from STA")
695 for i in range(0, 20):
697 if hapd.get_status_field("secondary_channel") == "0":
698 logger.info("AP moved to 20 MHz channel")
702 raise Exception("AP did not move to 20 MHz channel")
704 if "OK" not in hapd2.request("DISABLE"):
705 raise Exception("Failed to disable 40 MHz intolerant AP")
707 # make sure the intolerant AP disappears from scan results more quickly
708 dev[0].scan(type="ONLY", freq="2432", only_new=True)
709 dev[0].scan(type="ONLY", freq="2432", only_new=True)
710 dev[0].dump_monitor()
712 logger.info("Waiting for AP to move back to 40 MHz channel")
714 for i in range(0, 30):
716 if hapd.get_status_field("secondary_channel") == "-1":
717 logger.info("AP moved to 40 MHz channel")
721 raise Exception("AP did not move to 40 MHz channel")
723 def test_ap_ht40_csa(dev, apdev):
724 """HT with 40 MHz channel width and CSA"""
725 csa_supported(dev[0])
728 params = { "ssid": "ht",
729 "country_code": "US",
732 "ht_capab": "[HT40+]",
734 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
736 dev[0].connect("ht", key_mgmt="NONE", scan_freq="5180")
737 hwsim_utils.test_connectivity(dev[0], hapd)
739 hapd.request("CHAN_SWITCH 5 5200 ht sec_channel_offset=-1 bandwidth=40")
740 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
742 raise Exception("CSA finished event timed out")
743 if "freq=5200" not in ev:
744 raise Exception("Unexpected channel in CSA finished event")
745 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
747 raise Exception("Unexpected STA disconnection during CSA")
748 hwsim_utils.test_connectivity(dev[0], hapd)
750 hapd.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
751 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
753 raise Exception("CSA finished event timed out")
754 if "freq=5180" not in ev:
755 raise Exception("Unexpected channel in CSA finished event")
756 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
758 raise Exception("Unexpected STA disconnection during CSA")
759 hwsim_utils.test_connectivity(dev[0], hapd)
761 dev[0].request("DISCONNECT")
763 hapd.request("DISABLE")
764 subprocess.call(['iw', 'reg', 'set', '00'])
765 dev[0].flush_scan_cache()
767 def test_ap_ht40_csa2(dev, apdev):
768 """HT with 40 MHz channel width and CSA"""
769 csa_supported(dev[0])
772 params = { "ssid": "ht",
773 "country_code": "US",
776 "ht_capab": "[HT40+]",
778 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
780 dev[0].connect("ht", key_mgmt="NONE", scan_freq="5180")
781 hwsim_utils.test_connectivity(dev[0], hapd)
783 hapd.request("CHAN_SWITCH 5 5220 ht sec_channel_offset=1 bandwidth=40")
784 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
786 raise Exception("CSA finished event timed out")
787 if "freq=5220" not in ev:
788 raise Exception("Unexpected channel in CSA finished event")
789 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
791 raise Exception("Unexpected STA disconnection during CSA")
792 hwsim_utils.test_connectivity(dev[0], hapd)
794 hapd.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
795 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
797 raise Exception("CSA finished event timed out")
798 if "freq=5180" not in ev:
799 raise Exception("Unexpected channel in CSA finished event")
800 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
802 raise Exception("Unexpected STA disconnection during CSA")
803 hwsim_utils.test_connectivity(dev[0], hapd)
805 dev[0].request("DISCONNECT")
807 hapd.request("DISABLE")
808 subprocess.call(['iw', 'reg', 'set', '00'])
809 dev[0].flush_scan_cache()
811 def test_ap_ht40_csa3(dev, apdev):
812 """HT with 40 MHz channel width and CSA"""
813 csa_supported(dev[0])
816 params = { "ssid": "ht",
817 "country_code": "US",
820 "ht_capab": "[HT40+]",
822 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
824 dev[0].connect("ht", key_mgmt="NONE", scan_freq="5180")
825 hwsim_utils.test_connectivity(dev[0], hapd)
827 hapd.request("CHAN_SWITCH 5 5240 ht sec_channel_offset=-1 bandwidth=40")
828 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
830 raise Exception("CSA finished event timed out")
831 if "freq=5240" not in ev:
832 raise Exception("Unexpected channel in CSA finished event")
833 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
835 raise Exception("Unexpected STA disconnection during CSA")
836 hwsim_utils.test_connectivity(dev[0], hapd)
838 hapd.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
839 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
841 raise Exception("CSA finished event timed out")
842 if "freq=5180" not in ev:
843 raise Exception("Unexpected channel in CSA finished event")
844 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
846 raise Exception("Unexpected STA disconnection during CSA")
847 hwsim_utils.test_connectivity(dev[0], hapd)
849 dev[0].request("DISCONNECT")
851 hapd.request("DISABLE")
852 subprocess.call(['iw', 'reg', 'set', '00'])
853 dev[0].flush_scan_cache()
855 def test_ap_ht_smps(dev, apdev):
856 """SMPS AP configuration options"""
857 params = { "ssid": "ht1", "ht_capab": "[SMPS-STATIC]" }
859 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
861 raise HwsimSkip("Assume mac80211_hwsim was not recent enough to support SMPS")
862 params = { "ssid": "ht2", "ht_capab": "[SMPS-DYNAMIC]" }
863 hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
865 dev[0].connect("ht1", key_mgmt="NONE", scan_freq="2412")
866 dev[1].connect("ht2", key_mgmt="NONE", scan_freq="2412")
867 hwsim_utils.test_connectivity(dev[0], hapd)
868 hwsim_utils.test_connectivity(dev[1], hapd2)
870 def test_prefer_ht20(dev, apdev):
871 """Preference on HT20 over no-HT"""
872 params = { "ssid": "test",
875 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
876 bssid = apdev[0]['bssid']
877 params = { "ssid": "test",
880 hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
881 bssid2 = apdev[1]['bssid']
883 dev[0].scan_for_bss(bssid, freq=2412)
884 dev[0].scan_for_bss(bssid2, freq=2412)
885 dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
886 if dev[0].get_status_field('bssid') != bssid2:
887 raise Exception("Unexpected BSS selected")
889 est = dev[0].get_bss(bssid)['est_throughput']
891 raise Exception("Unexpected BSS0 est_throughput: " + est)
893 est = dev[0].get_bss(bssid2)['est_throughput']
895 raise Exception("Unexpected BSS1 est_throughput: " + est)
897 def test_prefer_ht40(dev, apdev):
898 """Preference on HT40 over HT20"""
899 params = { "ssid": "test",
902 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
903 bssid = apdev[0]['bssid']
904 params = { "ssid": "test",
907 "ht_capab": "[HT40+]" }
908 hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
909 bssid2 = apdev[1]['bssid']
911 dev[0].scan_for_bss(bssid, freq=2412)
912 dev[0].scan_for_bss(bssid2, freq=2412)
913 dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
914 if dev[0].get_status_field('bssid') != bssid2:
915 raise Exception("Unexpected BSS selected")
917 est = dev[0].get_bss(bssid)['est_throughput']
919 raise Exception("Unexpected BSS0 est_throughput: " + est)
921 est = dev[0].get_bss(bssid2)['est_throughput']
923 raise Exception("Unexpected BSS1 est_throughput: " + est)
925 def test_prefer_ht20_during_roam(dev, apdev):
926 """Preference on HT20 over no-HT in roaming consideration"""
927 params = { "ssid": "test",
930 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
931 bssid = apdev[0]['bssid']
933 dev[0].scan_for_bss(bssid, freq=2412)
934 dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
936 params = { "ssid": "test",
939 hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
940 bssid2 = apdev[1]['bssid']
941 dev[0].scan_for_bss(bssid2, freq=2412)
942 dev[0].scan(freq=2412)
943 dev[0].wait_connected()
945 if dev[0].get_status_field('bssid') != bssid2:
946 raise Exception("Unexpected BSS selected")