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.
7 from remotehost import remote_compatible
10 logger = logging.getLogger()
14 from utils import HwsimSkip, alloc_fail
16 from test_ap_csa import csa_supported
18 def clear_scan_cache(apdev):
19 ifname = apdev['ifname']
20 hostapd.cmd_execute(apdev, ['ifconfig', ifname, 'up'])
21 hostapd.cmd_execute(apdev, ['iw', ifname, 'scan', 'trigger', 'freq', '2412',
24 hostapd.cmd_execute(apdev, ['ifconfig', ifname, 'down'])
26 def set_world_reg(apdev0=None, apdev1=None, dev0=None):
28 hostapd.cmd_execute(apdev0, ['iw', 'reg', 'set', '00'])
30 hostapd.cmd_execute(apdev1, ['iw', 'reg', 'set', '00'])
32 dev0.cmd_execute(['iw', 'reg', 'set', '00'])
34 def test_ap_ht40_scan(dev, apdev):
36 clear_scan_cache(apdev[0])
37 params = { "ssid": "test-ht40",
39 "ht_capab": "[HT40-]"}
40 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
42 state = hapd.get_status_field("state")
43 if state != "HT_SCAN":
45 state = hapd.get_status_field("state")
46 if state != "HT_SCAN":
47 raise Exception("Unexpected interface state - expected HT_SCAN")
49 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
51 raise Exception("AP setup timed out")
53 state = hapd.get_status_field("state")
54 if state != "ENABLED":
55 raise Exception("Unexpected interface state - expected ENABLED")
57 freq = hapd.get_status_field("freq")
59 raise Exception("Unexpected frequency")
60 pri = hapd.get_status_field("channel")
62 raise Exception("Unexpected primary channel")
63 sec = hapd.get_status_field("secondary_channel")
65 raise Exception("Unexpected secondary channel")
67 dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
70 def test_ap_ht40_scan_conflict(dev, apdev):
71 """HT40 co-ex scan conflict"""
72 clear_scan_cache(apdev[0])
73 params = { "ssid": "test-ht40",
75 "ht_capab": "[HT40+]"}
76 hostapd.add_ap(apdev[1], params)
78 params = { "ssid": "test-ht40",
80 "ht_capab": "[HT40-]"}
81 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
83 state = hapd.get_status_field("state")
84 if state != "HT_SCAN":
86 state = hapd.get_status_field("state")
87 if state != "HT_SCAN":
88 raise Exception("Unexpected interface state - expected HT_SCAN")
90 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
92 raise Exception("AP setup timed out")
94 state = hapd.get_status_field("state")
95 if state != "ENABLED":
96 raise Exception("Unexpected interface state - expected ENABLED")
98 freq = hapd.get_status_field("freq")
100 raise Exception("Unexpected frequency")
101 pri = hapd.get_status_field("channel")
103 raise Exception("Unexpected primary channel")
104 sec = hapd.get_status_field("secondary_channel")
106 raise Exception("Unexpected secondary channel: " + sec)
108 dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
111 def test_ap_ht40_scan_conflict2(dev, apdev):
112 """HT40 co-ex scan conflict (HT40-)"""
113 clear_scan_cache(apdev[0])
114 params = { "ssid": "test-ht40",
116 "ht_capab": "[HT40-]"}
117 hostapd.add_ap(apdev[1], params)
119 params = { "ssid": "test-ht40",
121 "ht_capab": "[HT40+]"}
122 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
124 state = hapd.get_status_field("state")
125 if state != "HT_SCAN":
127 state = hapd.get_status_field("state")
128 if state != "HT_SCAN":
129 raise Exception("Unexpected interface state - expected HT_SCAN")
131 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
133 raise Exception("AP setup timed out")
135 state = hapd.get_status_field("state")
136 if state != "ENABLED":
137 raise Exception("Unexpected interface state - expected ENABLED")
139 freq = hapd.get_status_field("freq")
141 raise Exception("Unexpected frequency")
142 pri = hapd.get_status_field("channel")
144 raise Exception("Unexpected primary channel")
145 sec = hapd.get_status_field("secondary_channel")
147 raise Exception("Unexpected secondary channel: " + sec)
149 dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
151 def test_ap_ht40_scan_not_affected(dev, apdev):
152 """HT40 co-ex scan and other BSS not affected"""
153 clear_scan_cache(apdev[0])
154 params = { "ssid": "test-ht20",
156 hostapd.add_ap(apdev[1], params)
158 hostapd.cmd_execute(apdev[0], ['ifconfig', apdev[0]['ifname'], 'up'])
159 hostapd.cmd_execute(apdev[0], ['iw', apdev[0]['ifname'], 'scan', 'trigger',
162 hostapd.cmd_execute(apdev[0], ['iw', apdev[0]['ifname'], 'scan', 'dump'])
164 hostapd.cmd_execute(apdev[0], ['ifconfig', apdev[0]['ifname'], 'down'])
166 params = { "ssid": "test-ht40",
168 "ht_capab": "[HT40+]"}
169 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
171 state = hapd.get_status_field("state")
172 if state != "HT_SCAN":
174 state = hapd.get_status_field("state")
175 if state != "HT_SCAN":
176 raise Exception("Unexpected interface state - expected HT_SCAN")
178 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
180 raise Exception("AP setup timed out")
182 state = hapd.get_status_field("state")
183 if state != "ENABLED":
184 raise Exception("Unexpected interface state - expected ENABLED")
186 freq = hapd.get_status_field("freq")
188 raise Exception("Unexpected frequency")
189 pri = hapd.get_status_field("channel")
191 raise Exception("Unexpected primary channel")
192 sec = hapd.get_status_field("secondary_channel")
194 raise Exception("Unexpected secondary channel: " + sec)
196 dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
199 def test_ap_ht40_scan_legacy_conflict(dev, apdev):
200 """HT40 co-ex scan conflict with legacy 20 MHz AP"""
201 clear_scan_cache(apdev[0])
202 params = { "ssid": "legacy-20",
203 "channel": "7", "ieee80211n": "0" }
204 hostapd.add_ap(apdev[1], params)
206 params = { "ssid": "test-ht40",
208 "ht_capab": "[HT40-]"}
209 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
211 state = hapd.get_status_field("state")
212 if state != "HT_SCAN":
214 state = hapd.get_status_field("state")
215 if state != "HT_SCAN":
216 raise Exception("Unexpected interface state - expected HT_SCAN")
218 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
220 raise Exception("AP setup timed out")
222 state = hapd.get_status_field("state")
223 if state != "ENABLED":
224 raise Exception("Unexpected interface state - expected ENABLED")
226 freq = hapd.get_status_field("freq")
228 raise Exception("Unexpected frequency: " + freq)
229 pri = hapd.get_status_field("channel")
231 raise Exception("Unexpected primary channel: " + pri)
232 sec = hapd.get_status_field("secondary_channel")
234 raise Exception("Unexpected secondary channel: " + sec)
236 dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
239 def test_ap_ht40_scan_ht20_conflict(dev, apdev):
240 """HT40 co-ex scan conflict with HT 20 MHz AP"""
241 clear_scan_cache(apdev[0])
242 params = { "ssid": "ht-20",
243 "channel": "7", "ieee80211n": "1" }
244 hostapd.add_ap(apdev[1], params)
246 params = { "ssid": "test-ht40",
248 "ht_capab": "[HT40-]"}
249 hapd = hostapd.add_ap(apdev[0], 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 def test_ap_ht40_scan_intolerant(dev, apdev):
279 """HT40 co-ex scan finding an AP advertising 40 MHz intolerant"""
280 clear_scan_cache(apdev[0])
281 params = { "ssid": "another-bss",
283 "ht_capab": "[40-INTOLERANT]" }
284 hostapd.add_ap(apdev[1], params)
286 params = { "ssid": "test-ht40",
288 "ht_capab": "[HT40+]"}
289 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
291 state = hapd.get_status_field("state")
292 if state != "HT_SCAN":
294 state = hapd.get_status_field("state")
295 if state != "HT_SCAN":
296 raise Exception("Unexpected interface state - expected HT_SCAN")
298 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
300 raise Exception("AP setup timed out")
302 state = hapd.get_status_field("state")
303 if state != "ENABLED":
304 raise Exception("Unexpected interface state - expected ENABLED")
306 freq = hapd.get_status_field("freq")
308 raise Exception("Unexpected frequency: " + freq)
309 pri = hapd.get_status_field("channel")
311 raise Exception("Unexpected primary channel: " + pri)
312 sec = hapd.get_status_field("secondary_channel")
314 raise Exception("Unexpected secondary channel: " + sec)
316 dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
318 def test_ap_ht40_scan_match(dev, apdev):
319 """HT40 co-ex scan matching configuration"""
320 clear_scan_cache(apdev[0])
321 params = { "ssid": "test-ht40",
323 "ht_capab": "[HT40-]"}
324 hostapd.add_ap(apdev[1], params)
326 params = { "ssid": "test-ht40",
328 "ht_capab": "[HT40-]"}
329 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
331 state = hapd.get_status_field("state")
332 if state != "HT_SCAN":
334 state = hapd.get_status_field("state")
335 if state != "HT_SCAN":
336 raise Exception("Unexpected interface state - expected HT_SCAN")
338 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
340 raise Exception("AP setup timed out")
342 state = hapd.get_status_field("state")
343 if state != "ENABLED":
344 raise Exception("Unexpected interface state - expected ENABLED")
346 freq = hapd.get_status_field("freq")
348 raise Exception("Unexpected frequency")
349 pri = hapd.get_status_field("channel")
351 raise Exception("Unexpected primary channel")
352 sec = hapd.get_status_field("secondary_channel")
354 raise Exception("Unexpected secondary channel: " + sec)
356 dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
358 def test_ap_ht40_5ghz_match(dev, apdev):
359 """HT40 co-ex scan on 5 GHz with matching pri/sec channel"""
360 clear_scan_cache(apdev[0])
364 params = { "ssid": "test-ht40",
367 "country_code": "US",
368 "ht_capab": "[HT40+]"}
369 hapd2 = hostapd.add_ap(apdev[1], params)
371 params = { "ssid": "test-ht40",
374 "ht_capab": "[HT40+]"}
375 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
377 state = hapd.get_status_field("state")
378 if state != "HT_SCAN":
380 state = hapd.get_status_field("state")
381 if state != "HT_SCAN":
382 raise Exception("Unexpected interface state - expected HT_SCAN")
384 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
386 raise Exception("AP setup timed out")
388 state = hapd.get_status_field("state")
389 if state != "ENABLED":
390 raise Exception("Unexpected interface state - expected ENABLED")
392 freq = hapd.get_status_field("freq")
394 raise Exception("Unexpected frequency")
395 pri = hapd.get_status_field("channel")
397 raise Exception("Unexpected primary channel")
398 sec = hapd.get_status_field("secondary_channel")
400 raise Exception("Unexpected secondary channel: " + sec)
402 dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
404 dev[0].request("DISCONNECT")
406 hapd.request("DISABLE")
408 hapd2.request("DISABLE")
409 set_world_reg(apdev[0], apdev[1], dev[0])
410 dev[0].flush_scan_cache()
412 def test_ap_ht40_5ghz_switch(dev, apdev):
413 """HT40 co-ex scan on 5 GHz switching pri/sec channel"""
414 clear_scan_cache(apdev[0])
418 params = { "ssid": "test-ht40",
421 "country_code": "US",
422 "ht_capab": "[HT40+]"}
423 hapd2 = hostapd.add_ap(apdev[1], params)
425 params = { "ssid": "test-ht40",
428 "ht_capab": "[HT40-]"}
429 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
431 state = hapd.get_status_field("state")
432 if state != "HT_SCAN":
434 state = hapd.get_status_field("state")
435 if state != "HT_SCAN":
436 raise Exception("Unexpected interface state - expected HT_SCAN")
438 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
440 raise Exception("AP setup timed out")
442 state = hapd.get_status_field("state")
443 if state != "ENABLED":
444 raise Exception("Unexpected interface state - expected ENABLED")
446 freq = hapd.get_status_field("freq")
448 raise Exception("Unexpected frequency: " + freq)
449 pri = hapd.get_status_field("channel")
451 raise Exception("Unexpected primary channel: " + pri)
452 sec = hapd.get_status_field("secondary_channel")
454 raise Exception("Unexpected secondary channel: " + sec)
456 dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
458 dev[0].request("DISCONNECT")
460 hapd.request("DISABLE")
462 hapd2.request("DISABLE")
463 set_world_reg(apdev[0], apdev[1], dev[0])
465 def test_ap_ht40_5ghz_switch2(dev, apdev):
466 """HT40 co-ex scan on 5 GHz switching pri/sec channel (2)"""
467 clear_scan_cache(apdev[0])
471 params = { "ssid": "test-ht40",
474 "country_code": "US",
475 "ht_capab": "[HT40+]"}
476 hapd2 = hostapd.add_ap(apdev[1], params)
478 id = dev[0].add_network()
479 dev[0].set_network(id, "mode", "2")
480 dev[0].set_network_quoted(id, "ssid", "wpas-ap-open")
481 dev[0].set_network(id, "key_mgmt", "NONE")
482 dev[0].set_network(id, "frequency", "5200")
483 dev[0].set_network(id, "scan_freq", "5200")
484 dev[0].select_network(id)
487 params = { "ssid": "test-ht40",
490 "ht_capab": "[HT40-]"}
491 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
493 state = hapd.get_status_field("state")
494 if state != "HT_SCAN":
496 state = hapd.get_status_field("state")
497 if state != "HT_SCAN":
498 raise Exception("Unexpected interface state - expected HT_SCAN")
500 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
502 raise Exception("AP setup timed out")
504 state = hapd.get_status_field("state")
505 if state != "ENABLED":
506 raise Exception("Unexpected interface state - expected ENABLED")
508 freq = hapd.get_status_field("freq")
510 raise Exception("Unexpected frequency: " + freq)
511 pri = hapd.get_status_field("channel")
513 raise Exception("Unexpected primary channel: " + pri)
514 sec = hapd.get_status_field("secondary_channel")
516 raise Exception("Unexpected secondary channel: " + sec)
518 dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
520 dev[0].request("DISCONNECT")
522 hapd.request("DISABLE")
524 hapd2.request("DISABLE")
525 set_world_reg(apdev[0], apdev[1], dev[0])
526 dev[0].flush_scan_cache()
528 def test_obss_scan(dev, apdev):
529 """Overlapping BSS scan request"""
530 params = { "ssid": "obss-scan",
532 "ht_capab": "[HT40-]",
533 "obss_interval": "10" }
534 hapd = hostapd.add_ap(apdev[0], params)
536 params = { "ssid": "another-bss",
539 hostapd.add_ap(apdev[1], params)
540 run_obss_scan(hapd, dev)
542 def test_obss_scan_ht40_plus(dev, apdev):
543 """Overlapping BSS scan request (HT40+)"""
544 params = { "ssid": "obss-scan",
546 "ht_capab": "[HT40+]",
547 "obss_interval": "10" }
548 hapd = hostapd.add_ap(apdev[0], params)
550 params = { "ssid": "another-bss",
553 hostapd.add_ap(apdev[1], params)
554 run_obss_scan(hapd, dev)
556 def run_obss_scan(hapd, dev):
557 dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
558 hapd.set("ext_mgmt_frame_handling", "1")
559 logger.info("Waiting for OBSS scan to occur")
560 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=15)
562 raise Exception("Timed out while waiting for OBSS scan to start")
563 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
565 raise Exception("Timed out while waiting for OBSS scan results")
567 for i in range(0, 4):
568 frame = hapd.mgmt_rx(timeout=5)
570 raise Exception("MGMT RX wait timed out")
571 if frame['subtype'] != 13:
573 payload = frame['payload']
576 (category, action, ie) = struct.unpack('BBB', payload[0:3])
582 logger.info("20/40 BSS Coexistence report received")
586 raise Exception("20/40 BSS Coexistence report not seen")
588 def test_obss_scan_40_intolerant(dev, apdev):
589 """Overlapping BSS scan request with 40 MHz intolerant AP"""
590 params = { "ssid": "obss-scan",
592 "ht_capab": "[HT40-]",
593 "obss_interval": "10" }
594 hapd = hostapd.add_ap(apdev[0], params)
596 params = { "ssid": "another-bss",
598 "ht_capab": "[40-INTOLERANT]" }
599 hostapd.add_ap(apdev[1], params)
601 dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
602 hapd.set("ext_mgmt_frame_handling", "1")
603 logger.info("Waiting for OBSS scan to occur")
604 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=15)
606 raise Exception("Timed out while waiting for OBSS scan to start")
607 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
609 raise Exception("Timed out while waiting for OBSS scan results")
611 for i in range(0, 4):
612 frame = hapd.mgmt_rx(timeout=5)
614 raise Exception("MGMT RX wait timed out")
615 if frame['subtype'] != 13:
617 payload = frame['payload']
620 (category, action, ie) = struct.unpack('BBB', payload[0:3])
626 logger.info("20/40 BSS Coexistence report received")
630 raise Exception("20/40 BSS Coexistence report not seen")
632 def test_obss_coex_report_handling(dev, apdev):
633 """Overlapping BSS scan report handling with obss_interval=0"""
634 clear_scan_cache(apdev[0])
635 params = { "ssid": "obss-scan",
637 "ht_capab": "[HT40-]" }
638 hapd = hostapd.add_ap(apdev[0], params)
639 bssid = apdev[0]['bssid']
640 dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
642 sec = hapd.get_status_field("secondary_channel")
644 raise Exception("AP is not using 40 MHz channel")
646 # 20/40 MHz co-ex report tests: number of invalid reports and a valid report
647 # that forces 20 MHz channel.
648 tests = [ '0400', '040048', '04004801', '0400480000', '0400490100',
649 '040048ff0000', '04004801ff49ff00', '04004801004900',
650 '0400480100490101', '0400480100490201ff',
651 '040048010449020005' ]
653 req = "MGMT_TX {} {} freq=2437 action={}".format(bssid, bssid, msg)
654 if "OK" not in dev[0].request(req):
655 raise Exception("Could not send management frame")
657 sec = hapd.get_status_field("secondary_channel")
659 raise Exception("AP did not move to 20 MHz channel")
661 def test_obss_coex_report_handling1(dev, apdev):
662 """Overlapping BSS scan report handling with obss_interval=1"""
663 clear_scan_cache(apdev[0])
664 params = { "ssid": "obss-scan",
666 "ht_capab": "[HT40+]",
667 "obss_interval": "1" }
668 hapd = hostapd.add_ap(apdev[0], params)
669 bssid = apdev[0]['bssid']
670 dev[0].connect("obss-scan", key_mgmt="NONE", scan_freq="2437")
672 sec = hapd.get_status_field("secondary_channel")
674 raise Exception("AP is not using 40 MHz channel")
676 # 20/40 MHz co-ex report forcing 20 MHz channel
677 msg = '040048010449020005'
678 req = "MGMT_TX {} {} freq=2437 action={}".format(bssid, bssid, msg)
679 if "OK" not in dev[0].request(req):
680 raise Exception("Could not send management frame")
682 sec = hapd.get_status_field("secondary_channel")
684 raise Exception("AP did not move to 20 MHz channel")
686 # No 20/40 MHz co-ex reports forcing 20 MHz channel during next interval
688 sec = hapd.get_status_field("secondary_channel")
693 raise Exception("AP did not return to 40 MHz channel")
695 def test_olbc(dev, apdev):
697 params = { "ssid": "test-olbc",
699 "ht_capab": "[HT40-]",
700 "ap_table_expiration_time": "2" }
701 hapd = hostapd.add_ap(apdev[0], params)
702 status = hapd.get_status()
703 if status['olbc'] != '0' or status['olbc_ht'] != '0':
704 raise Exception("Unexpected OLBC information")
706 params = { "ssid": "olbc-ap",
710 hostapd.add_ap(apdev[1], params)
712 status = hapd.get_status()
713 if status['olbc'] != '1' or status['olbc_ht'] != '1':
714 raise Exception("Missing OLBC information")
716 hostapd.remove_bss(apdev[1])
718 logger.info("Waiting for OLBC state to time out")
720 for i in range(0, 15):
722 status = hapd.get_status()
723 if status['olbc'] == '0' and status['olbc_ht'] == '0':
727 raise Exception("OLBC state did nto time out")
729 def test_olbc_table_limit(dev, apdev):
730 """OLBC AP table size limit"""
731 ifname1 = apdev[0]['ifname']
732 ifname2 = apdev[0]['ifname'] + '-2'
733 ifname3 = apdev[0]['ifname'] + '-3'
734 hostapd.add_bss(apdev[0], ifname1, 'bss-1.conf')
735 hostapd.add_bss(apdev[0], ifname2, 'bss-2.conf')
736 hostapd.add_bss(apdev[0], ifname3, 'bss-3.conf')
738 params = { "ssid": "test-olbc",
740 "ap_table_max_size": "2" }
741 hapd = hostapd.add_ap(apdev[1], params)
744 with alloc_fail(hapd, 1, "ap_list_process_beacon"):
746 hapd.set("ap_table_max_size", "1")
748 hapd.set("ap_table_max_size", "0")
751 def test_olbc_5ghz(dev, apdev):
752 """OLBC detection on 5 GHz"""
756 params = { "ssid": "test-olbc",
757 "country_code": "FI",
760 "ht_capab": "[HT40+]" }
761 hapd = hostapd.add_ap(apdev[0], params)
762 status = hapd.get_status()
763 if status['olbc'] != '0' or status['olbc_ht'] != '0':
764 raise Exception("Unexpected OLBC information")
766 params = { "ssid": "olbc-ap",
767 "country_code": "FI",
772 hapd2 = hostapd.add_ap(apdev[1], params)
776 status = hapd.get_status()
777 logger.debug('olbc_ht: ' + status['olbc_ht'])
778 if status['olbc_ht'] == '1':
782 raise Exception("Missing OLBC information")
785 hapd.request("DISABLE")
787 hapd2.request("DISABLE")
788 set_world_reg(apdev[0], apdev[1], None)
790 def test_ap_require_ht(dev, apdev):
792 params = { "ssid": "require-ht",
794 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
796 dev[1].connect("require-ht", key_mgmt="NONE", scan_freq="2412",
797 disable_ht="1", wait_connect=False)
798 dev[0].connect("require-ht", key_mgmt="NONE", scan_freq="2412")
799 ev = dev[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
800 dev[1].request("DISCONNECT")
802 raise Exception("Association rejection timed out")
803 if "status_code=27" not in ev:
804 raise Exception("Unexpected rejection status code")
805 dev[2].connect("require-ht", key_mgmt="NONE", scan_freq="2412",
806 ht_mcs="0x01 00 00 00 00 00 00 00 00 00",
807 disable_max_amsdu="1", ampdu_factor="2",
808 ampdu_density="1", disable_ht40="1", disable_sgi="1",
812 def test_ap_require_ht_limited_rates(dev, apdev):
813 """Require HT with limited supported rates"""
814 params = { "ssid": "require-ht",
815 "supported_rates": "60 120 240 360 480 540",
817 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
819 dev[1].connect("require-ht", key_mgmt="NONE", scan_freq="2412",
820 disable_ht="1", wait_connect=False)
821 dev[0].connect("require-ht", key_mgmt="NONE", scan_freq="2412")
822 ev = dev[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
823 dev[1].request("DISCONNECT")
825 raise Exception("Association rejection timed out")
826 if "status_code=27" not in ev:
827 raise Exception("Unexpected rejection status code")
830 def test_ap_ht_capab_not_supported(dev, apdev):
831 """HT configuration with driver not supporting all ht_capab entries"""
832 params = { "ssid": "test-ht40",
834 "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]"}
835 hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
836 if "FAIL" not in hapd.request("ENABLE"):
837 raise Exception("Unexpected ENABLE success")
839 def test_ap_ht_40mhz_intolerant_sta(dev, apdev):
840 """Associated STA indicating 40 MHz intolerant"""
841 clear_scan_cache(apdev[0])
842 params = { "ssid": "intolerant",
844 "ht_capab": "[HT40-]" }
845 hapd = hostapd.add_ap(apdev[0], params)
846 if hapd.get_status_field("num_sta_ht40_intolerant") != "0":
847 raise Exception("Unexpected num_sta_ht40_intolerant value")
848 if hapd.get_status_field("secondary_channel") != "-1":
849 raise Exception("Unexpected secondary_channel")
851 dev[0].connect("intolerant", key_mgmt="NONE", scan_freq="2437")
852 if hapd.get_status_field("num_sta_ht40_intolerant") != "0":
853 raise Exception("Unexpected num_sta_ht40_intolerant value")
854 if hapd.get_status_field("secondary_channel") != "-1":
855 raise Exception("Unexpected secondary_channel")
857 dev[2].connect("intolerant", key_mgmt="NONE", scan_freq="2437",
860 if hapd.get_status_field("num_sta_ht40_intolerant") != "1":
861 raise Exception("Unexpected num_sta_ht40_intolerant value (expected 1)")
862 if hapd.get_status_field("secondary_channel") != "0":
863 raise Exception("Unexpected secondary_channel (did not disable 40 MHz)")
865 dev[2].request("DISCONNECT")
867 if hapd.get_status_field("num_sta_ht40_intolerant") != "0":
868 raise Exception("Unexpected num_sta_ht40_intolerant value (expected 0)")
869 if hapd.get_status_field("secondary_channel") != "-1":
870 raise Exception("Unexpected secondary_channel (did not re-enable 40 MHz)")
872 def test_ap_ht_40mhz_intolerant_ap(dev, apdev):
873 """Associated STA reports 40 MHz intolerant AP after association"""
874 clear_scan_cache(apdev[0])
875 params = { "ssid": "ht",
877 "ht_capab": "[HT40-]",
878 "obss_interval": "3" }
879 hapd = hostapd.add_ap(apdev[0], params)
881 dev[0].connect("ht", key_mgmt="NONE", scan_freq="2437")
883 if hapd.get_status_field("secondary_channel") != "-1":
884 raise Exception("Unexpected secondary channel information")
886 logger.info("Start 40 MHz intolerant AP")
887 params = { "ssid": "intolerant",
889 "ht_capab": "[40-INTOLERANT]" }
890 hapd2 = hostapd.add_ap(apdev[1], params)
892 logger.info("Waiting for co-ex report from STA")
894 for i in range(0, 20):
896 if hapd.get_status_field("secondary_channel") == "0":
897 logger.info("AP moved to 20 MHz channel")
901 raise Exception("AP did not move to 20 MHz channel")
903 if "OK" not in hapd2.request("DISABLE"):
904 raise Exception("Failed to disable 40 MHz intolerant AP")
906 # make sure the intolerant AP disappears from scan results more quickly
907 dev[0].scan(type="ONLY", freq="2432", only_new=True)
908 dev[0].scan(type="ONLY", freq="2432", only_new=True)
909 dev[0].dump_monitor()
911 logger.info("Waiting for AP to move back to 40 MHz channel")
913 for i in range(0, 30):
915 if hapd.get_status_field("secondary_channel") == "-1":
916 logger.info("AP moved to 40 MHz channel")
920 raise Exception("AP did not move to 40 MHz channel")
922 def test_ap_ht40_csa(dev, apdev):
923 """HT with 40 MHz channel width and CSA"""
924 csa_supported(dev[0])
927 params = { "ssid": "ht",
928 "country_code": "US",
931 "ht_capab": "[HT40+]",
933 hapd = hostapd.add_ap(apdev[0], params)
935 dev[0].connect("ht", key_mgmt="NONE", scan_freq="5180")
936 hwsim_utils.test_connectivity(dev[0], hapd)
938 hapd.request("CHAN_SWITCH 5 5200 ht sec_channel_offset=-1 bandwidth=40")
939 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
941 raise Exception("CSA finished event timed out")
942 if "freq=5200" not in ev:
943 raise Exception("Unexpected channel in CSA finished event")
944 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
946 raise Exception("Unexpected STA disconnection during CSA")
947 hwsim_utils.test_connectivity(dev[0], hapd)
949 hapd.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
950 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
952 raise Exception("CSA finished event timed out")
953 if "freq=5180" not in ev:
954 raise Exception("Unexpected channel in CSA finished event")
955 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
957 raise Exception("Unexpected STA disconnection during CSA")
958 hwsim_utils.test_connectivity(dev[0], hapd)
960 dev[0].request("DISCONNECT")
962 hapd.request("DISABLE")
963 set_world_reg(apdev[0], None, dev[0])
964 dev[0].flush_scan_cache()
966 def test_ap_ht40_csa2(dev, apdev):
967 """HT with 40 MHz channel width and CSA"""
968 csa_supported(dev[0])
971 params = { "ssid": "ht",
972 "country_code": "US",
975 "ht_capab": "[HT40+]",
977 hapd = hostapd.add_ap(apdev[0], params)
979 dev[0].connect("ht", key_mgmt="NONE", scan_freq="5180")
980 hwsim_utils.test_connectivity(dev[0], hapd)
982 hapd.request("CHAN_SWITCH 5 5220 ht sec_channel_offset=1 bandwidth=40")
983 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
985 raise Exception("CSA finished event timed out")
986 if "freq=5220" not in ev:
987 raise Exception("Unexpected channel in CSA finished event")
988 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
990 raise Exception("Unexpected STA disconnection during CSA")
991 hwsim_utils.test_connectivity(dev[0], hapd)
993 hapd.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
994 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
996 raise Exception("CSA finished event timed out")
997 if "freq=5180" not in ev:
998 raise Exception("Unexpected channel in CSA finished event")
999 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
1001 raise Exception("Unexpected STA disconnection during CSA")
1002 hwsim_utils.test_connectivity(dev[0], hapd)
1004 dev[0].request("DISCONNECT")
1006 hapd.request("DISABLE")
1007 set_world_reg(apdev[0], None, dev[0])
1008 dev[0].flush_scan_cache()
1010 def test_ap_ht40_csa3(dev, apdev):
1011 """HT with 40 MHz channel width and CSA"""
1012 csa_supported(dev[0])
1015 params = { "ssid": "ht",
1016 "country_code": "US",
1019 "ht_capab": "[HT40+]",
1021 hapd = hostapd.add_ap(apdev[0], params)
1023 dev[0].connect("ht", key_mgmt="NONE", scan_freq="5180")
1024 hwsim_utils.test_connectivity(dev[0], hapd)
1026 hapd.request("CHAN_SWITCH 5 5240 ht sec_channel_offset=-1 bandwidth=40")
1027 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
1029 raise Exception("CSA finished event timed out")
1030 if "freq=5240" not in ev:
1031 raise Exception("Unexpected channel in CSA finished event")
1032 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
1034 raise Exception("Unexpected STA disconnection during CSA")
1035 hwsim_utils.test_connectivity(dev[0], hapd)
1037 hapd.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
1038 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
1040 raise Exception("CSA finished event timed out")
1041 if "freq=5180" not in ev:
1042 raise Exception("Unexpected channel in CSA finished event")
1043 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
1045 raise Exception("Unexpected STA disconnection during CSA")
1046 hwsim_utils.test_connectivity(dev[0], hapd)
1048 dev[0].request("DISCONNECT")
1050 hapd.request("DISABLE")
1051 set_world_reg(apdev[0], None, dev[0])
1052 dev[0].flush_scan_cache()
1055 def test_ap_ht_smps(dev, apdev):
1056 """SMPS AP configuration options"""
1057 params = { "ssid": "ht1", "ht_capab": "[SMPS-STATIC]" }
1059 hapd = hostapd.add_ap(apdev[0], params)
1061 raise HwsimSkip("Assume mac80211_hwsim was not recent enough to support SMPS")
1062 params = { "ssid": "ht2", "ht_capab": "[SMPS-DYNAMIC]" }
1063 hapd2 = hostapd.add_ap(apdev[1], params)
1065 dev[0].connect("ht1", key_mgmt="NONE", scan_freq="2412")
1066 dev[1].connect("ht2", key_mgmt="NONE", scan_freq="2412")
1067 hwsim_utils.test_connectivity(dev[0], hapd)
1068 hwsim_utils.test_connectivity(dev[1], hapd2)
1071 def test_prefer_ht20(dev, apdev):
1072 """Preference on HT20 over no-HT"""
1073 params = { "ssid": "test",
1076 hapd = hostapd.add_ap(apdev[0], params)
1077 bssid = apdev[0]['bssid']
1078 params = { "ssid": "test",
1081 hapd2 = hostapd.add_ap(apdev[1], params)
1082 bssid2 = apdev[1]['bssid']
1084 dev[0].scan_for_bss(bssid, freq=2412)
1085 dev[0].scan_for_bss(bssid2, freq=2412)
1086 dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
1087 if dev[0].get_status_field('bssid') != bssid2:
1088 raise Exception("Unexpected BSS selected")
1090 est = dev[0].get_bss(bssid)['est_throughput']
1092 raise Exception("Unexpected BSS0 est_throughput: " + est)
1094 est = dev[0].get_bss(bssid2)['est_throughput']
1096 raise Exception("Unexpected BSS1 est_throughput: " + est)
1098 def test_prefer_ht40(dev, apdev):
1099 """Preference on HT40 over HT20"""
1100 params = { "ssid": "test",
1103 hapd = hostapd.add_ap(apdev[0], params)
1104 bssid = apdev[0]['bssid']
1105 params = { "ssid": "test",
1108 "ht_capab": "[HT40+]" }
1109 hapd2 = hostapd.add_ap(apdev[1], params)
1110 bssid2 = apdev[1]['bssid']
1112 dev[0].scan_for_bss(bssid, freq=2412)
1113 dev[0].scan_for_bss(bssid2, freq=2412)
1114 dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
1115 if dev[0].get_status_field('bssid') != bssid2:
1116 raise Exception("Unexpected BSS selected")
1118 est = dev[0].get_bss(bssid)['est_throughput']
1120 raise Exception("Unexpected BSS0 est_throughput: " + est)
1122 est = dev[0].get_bss(bssid2)['est_throughput']
1124 raise Exception("Unexpected BSS1 est_throughput: " + est)
1127 def test_prefer_ht20_during_roam(dev, apdev):
1128 """Preference on HT20 over no-HT in roaming consideration"""
1129 params = { "ssid": "test",
1132 hapd = hostapd.add_ap(apdev[0], params)
1133 bssid = apdev[0]['bssid']
1135 dev[0].scan_for_bss(bssid, freq=2412)
1136 dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
1138 params = { "ssid": "test",
1141 hapd2 = hostapd.add_ap(apdev[1], params)
1142 bssid2 = apdev[1]['bssid']
1143 dev[0].scan_for_bss(bssid2, freq=2412)
1144 dev[0].scan(freq=2412)
1145 dev[0].wait_connected()
1147 if dev[0].get_status_field('bssid') != bssid2:
1148 raise Exception("Unexpected BSS selected")
1151 def test_ap_ht40_5ghz_invalid_pair(dev, apdev):
1152 """HT40 on 5 GHz with invalid channel pair"""
1153 clear_scan_cache(apdev[0])
1155 params = { "ssid": "test-ht40",
1158 "country_code": "US",
1159 "ht_capab": "[HT40+]"}
1160 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
1161 ev = hapd.wait_event(["AP-DISABLED", "AP-ENABLED"], timeout=10)
1163 raise Exception("AP setup failure timed out")
1164 if "AP-ENABLED" in ev:
1165 sec = hapd.get_status_field("secondary_channel")
1167 raise Exception("Invalid 40 MHz channel accepted")
1169 set_world_reg(apdev[0], None, None)
1172 def test_ap_ht40_5ghz_disabled_sec(dev, apdev):
1173 """HT40 on 5 GHz with disabled secondary channel"""
1174 clear_scan_cache(apdev[0])
1176 params = { "ssid": "test-ht40",
1179 "country_code": "US",
1180 "ht_capab": "[HT40+]"}
1181 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
1182 ev = hapd.wait_event(["AP-DISABLED", "AP-ENABLED"], timeout=10)
1184 raise Exception("AP setup failure timed out")
1185 if "AP-ENABLED" in ev:
1186 sec = hapd.get_status_field("secondary_channel")
1188 raise Exception("Invalid 40 MHz channel accepted")
1190 set_world_reg(apdev[0], None, None)
1192 def test_ap_ht40_scan_broken_ap(dev, apdev):
1193 """HT40 co-ex scan and broken legacy/HT AP"""
1194 clear_scan_cache(apdev[0])
1196 # Broken AP: Include HT Capabilities element but not HT Operation element
1197 params = { "ssid": "legacy-20",
1198 "channel": "7", "ieee80211n": "0",
1200 "vendor_elements": "2d1a0e001bffff000000000000000000000100000000000000000000" }
1201 hapd2 = hostapd.add_ap(apdev[1], params)
1203 params = { "ssid": "test-ht40",
1205 "ht_capab": "[HT40-]"}
1206 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
1208 state = hapd.get_status_field("state")
1209 if state != "HT_SCAN":
1211 state = hapd.get_status_field("state")
1212 if state != "HT_SCAN":
1213 raise Exception("Unexpected interface state - expected HT_SCAN")
1215 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
1217 raise Exception("AP setup timed out")
1219 state = hapd.get_status_field("state")
1220 if state != "ENABLED":
1221 raise Exception("Unexpected interface state - expected ENABLED")
1223 freq = hapd.get_status_field("freq")
1225 raise Exception("Unexpected frequency: " + freq)
1226 pri = hapd.get_status_field("channel")
1228 raise Exception("Unexpected primary channel: " + pri)
1229 sec = hapd.get_status_field("secondary_channel")
1231 raise Exception("Unexpected secondary channel: " + sec)
1233 dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq)
1234 dev[1].connect("legacy-20", key_mgmt="NONE", scan_freq="2442")
1235 hwsim_utils.test_connectivity(dev[0], hapd)
1236 hwsim_utils.test_connectivity(dev[1], hapd2)