]>
git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_ap_ht.py
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
)
541 dev
[0].connect("obss-scan", key_mgmt
="NONE", scan_freq
="2437")
542 hapd
.set("ext_mgmt_frame_handling", "1")
543 logger
.info("Waiting for OBSS scan to occur")
544 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=15)
546 raise Exception("Timed out while waiting for OBSS scan to start")
547 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout
=10)
549 raise Exception("Timed out while waiting for OBSS scan results")
551 for i
in range(0, 4):
552 frame
= hapd
.mgmt_rx(timeout
=5)
554 raise Exception("MGMT RX wait timed out")
555 if frame
['subtype'] != 13:
557 payload
= frame
['payload']
560 (category
, action
, ie
) = struct
.unpack('BBB', payload
[0:3])
566 logger
.info("20/40 BSS Coexistence report received")
570 raise Exception("20/40 BSS Coexistence report not seen")
572 def test_obss_scan_40_intolerant(dev
, apdev
):
573 """Overlapping BSS scan request with 40 MHz intolerant AP"""
574 params
= { "ssid": "obss-scan",
576 "ht_capab": "[HT40-]",
577 "obss_interval": "10" }
578 hapd
= hostapd
.add_ap(apdev
[0], params
)
580 params
= { "ssid": "another-bss",
582 "ht_capab": "[40-INTOLERANT]" }
583 hostapd
.add_ap(apdev
[1], params
)
585 dev
[0].connect("obss-scan", key_mgmt
="NONE", scan_freq
="2437")
586 hapd
.set("ext_mgmt_frame_handling", "1")
587 logger
.info("Waiting for OBSS scan to occur")
588 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=15)
590 raise Exception("Timed out while waiting for OBSS scan to start")
591 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout
=10)
593 raise Exception("Timed out while waiting for OBSS scan results")
595 for i
in range(0, 4):
596 frame
= hapd
.mgmt_rx(timeout
=5)
598 raise Exception("MGMT RX wait timed out")
599 if frame
['subtype'] != 13:
601 payload
= frame
['payload']
604 (category
, action
, ie
) = struct
.unpack('BBB', payload
[0:3])
610 logger
.info("20/40 BSS Coexistence report received")
614 raise Exception("20/40 BSS Coexistence report not seen")
616 def test_obss_coex_report_handling(dev
, apdev
):
617 """Overlapping BSS scan report handling with obss_interval=0"""
618 clear_scan_cache(apdev
[0])
619 params
= { "ssid": "obss-scan",
621 "ht_capab": "[HT40-]" }
622 hapd
= hostapd
.add_ap(apdev
[0], params
)
623 bssid
= apdev
[0]['bssid']
624 dev
[0].connect("obss-scan", key_mgmt
="NONE", scan_freq
="2437")
626 sec
= hapd
.get_status_field("secondary_channel")
628 raise Exception("AP is not using 40 MHz channel")
630 # 20/40 MHz co-ex report tests: number of invalid reports and a valid report
631 # that forces 20 MHz channel.
632 tests
= [ '0400', '040048', '04004801', '0400480000', '0400490100',
633 '040048ff0000', '04004801ff49ff00', '04004801004900',
634 '0400480100490101', '0400480100490201ff',
635 '040048010449020005' ]
637 req
= "MGMT_TX {} {} freq=2437 action={}".format(bssid
, bssid
, msg
)
638 if "OK" not in dev
[0].request(req
):
639 raise Exception("Could not send management frame")
641 sec
= hapd
.get_status_field("secondary_channel")
643 raise Exception("AP did not move to 20 MHz channel")
645 def test_obss_coex_report_handling1(dev
, apdev
):
646 """Overlapping BSS scan report handling with obss_interval=1"""
647 clear_scan_cache(apdev
[0])
648 params
= { "ssid": "obss-scan",
650 "ht_capab": "[HT40+]",
651 "obss_interval": "1" }
652 hapd
= hostapd
.add_ap(apdev
[0], params
)
653 bssid
= apdev
[0]['bssid']
654 dev
[0].connect("obss-scan", key_mgmt
="NONE", scan_freq
="2437")
656 sec
= hapd
.get_status_field("secondary_channel")
658 raise Exception("AP is not using 40 MHz channel")
660 # 20/40 MHz co-ex report forcing 20 MHz channel
661 msg
= '040048010449020005'
662 req
= "MGMT_TX {} {} freq=2437 action={}".format(bssid
, bssid
, msg
)
663 if "OK" not in dev
[0].request(req
):
664 raise Exception("Could not send management frame")
666 sec
= hapd
.get_status_field("secondary_channel")
668 raise Exception("AP did not move to 20 MHz channel")
670 # No 20/40 MHz co-ex reports forcing 20 MHz channel during next interval
672 sec
= hapd
.get_status_field("secondary_channel")
677 raise Exception("AP did not return to 40 MHz channel")
679 def test_olbc(dev
, apdev
):
681 params
= { "ssid": "test-olbc",
683 "ht_capab": "[HT40-]",
684 "ap_table_expiration_time": "2" }
685 hapd
= hostapd
.add_ap(apdev
[0], params
)
686 status
= hapd
.get_status()
687 if status
['olbc'] != '0' or status
['olbc_ht'] != '0':
688 raise Exception("Unexpected OLBC information")
690 params
= { "ssid": "olbc-ap",
694 hostapd
.add_ap(apdev
[1], params
)
696 status
= hapd
.get_status()
697 if status
['olbc'] != '1' or status
['olbc_ht'] != '1':
698 raise Exception("Missing OLBC information")
700 hostapd
.remove_bss(apdev
[1])
702 logger
.info("Waiting for OLBC state to time out")
704 for i
in range(0, 15):
706 status
= hapd
.get_status()
707 if status
['olbc'] == '0' and status
['olbc_ht'] == '0':
711 raise Exception("OLBC state did nto time out")
713 def test_olbc_table_limit(dev
, apdev
):
714 """OLBC AP table size limit"""
715 ifname1
= apdev
[0]['ifname']
716 ifname2
= apdev
[0]['ifname'] + '-2'
717 ifname3
= apdev
[0]['ifname'] + '-3'
718 hostapd
.add_bss(apdev
[0], ifname1
, 'bss-1.conf')
719 hostapd
.add_bss(apdev
[0], ifname2
, 'bss-2.conf')
720 hostapd
.add_bss(apdev
[0], ifname3
, 'bss-3.conf')
722 params
= { "ssid": "test-olbc",
724 "ap_table_max_size": "2" }
725 hapd
= hostapd
.add_ap(apdev
[1], params
)
728 with
alloc_fail(hapd
, 1, "ap_list_process_beacon"):
730 hapd
.set("ap_table_max_size", "1")
732 hapd
.set("ap_table_max_size", "0")
735 def test_olbc_5ghz(dev
, apdev
):
736 """OLBC detection on 5 GHz"""
740 params
= { "ssid": "test-olbc",
741 "country_code": "FI",
744 "ht_capab": "[HT40+]" }
745 hapd
= hostapd
.add_ap(apdev
[0], params
)
746 status
= hapd
.get_status()
747 if status
['olbc'] != '0' or status
['olbc_ht'] != '0':
748 raise Exception("Unexpected OLBC information")
750 params
= { "ssid": "olbc-ap",
751 "country_code": "FI",
756 hapd2
= hostapd
.add_ap(apdev
[1], params
)
760 status
= hapd
.get_status()
761 logger
.debug('olbc_ht: ' + status
['olbc_ht'])
762 if status
['olbc_ht'] == '1':
766 raise Exception("Missing OLBC information")
769 hapd
.request("DISABLE")
771 hapd2
.request("DISABLE")
772 set_world_reg(apdev
[0], apdev
[1], None)
774 def test_ap_require_ht(dev
, apdev
):
776 params
= { "ssid": "require-ht",
778 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
780 dev
[1].connect("require-ht", key_mgmt
="NONE", scan_freq
="2412",
781 disable_ht
="1", wait_connect
=False)
782 dev
[0].connect("require-ht", key_mgmt
="NONE", scan_freq
="2412")
783 ev
= dev
[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
784 dev
[1].request("DISCONNECT")
786 raise Exception("Association rejection timed out")
787 if "status_code=27" not in ev
:
788 raise Exception("Unexpected rejection status code")
789 dev
[2].connect("require-ht", key_mgmt
="NONE", scan_freq
="2412",
790 ht_mcs
="0x01 00 00 00 00 00 00 00 00 00",
791 disable_max_amsdu
="1", ampdu_factor
="2",
792 ampdu_density
="1", disable_ht40
="1", disable_sgi
="1",
796 def test_ap_require_ht_limited_rates(dev
, apdev
):
797 """Require HT with limited supported rates"""
798 params
= { "ssid": "require-ht",
799 "supported_rates": "60 120 240 360 480 540",
801 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
803 dev
[1].connect("require-ht", key_mgmt
="NONE", scan_freq
="2412",
804 disable_ht
="1", wait_connect
=False)
805 dev
[0].connect("require-ht", key_mgmt
="NONE", scan_freq
="2412")
806 ev
= dev
[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
807 dev
[1].request("DISCONNECT")
809 raise Exception("Association rejection timed out")
810 if "status_code=27" not in ev
:
811 raise Exception("Unexpected rejection status code")
814 def test_ap_ht_capab_not_supported(dev
, apdev
):
815 """HT configuration with driver not supporting all ht_capab entries"""
816 params
= { "ssid": "test-ht40",
818 "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]"}
819 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
820 if "FAIL" not in hapd
.request("ENABLE"):
821 raise Exception("Unexpected ENABLE success")
823 def test_ap_ht_40mhz_intolerant_sta(dev
, apdev
):
824 """Associated STA indicating 40 MHz intolerant"""
825 clear_scan_cache(apdev
[0])
826 params
= { "ssid": "intolerant",
828 "ht_capab": "[HT40-]" }
829 hapd
= hostapd
.add_ap(apdev
[0], params
)
830 if hapd
.get_status_field("num_sta_ht40_intolerant") != "0":
831 raise Exception("Unexpected num_sta_ht40_intolerant value")
832 if hapd
.get_status_field("secondary_channel") != "-1":
833 raise Exception("Unexpected secondary_channel")
835 dev
[0].connect("intolerant", key_mgmt
="NONE", scan_freq
="2437")
836 if hapd
.get_status_field("num_sta_ht40_intolerant") != "0":
837 raise Exception("Unexpected num_sta_ht40_intolerant value")
838 if hapd
.get_status_field("secondary_channel") != "-1":
839 raise Exception("Unexpected secondary_channel")
841 dev
[2].connect("intolerant", key_mgmt
="NONE", scan_freq
="2437",
844 if hapd
.get_status_field("num_sta_ht40_intolerant") != "1":
845 raise Exception("Unexpected num_sta_ht40_intolerant value (expected 1)")
846 if hapd
.get_status_field("secondary_channel") != "0":
847 raise Exception("Unexpected secondary_channel (did not disable 40 MHz)")
849 dev
[2].request("DISCONNECT")
851 if hapd
.get_status_field("num_sta_ht40_intolerant") != "0":
852 raise Exception("Unexpected num_sta_ht40_intolerant value (expected 0)")
853 if hapd
.get_status_field("secondary_channel") != "-1":
854 raise Exception("Unexpected secondary_channel (did not re-enable 40 MHz)")
856 def test_ap_ht_40mhz_intolerant_ap(dev
, apdev
):
857 """Associated STA reports 40 MHz intolerant AP after association"""
858 clear_scan_cache(apdev
[0])
859 params
= { "ssid": "ht",
861 "ht_capab": "[HT40-]",
862 "obss_interval": "3" }
863 hapd
= hostapd
.add_ap(apdev
[0], params
)
865 dev
[0].connect("ht", key_mgmt
="NONE", scan_freq
="2437")
867 if hapd
.get_status_field("secondary_channel") != "-1":
868 raise Exception("Unexpected secondary channel information")
870 logger
.info("Start 40 MHz intolerant AP")
871 params
= { "ssid": "intolerant",
873 "ht_capab": "[40-INTOLERANT]" }
874 hapd2
= hostapd
.add_ap(apdev
[1], params
)
876 logger
.info("Waiting for co-ex report from STA")
878 for i
in range(0, 20):
880 if hapd
.get_status_field("secondary_channel") == "0":
881 logger
.info("AP moved to 20 MHz channel")
885 raise Exception("AP did not move to 20 MHz channel")
887 if "OK" not in hapd2
.request("DISABLE"):
888 raise Exception("Failed to disable 40 MHz intolerant AP")
890 # make sure the intolerant AP disappears from scan results more quickly
891 dev
[0].scan(type="ONLY", freq
="2432", only_new
=True)
892 dev
[0].scan(type="ONLY", freq
="2432", only_new
=True)
893 dev
[0].dump_monitor()
895 logger
.info("Waiting for AP to move back to 40 MHz channel")
897 for i
in range(0, 30):
899 if hapd
.get_status_field("secondary_channel") == "-1":
900 logger
.info("AP moved to 40 MHz channel")
904 raise Exception("AP did not move to 40 MHz channel")
906 def test_ap_ht40_csa(dev
, apdev
):
907 """HT with 40 MHz channel width and CSA"""
908 csa_supported(dev
[0])
911 params
= { "ssid": "ht",
912 "country_code": "US",
915 "ht_capab": "[HT40+]",
917 hapd
= hostapd
.add_ap(apdev
[0], params
)
919 dev
[0].connect("ht", key_mgmt
="NONE", scan_freq
="5180")
920 hwsim_utils
.test_connectivity(dev
[0], hapd
)
922 hapd
.request("CHAN_SWITCH 5 5200 ht sec_channel_offset=-1 bandwidth=40")
923 ev
= hapd
.wait_event(["AP-CSA-FINISHED"], timeout
=10)
925 raise Exception("CSA finished event timed out")
926 if "freq=5200" not in ev
:
927 raise Exception("Unexpected channel in CSA finished event")
928 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=0.5)
930 raise Exception("Unexpected STA disconnection during CSA")
931 hwsim_utils
.test_connectivity(dev
[0], hapd
)
933 hapd
.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
934 ev
= hapd
.wait_event(["AP-CSA-FINISHED"], timeout
=10)
936 raise Exception("CSA finished event timed out")
937 if "freq=5180" not in ev
:
938 raise Exception("Unexpected channel in CSA finished event")
939 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=0.5)
941 raise Exception("Unexpected STA disconnection during CSA")
942 hwsim_utils
.test_connectivity(dev
[0], hapd
)
944 dev
[0].request("DISCONNECT")
946 hapd
.request("DISABLE")
947 set_world_reg(apdev
[0], None, dev
[0])
948 dev
[0].flush_scan_cache()
950 def test_ap_ht40_csa2(dev
, apdev
):
951 """HT with 40 MHz channel width and CSA"""
952 csa_supported(dev
[0])
955 params
= { "ssid": "ht",
956 "country_code": "US",
959 "ht_capab": "[HT40+]",
961 hapd
= hostapd
.add_ap(apdev
[0], params
)
963 dev
[0].connect("ht", key_mgmt
="NONE", scan_freq
="5180")
964 hwsim_utils
.test_connectivity(dev
[0], hapd
)
966 hapd
.request("CHAN_SWITCH 5 5220 ht sec_channel_offset=1 bandwidth=40")
967 ev
= hapd
.wait_event(["AP-CSA-FINISHED"], timeout
=10)
969 raise Exception("CSA finished event timed out")
970 if "freq=5220" not in ev
:
971 raise Exception("Unexpected channel in CSA finished event")
972 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=0.5)
974 raise Exception("Unexpected STA disconnection during CSA")
975 hwsim_utils
.test_connectivity(dev
[0], hapd
)
977 hapd
.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
978 ev
= hapd
.wait_event(["AP-CSA-FINISHED"], timeout
=10)
980 raise Exception("CSA finished event timed out")
981 if "freq=5180" not in ev
:
982 raise Exception("Unexpected channel in CSA finished event")
983 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=0.5)
985 raise Exception("Unexpected STA disconnection during CSA")
986 hwsim_utils
.test_connectivity(dev
[0], hapd
)
988 dev
[0].request("DISCONNECT")
990 hapd
.request("DISABLE")
991 set_world_reg(apdev
[0], None, dev
[0])
992 dev
[0].flush_scan_cache()
994 def test_ap_ht40_csa3(dev
, apdev
):
995 """HT with 40 MHz channel width and CSA"""
996 csa_supported(dev
[0])
999 params
= { "ssid": "ht",
1000 "country_code": "US",
1003 "ht_capab": "[HT40+]",
1005 hapd
= hostapd
.add_ap(apdev
[0], params
)
1007 dev
[0].connect("ht", key_mgmt
="NONE", scan_freq
="5180")
1008 hwsim_utils
.test_connectivity(dev
[0], hapd
)
1010 hapd
.request("CHAN_SWITCH 5 5240 ht sec_channel_offset=-1 bandwidth=40")
1011 ev
= hapd
.wait_event(["AP-CSA-FINISHED"], timeout
=10)
1013 raise Exception("CSA finished event timed out")
1014 if "freq=5240" not in ev
:
1015 raise Exception("Unexpected channel in CSA finished event")
1016 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=0.5)
1018 raise Exception("Unexpected STA disconnection during CSA")
1019 hwsim_utils
.test_connectivity(dev
[0], hapd
)
1021 hapd
.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
1022 ev
= hapd
.wait_event(["AP-CSA-FINISHED"], timeout
=10)
1024 raise Exception("CSA finished event timed out")
1025 if "freq=5180" not in ev
:
1026 raise Exception("Unexpected channel in CSA finished event")
1027 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=0.5)
1029 raise Exception("Unexpected STA disconnection during CSA")
1030 hwsim_utils
.test_connectivity(dev
[0], hapd
)
1032 dev
[0].request("DISCONNECT")
1034 hapd
.request("DISABLE")
1035 set_world_reg(apdev
[0], None, dev
[0])
1036 dev
[0].flush_scan_cache()
1039 def test_ap_ht_smps(dev
, apdev
):
1040 """SMPS AP configuration options"""
1041 params
= { "ssid": "ht1", "ht_capab": "[SMPS-STATIC]" }
1043 hapd
= hostapd
.add_ap(apdev
[0], params
)
1045 raise HwsimSkip("Assume mac80211_hwsim was not recent enough to support SMPS")
1046 params
= { "ssid": "ht2", "ht_capab": "[SMPS-DYNAMIC]" }
1047 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1049 dev
[0].connect("ht1", key_mgmt
="NONE", scan_freq
="2412")
1050 dev
[1].connect("ht2", key_mgmt
="NONE", scan_freq
="2412")
1051 hwsim_utils
.test_connectivity(dev
[0], hapd
)
1052 hwsim_utils
.test_connectivity(dev
[1], hapd2
)
1055 def test_prefer_ht20(dev
, apdev
):
1056 """Preference on HT20 over no-HT"""
1057 params
= { "ssid": "test",
1060 hapd
= hostapd
.add_ap(apdev
[0], params
)
1061 bssid
= apdev
[0]['bssid']
1062 params
= { "ssid": "test",
1065 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1066 bssid2
= apdev
[1]['bssid']
1068 dev
[0].scan_for_bss(bssid
, freq
=2412)
1069 dev
[0].scan_for_bss(bssid2
, freq
=2412)
1070 dev
[0].connect("test", key_mgmt
="NONE", scan_freq
="2412")
1071 if dev
[0].get_status_field('bssid') != bssid2
:
1072 raise Exception("Unexpected BSS selected")
1074 est
= dev
[0].get_bss(bssid
)['est_throughput']
1076 raise Exception("Unexpected BSS0 est_throughput: " + est
)
1078 est
= dev
[0].get_bss(bssid2
)['est_throughput']
1080 raise Exception("Unexpected BSS1 est_throughput: " + est
)
1082 def test_prefer_ht40(dev
, apdev
):
1083 """Preference on HT40 over HT20"""
1084 params
= { "ssid": "test",
1087 hapd
= hostapd
.add_ap(apdev
[0], params
)
1088 bssid
= apdev
[0]['bssid']
1089 params
= { "ssid": "test",
1092 "ht_capab": "[HT40+]" }
1093 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1094 bssid2
= apdev
[1]['bssid']
1096 dev
[0].scan_for_bss(bssid
, freq
=2412)
1097 dev
[0].scan_for_bss(bssid2
, freq
=2412)
1098 dev
[0].connect("test", key_mgmt
="NONE", scan_freq
="2412")
1099 if dev
[0].get_status_field('bssid') != bssid2
:
1100 raise Exception("Unexpected BSS selected")
1102 est
= dev
[0].get_bss(bssid
)['est_throughput']
1104 raise Exception("Unexpected BSS0 est_throughput: " + est
)
1106 est
= dev
[0].get_bss(bssid2
)['est_throughput']
1108 raise Exception("Unexpected BSS1 est_throughput: " + est
)
1111 def test_prefer_ht20_during_roam(dev
, apdev
):
1112 """Preference on HT20 over no-HT in roaming consideration"""
1113 params
= { "ssid": "test",
1116 hapd
= hostapd
.add_ap(apdev
[0], params
)
1117 bssid
= apdev
[0]['bssid']
1119 dev
[0].scan_for_bss(bssid
, freq
=2412)
1120 dev
[0].connect("test", key_mgmt
="NONE", scan_freq
="2412")
1122 params
= { "ssid": "test",
1125 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1126 bssid2
= apdev
[1]['bssid']
1127 dev
[0].scan_for_bss(bssid2
, freq
=2412)
1128 dev
[0].scan(freq
=2412)
1129 dev
[0].wait_connected()
1131 if dev
[0].get_status_field('bssid') != bssid2
:
1132 raise Exception("Unexpected BSS selected")
1135 def test_ap_ht40_5ghz_invalid_pair(dev
, apdev
):
1136 """HT40 on 5 GHz with invalid channel pair"""
1137 clear_scan_cache(apdev
[0])
1139 params
= { "ssid": "test-ht40",
1142 "country_code": "US",
1143 "ht_capab": "[HT40+]"}
1144 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
1145 ev
= hapd
.wait_event(["AP-DISABLED", "AP-ENABLED"], timeout
=10)
1147 raise Exception("AP setup failure timed out")
1148 if "AP-ENABLED" in ev
:
1149 sec
= hapd
.get_status_field("secondary_channel")
1151 raise Exception("Invalid 40 MHz channel accepted")
1153 set_world_reg(apdev
[0], None, None)
1156 def test_ap_ht40_5ghz_disabled_sec(dev
, apdev
):
1157 """HT40 on 5 GHz with disabled secondary channel"""
1158 clear_scan_cache(apdev
[0])
1160 params
= { "ssid": "test-ht40",
1163 "country_code": "US",
1164 "ht_capab": "[HT40+]"}
1165 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
1166 ev
= hapd
.wait_event(["AP-DISABLED", "AP-ENABLED"], timeout
=10)
1168 raise Exception("AP setup failure timed out")
1169 if "AP-ENABLED" in ev
:
1170 sec
= hapd
.get_status_field("secondary_channel")
1172 raise Exception("Invalid 40 MHz channel accepted")
1174 set_world_reg(apdev
[0], None, None)
1176 def test_ap_ht40_scan_broken_ap(dev
, apdev
):
1177 """HT40 co-ex scan and broken legacy/HT AP"""
1178 clear_scan_cache(apdev
[0])
1180 # Broken AP: Include HT Capabilities element but not HT Operation element
1181 params
= { "ssid": "legacy-20",
1182 "channel": "7", "ieee80211n": "0",
1184 "vendor_elements": "2d1a0e001bffff000000000000000000000100000000000000000000" }
1185 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1187 params
= { "ssid": "test-ht40",
1189 "ht_capab": "[HT40-]"}
1190 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
1192 state
= hapd
.get_status_field("state")
1193 if state
!= "HT_SCAN":
1195 state
= hapd
.get_status_field("state")
1196 if state
!= "HT_SCAN":
1197 raise Exception("Unexpected interface state - expected HT_SCAN")
1199 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
1201 raise Exception("AP setup timed out")
1203 state
= hapd
.get_status_field("state")
1204 if state
!= "ENABLED":
1205 raise Exception("Unexpected interface state - expected ENABLED")
1207 freq
= hapd
.get_status_field("freq")
1209 raise Exception("Unexpected frequency: " + freq
)
1210 pri
= hapd
.get_status_field("channel")
1212 raise Exception("Unexpected primary channel: " + pri
)
1213 sec
= hapd
.get_status_field("secondary_channel")
1215 raise Exception("Unexpected secondary channel: " + sec
)
1217 dev
[0].connect("test-ht40", key_mgmt
="NONE", scan_freq
=freq
)
1218 dev
[1].connect("legacy-20", key_mgmt
="NONE", scan_freq
="2442")
1219 hwsim_utils
.test_connectivity(dev
[0], hapd
)
1220 hwsim_utils
.test_connectivity(dev
[1], hapd2
)