]>
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.
9 logger
= logging
.getLogger()
13 from utils
import HwsimSkip
, alloc_fail
15 from test_ap_csa
import csa_supported
17 def clear_scan_cache(apdev
):
18 ifname
= apdev
['ifname']
19 hostapd
.cmd_execute(apdev
, ['ifconfig', ifname
, 'up'])
20 hostapd
.cmd_execute(apdev
, ['iw', ifname
, 'scan', 'trigger', 'freq', '2412',
23 hostapd
.cmd_execute(apdev
, ['ifconfig', ifname
, 'down'])
25 def set_world_reg(apdev0
=None, apdev1
=None, dev0
=None):
27 hostapd
.cmd_execute(apdev0
, ['iw', 'reg', 'set', '00'])
29 hostapd
.cmd_execute(apdev1
, ['iw', 'reg', 'set', '00'])
31 dev0
.cmd_execute(['iw', 'reg', 'set', '00'])
33 def test_ap_ht40_scan(dev
, apdev
):
35 clear_scan_cache(apdev
[0])
36 params
= { "ssid": "test-ht40",
38 "ht_capab": "[HT40-]"}
39 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
41 state
= hapd
.get_status_field("state")
42 if state
!= "HT_SCAN":
44 state
= hapd
.get_status_field("state")
45 if state
!= "HT_SCAN":
46 raise Exception("Unexpected interface state - expected HT_SCAN")
48 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
50 raise Exception("AP setup timed out")
52 state
= hapd
.get_status_field("state")
53 if state
!= "ENABLED":
54 raise Exception("Unexpected interface state - expected ENABLED")
56 freq
= hapd
.get_status_field("freq")
58 raise Exception("Unexpected frequency")
59 pri
= hapd
.get_status_field("channel")
61 raise Exception("Unexpected primary channel")
62 sec
= hapd
.get_status_field("secondary_channel")
64 raise Exception("Unexpected secondary channel")
66 dev
[0].connect("test-ht40", key_mgmt
="NONE", scan_freq
=freq
)
68 def test_ap_ht40_scan_conflict(dev
, apdev
):
69 """HT40 co-ex scan conflict"""
70 clear_scan_cache(apdev
[0])
71 params
= { "ssid": "test-ht40",
73 "ht_capab": "[HT40+]"}
74 hostapd
.add_ap(apdev
[1], params
)
76 params
= { "ssid": "test-ht40",
78 "ht_capab": "[HT40-]"}
79 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
81 state
= hapd
.get_status_field("state")
82 if state
!= "HT_SCAN":
84 state
= hapd
.get_status_field("state")
85 if state
!= "HT_SCAN":
86 raise Exception("Unexpected interface state - expected HT_SCAN")
88 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
90 raise Exception("AP setup timed out")
92 state
= hapd
.get_status_field("state")
93 if state
!= "ENABLED":
94 raise Exception("Unexpected interface state - expected ENABLED")
96 freq
= hapd
.get_status_field("freq")
98 raise Exception("Unexpected frequency")
99 pri
= hapd
.get_status_field("channel")
101 raise Exception("Unexpected primary channel")
102 sec
= hapd
.get_status_field("secondary_channel")
104 raise Exception("Unexpected secondary channel: " + sec
)
106 dev
[0].connect("test-ht40", key_mgmt
="NONE", scan_freq
=freq
)
108 def test_ap_ht40_scan_conflict2(dev
, apdev
):
109 """HT40 co-ex scan conflict (HT40-)"""
110 clear_scan_cache(apdev
[0])
111 params
= { "ssid": "test-ht40",
113 "ht_capab": "[HT40-]"}
114 hostapd
.add_ap(apdev
[1], params
)
116 params
= { "ssid": "test-ht40",
118 "ht_capab": "[HT40+]"}
119 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
121 state
= hapd
.get_status_field("state")
122 if state
!= "HT_SCAN":
124 state
= hapd
.get_status_field("state")
125 if state
!= "HT_SCAN":
126 raise Exception("Unexpected interface state - expected HT_SCAN")
128 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
130 raise Exception("AP setup timed out")
132 state
= hapd
.get_status_field("state")
133 if state
!= "ENABLED":
134 raise Exception("Unexpected interface state - expected ENABLED")
136 freq
= hapd
.get_status_field("freq")
138 raise Exception("Unexpected frequency")
139 pri
= hapd
.get_status_field("channel")
141 raise Exception("Unexpected primary channel")
142 sec
= hapd
.get_status_field("secondary_channel")
144 raise Exception("Unexpected secondary channel: " + sec
)
146 dev
[0].connect("test-ht40", key_mgmt
="NONE", scan_freq
=freq
)
148 def test_ap_ht40_scan_not_affected(dev
, apdev
):
149 """HT40 co-ex scan and other BSS not affected"""
150 clear_scan_cache(apdev
[0])
151 params
= { "ssid": "test-ht20",
153 hostapd
.add_ap(apdev
[1], params
)
155 hostapd
.cmd_execute(apdev
[0], ['ifconfig', apdev
[0]['ifname'], 'up'])
156 hostapd
.cmd_execute(apdev
[0], ['iw', apdev
[0]['ifname'], 'scan', 'trigger',
159 hostapd
.cmd_execute(apdev
[0], ['iw', apdev
[0]['ifname'], 'scan', 'dump'])
161 hostapd
.cmd_execute(apdev
[0], ['ifconfig', apdev
[0]['ifname'], 'down'])
163 params
= { "ssid": "test-ht40",
165 "ht_capab": "[HT40+]"}
166 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
168 state
= hapd
.get_status_field("state")
169 if state
!= "HT_SCAN":
171 state
= hapd
.get_status_field("state")
172 if state
!= "HT_SCAN":
173 raise Exception("Unexpected interface state - expected HT_SCAN")
175 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
177 raise Exception("AP setup timed out")
179 state
= hapd
.get_status_field("state")
180 if state
!= "ENABLED":
181 raise Exception("Unexpected interface state - expected ENABLED")
183 freq
= hapd
.get_status_field("freq")
185 raise Exception("Unexpected frequency")
186 pri
= hapd
.get_status_field("channel")
188 raise Exception("Unexpected primary channel")
189 sec
= hapd
.get_status_field("secondary_channel")
191 raise Exception("Unexpected secondary channel: " + sec
)
193 dev
[0].connect("test-ht40", key_mgmt
="NONE", scan_freq
=freq
)
195 def test_ap_ht40_scan_legacy_conflict(dev
, apdev
):
196 """HT40 co-ex scan conflict with legacy 20 MHz AP"""
197 clear_scan_cache(apdev
[0])
198 params
= { "ssid": "legacy-20",
199 "channel": "7", "ieee80211n": "0" }
200 hostapd
.add_ap(apdev
[1], params
)
202 params
= { "ssid": "test-ht40",
204 "ht_capab": "[HT40-]"}
205 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
207 state
= hapd
.get_status_field("state")
208 if state
!= "HT_SCAN":
210 state
= hapd
.get_status_field("state")
211 if state
!= "HT_SCAN":
212 raise Exception("Unexpected interface state - expected HT_SCAN")
214 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
216 raise Exception("AP setup timed out")
218 state
= hapd
.get_status_field("state")
219 if state
!= "ENABLED":
220 raise Exception("Unexpected interface state - expected ENABLED")
222 freq
= hapd
.get_status_field("freq")
224 raise Exception("Unexpected frequency: " + freq
)
225 pri
= hapd
.get_status_field("channel")
227 raise Exception("Unexpected primary channel: " + pri
)
228 sec
= hapd
.get_status_field("secondary_channel")
230 raise Exception("Unexpected secondary channel: " + sec
)
232 dev
[0].connect("test-ht40", key_mgmt
="NONE", scan_freq
=freq
)
234 def test_ap_ht40_scan_ht20_conflict(dev
, apdev
):
235 """HT40 co-ex scan conflict with HT 20 MHz AP"""
236 clear_scan_cache(apdev
[0])
237 params
= { "ssid": "ht-20",
238 "channel": "7", "ieee80211n": "1" }
239 hostapd
.add_ap(apdev
[1], params
)
241 params
= { "ssid": "test-ht40",
243 "ht_capab": "[HT40-]"}
244 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
246 state
= hapd
.get_status_field("state")
247 if state
!= "HT_SCAN":
249 state
= hapd
.get_status_field("state")
250 if state
!= "HT_SCAN":
251 raise Exception("Unexpected interface state - expected HT_SCAN")
253 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
255 raise Exception("AP setup timed out")
257 state
= hapd
.get_status_field("state")
258 if state
!= "ENABLED":
259 raise Exception("Unexpected interface state - expected ENABLED")
261 freq
= hapd
.get_status_field("freq")
263 raise Exception("Unexpected frequency: " + freq
)
264 pri
= hapd
.get_status_field("channel")
266 raise Exception("Unexpected primary channel: " + pri
)
267 sec
= hapd
.get_status_field("secondary_channel")
269 raise Exception("Unexpected secondary channel: " + sec
)
271 dev
[0].connect("test-ht40", key_mgmt
="NONE", scan_freq
=freq
)
273 def test_ap_ht40_scan_intolerant(dev
, apdev
):
274 """HT40 co-ex scan finding an AP advertising 40 MHz intolerant"""
275 clear_scan_cache(apdev
[0])
276 params
= { "ssid": "another-bss",
278 "ht_capab": "[40-INTOLERANT]" }
279 hostapd
.add_ap(apdev
[1], params
)
281 params
= { "ssid": "test-ht40",
283 "ht_capab": "[HT40+]"}
284 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
286 state
= hapd
.get_status_field("state")
287 if state
!= "HT_SCAN":
289 state
= hapd
.get_status_field("state")
290 if state
!= "HT_SCAN":
291 raise Exception("Unexpected interface state - expected HT_SCAN")
293 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
295 raise Exception("AP setup timed out")
297 state
= hapd
.get_status_field("state")
298 if state
!= "ENABLED":
299 raise Exception("Unexpected interface state - expected ENABLED")
301 freq
= hapd
.get_status_field("freq")
303 raise Exception("Unexpected frequency: " + freq
)
304 pri
= hapd
.get_status_field("channel")
306 raise Exception("Unexpected primary channel: " + pri
)
307 sec
= hapd
.get_status_field("secondary_channel")
309 raise Exception("Unexpected secondary channel: " + sec
)
311 dev
[0].connect("test-ht40", key_mgmt
="NONE", scan_freq
=freq
)
313 def test_ap_ht40_scan_match(dev
, apdev
):
314 """HT40 co-ex scan matching configuration"""
315 clear_scan_cache(apdev
[0])
316 params
= { "ssid": "test-ht40",
318 "ht_capab": "[HT40-]"}
319 hostapd
.add_ap(apdev
[1], params
)
321 params
= { "ssid": "test-ht40",
323 "ht_capab": "[HT40-]"}
324 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
326 state
= hapd
.get_status_field("state")
327 if state
!= "HT_SCAN":
329 state
= hapd
.get_status_field("state")
330 if state
!= "HT_SCAN":
331 raise Exception("Unexpected interface state - expected HT_SCAN")
333 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
335 raise Exception("AP setup timed out")
337 state
= hapd
.get_status_field("state")
338 if state
!= "ENABLED":
339 raise Exception("Unexpected interface state - expected ENABLED")
341 freq
= hapd
.get_status_field("freq")
343 raise Exception("Unexpected frequency")
344 pri
= hapd
.get_status_field("channel")
346 raise Exception("Unexpected primary channel")
347 sec
= hapd
.get_status_field("secondary_channel")
349 raise Exception("Unexpected secondary channel: " + sec
)
351 dev
[0].connect("test-ht40", key_mgmt
="NONE", scan_freq
=freq
)
353 def test_ap_ht40_5ghz_match(dev
, apdev
):
354 """HT40 co-ex scan on 5 GHz with matching pri/sec channel"""
355 clear_scan_cache(apdev
[0])
359 params
= { "ssid": "test-ht40",
362 "country_code": "US",
363 "ht_capab": "[HT40+]"}
364 hapd2
= hostapd
.add_ap(apdev
[1], params
)
366 params
= { "ssid": "test-ht40",
369 "ht_capab": "[HT40+]"}
370 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
372 state
= hapd
.get_status_field("state")
373 if state
!= "HT_SCAN":
375 state
= hapd
.get_status_field("state")
376 if state
!= "HT_SCAN":
377 raise Exception("Unexpected interface state - expected HT_SCAN")
379 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
381 raise Exception("AP setup timed out")
383 state
= hapd
.get_status_field("state")
384 if state
!= "ENABLED":
385 raise Exception("Unexpected interface state - expected ENABLED")
387 freq
= hapd
.get_status_field("freq")
389 raise Exception("Unexpected frequency")
390 pri
= hapd
.get_status_field("channel")
392 raise Exception("Unexpected primary channel")
393 sec
= hapd
.get_status_field("secondary_channel")
395 raise Exception("Unexpected secondary channel: " + sec
)
397 dev
[0].connect("test-ht40", key_mgmt
="NONE", scan_freq
=freq
)
399 dev
[0].request("DISCONNECT")
401 hapd
.request("DISABLE")
403 hapd2
.request("DISABLE")
404 set_world_reg(apdev
[0], apdev
[1], dev
[0])
405 dev
[0].flush_scan_cache()
407 def test_ap_ht40_5ghz_switch(dev
, apdev
):
408 """HT40 co-ex scan on 5 GHz switching pri/sec channel"""
409 clear_scan_cache(apdev
[0])
413 params
= { "ssid": "test-ht40",
416 "country_code": "US",
417 "ht_capab": "[HT40+]"}
418 hapd2
= hostapd
.add_ap(apdev
[1], params
)
420 params
= { "ssid": "test-ht40",
423 "ht_capab": "[HT40-]"}
424 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
426 state
= hapd
.get_status_field("state")
427 if state
!= "HT_SCAN":
429 state
= hapd
.get_status_field("state")
430 if state
!= "HT_SCAN":
431 raise Exception("Unexpected interface state - expected HT_SCAN")
433 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
435 raise Exception("AP setup timed out")
437 state
= hapd
.get_status_field("state")
438 if state
!= "ENABLED":
439 raise Exception("Unexpected interface state - expected ENABLED")
441 freq
= hapd
.get_status_field("freq")
443 raise Exception("Unexpected frequency: " + freq
)
444 pri
= hapd
.get_status_field("channel")
446 raise Exception("Unexpected primary channel: " + pri
)
447 sec
= hapd
.get_status_field("secondary_channel")
449 raise Exception("Unexpected secondary channel: " + sec
)
451 dev
[0].connect("test-ht40", key_mgmt
="NONE", scan_freq
=freq
)
453 dev
[0].request("DISCONNECT")
455 hapd
.request("DISABLE")
457 hapd2
.request("DISABLE")
458 set_world_reg(apdev
[0], apdev
[1], dev
[0])
460 def test_ap_ht40_5ghz_switch2(dev
, apdev
):
461 """HT40 co-ex scan on 5 GHz switching pri/sec channel (2)"""
462 clear_scan_cache(apdev
[0])
466 params
= { "ssid": "test-ht40",
469 "country_code": "US",
470 "ht_capab": "[HT40+]"}
471 hapd2
= hostapd
.add_ap(apdev
[1], params
)
473 id = dev
[0].add_network()
474 dev
[0].set_network(id, "mode", "2")
475 dev
[0].set_network_quoted(id, "ssid", "wpas-ap-open")
476 dev
[0].set_network(id, "key_mgmt", "NONE")
477 dev
[0].set_network(id, "frequency", "5200")
478 dev
[0].set_network(id, "scan_freq", "5200")
479 dev
[0].select_network(id)
482 params
= { "ssid": "test-ht40",
485 "ht_capab": "[HT40-]"}
486 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
488 state
= hapd
.get_status_field("state")
489 if state
!= "HT_SCAN":
491 state
= hapd
.get_status_field("state")
492 if state
!= "HT_SCAN":
493 raise Exception("Unexpected interface state - expected HT_SCAN")
495 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
497 raise Exception("AP setup timed out")
499 state
= hapd
.get_status_field("state")
500 if state
!= "ENABLED":
501 raise Exception("Unexpected interface state - expected ENABLED")
503 freq
= hapd
.get_status_field("freq")
505 raise Exception("Unexpected frequency: " + freq
)
506 pri
= hapd
.get_status_field("channel")
508 raise Exception("Unexpected primary channel: " + pri
)
509 sec
= hapd
.get_status_field("secondary_channel")
511 raise Exception("Unexpected secondary channel: " + sec
)
513 dev
[0].connect("test-ht40", key_mgmt
="NONE", scan_freq
=freq
)
515 dev
[0].request("DISCONNECT")
517 hapd
.request("DISABLE")
519 hapd2
.request("DISABLE")
520 set_world_reg(apdev
[0], apdev
[1], dev
[0])
521 dev
[0].flush_scan_cache()
523 def test_obss_scan(dev
, apdev
):
524 """Overlapping BSS scan request"""
525 params
= { "ssid": "obss-scan",
527 "ht_capab": "[HT40-]",
528 "obss_interval": "10" }
529 hapd
= hostapd
.add_ap(apdev
[0], params
)
531 params
= { "ssid": "another-bss",
534 hostapd
.add_ap(apdev
[1], params
)
536 dev
[0].connect("obss-scan", key_mgmt
="NONE", scan_freq
="2437")
537 hapd
.set("ext_mgmt_frame_handling", "1")
538 logger
.info("Waiting for OBSS scan to occur")
539 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=15)
541 raise Exception("Timed out while waiting for OBSS scan to start")
542 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout
=10)
544 raise Exception("Timed out while waiting for OBSS scan results")
546 for i
in range(0, 4):
547 frame
= hapd
.mgmt_rx(timeout
=5)
549 raise Exception("MGMT RX wait timed out")
550 if frame
['subtype'] != 13:
552 payload
= frame
['payload']
555 (category
, action
, ie
) = struct
.unpack('BBB', payload
[0:3])
561 logger
.info("20/40 BSS Coexistence report received")
565 raise Exception("20/40 BSS Coexistence report not seen")
567 def test_obss_scan_40_intolerant(dev
, apdev
):
568 """Overlapping BSS scan request with 40 MHz intolerant AP"""
569 params
= { "ssid": "obss-scan",
571 "ht_capab": "[HT40-]",
572 "obss_interval": "10" }
573 hapd
= hostapd
.add_ap(apdev
[0], params
)
575 params
= { "ssid": "another-bss",
577 "ht_capab": "[40-INTOLERANT]" }
578 hostapd
.add_ap(apdev
[1], params
)
580 dev
[0].connect("obss-scan", key_mgmt
="NONE", scan_freq
="2437")
581 hapd
.set("ext_mgmt_frame_handling", "1")
582 logger
.info("Waiting for OBSS scan to occur")
583 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=15)
585 raise Exception("Timed out while waiting for OBSS scan to start")
586 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout
=10)
588 raise Exception("Timed out while waiting for OBSS scan results")
590 for i
in range(0, 4):
591 frame
= hapd
.mgmt_rx(timeout
=5)
593 raise Exception("MGMT RX wait timed out")
594 if frame
['subtype'] != 13:
596 payload
= frame
['payload']
599 (category
, action
, ie
) = struct
.unpack('BBB', payload
[0:3])
605 logger
.info("20/40 BSS Coexistence report received")
609 raise Exception("20/40 BSS Coexistence report not seen")
611 def test_obss_coex_report_handling(dev
, apdev
):
612 """Overlapping BSS scan report handling with obss_interval=0"""
613 clear_scan_cache(apdev
[0])
614 params
= { "ssid": "obss-scan",
616 "ht_capab": "[HT40-]" }
617 hapd
= hostapd
.add_ap(apdev
[0], params
)
618 bssid
= apdev
[0]['bssid']
619 dev
[0].connect("obss-scan", key_mgmt
="NONE", scan_freq
="2437")
621 sec
= hapd
.get_status_field("secondary_channel")
623 raise Exception("AP is not using 40 MHz channel")
625 # 20/40 MHz co-ex report tests: number of invalid reports and a valid report
626 # that forces 20 MHz channel.
627 tests
= [ '0400', '040048', '04004801', '0400480000', '0400490100',
628 '040048ff0000', '04004801ff49ff00', '04004801004900',
629 '0400480100490101', '0400480100490201ff',
630 '040048010449020005' ]
632 req
= "MGMT_TX {} {} freq=2437 action={}".format(bssid
, bssid
, msg
)
633 if "OK" not in dev
[0].request(req
):
634 raise Exception("Could not send management frame")
636 sec
= hapd
.get_status_field("secondary_channel")
638 raise Exception("AP did not move to 20 MHz channel")
640 def test_obss_coex_report_handling1(dev
, apdev
):
641 """Overlapping BSS scan report handling with obss_interval=1"""
642 clear_scan_cache(apdev
[0])
643 params
= { "ssid": "obss-scan",
645 "ht_capab": "[HT40+]",
646 "obss_interval": "1" }
647 hapd
= hostapd
.add_ap(apdev
[0], params
)
648 bssid
= apdev
[0]['bssid']
649 dev
[0].connect("obss-scan", key_mgmt
="NONE", scan_freq
="2437")
651 sec
= hapd
.get_status_field("secondary_channel")
653 raise Exception("AP is not using 40 MHz channel")
655 # 20/40 MHz co-ex report forcing 20 MHz channel
656 msg
= '040048010449020005'
657 req
= "MGMT_TX {} {} freq=2437 action={}".format(bssid
, bssid
, msg
)
658 if "OK" not in dev
[0].request(req
):
659 raise Exception("Could not send management frame")
661 sec
= hapd
.get_status_field("secondary_channel")
663 raise Exception("AP did not move to 20 MHz channel")
665 # No 20/40 MHz co-ex reports forcing 20 MHz channel during next interval
667 sec
= hapd
.get_status_field("secondary_channel")
672 raise Exception("AP did not return to 40 MHz channel")
674 def test_olbc(dev
, apdev
):
676 params
= { "ssid": "test-olbc",
678 "ht_capab": "[HT40-]",
679 "ap_table_expiration_time": "2" }
680 hapd
= hostapd
.add_ap(apdev
[0], params
)
681 status
= hapd
.get_status()
682 if status
['olbc'] != '0' or status
['olbc_ht'] != '0':
683 raise Exception("Unexpected OLBC information")
685 params
= { "ssid": "olbc-ap",
689 hostapd
.add_ap(apdev
[1], params
)
691 status
= hapd
.get_status()
692 if status
['olbc'] != '1' or status
['olbc_ht'] != '1':
693 raise Exception("Missing OLBC information")
695 hostapd
.remove_bss(apdev
[1])
697 logger
.info("Waiting for OLBC state to time out")
699 for i
in range(0, 15):
701 status
= hapd
.get_status()
702 if status
['olbc'] == '0' and status
['olbc_ht'] == '0':
706 raise Exception("OLBC state did nto time out")
708 def test_olbc_table_limit(dev
, apdev
):
709 """OLBC AP table size limit"""
710 ifname1
= apdev
[0]['ifname']
711 ifname2
= apdev
[0]['ifname'] + '-2'
712 ifname3
= apdev
[0]['ifname'] + '-3'
713 hostapd
.add_bss(apdev
[0], ifname1
, 'bss-1.conf')
714 hostapd
.add_bss(apdev
[0], ifname2
, 'bss-2.conf')
715 hostapd
.add_bss(apdev
[0], ifname3
, 'bss-3.conf')
717 params
= { "ssid": "test-olbc",
719 "ap_table_max_size": "2" }
720 hapd
= hostapd
.add_ap(apdev
[1], params
)
723 with
alloc_fail(hapd
, 1, "ap_list_process_beacon"):
725 hapd
.set("ap_table_max_size", "1")
727 hapd
.set("ap_table_max_size", "0")
730 def test_olbc_5ghz(dev
, apdev
):
731 """OLBC detection on 5 GHz"""
735 params
= { "ssid": "test-olbc",
736 "country_code": "FI",
739 "ht_capab": "[HT40+]" }
740 hapd
= hostapd
.add_ap(apdev
[0], params
)
741 status
= hapd
.get_status()
742 if status
['olbc'] != '0' or status
['olbc_ht'] != '0':
743 raise Exception("Unexpected OLBC information")
745 params
= { "ssid": "olbc-ap",
746 "country_code": "FI",
751 hapd2
= hostapd
.add_ap(apdev
[1], params
)
755 status
= hapd
.get_status()
756 logger
.debug('olbc_ht: ' + status
['olbc_ht'])
757 if status
['olbc_ht'] == '1':
761 raise Exception("Missing OLBC information")
764 hapd
.request("DISABLE")
766 hapd2
.request("DISABLE")
767 set_world_reg(apdev
[0], apdev
[1], None)
769 def test_ap_require_ht(dev
, apdev
):
771 params
= { "ssid": "require-ht",
773 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
775 dev
[1].connect("require-ht", key_mgmt
="NONE", scan_freq
="2412",
776 disable_ht
="1", wait_connect
=False)
777 dev
[0].connect("require-ht", key_mgmt
="NONE", scan_freq
="2412")
778 ev
= dev
[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
779 dev
[1].request("DISCONNECT")
781 raise Exception("Association rejection timed out")
782 if "status_code=27" not in ev
:
783 raise Exception("Unexpected rejection status code")
784 dev
[2].connect("require-ht", key_mgmt
="NONE", scan_freq
="2412",
785 ht_mcs
="0x01 00 00 00 00 00 00 00 00 00",
786 disable_max_amsdu
="1", ampdu_factor
="2",
787 ampdu_density
="1", disable_ht40
="1", disable_sgi
="1",
790 def test_ap_require_ht_limited_rates(dev
, apdev
):
791 """Require HT with limited supported rates"""
792 params
= { "ssid": "require-ht",
793 "supported_rates": "60 120 240 360 480 540",
795 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
797 dev
[1].connect("require-ht", key_mgmt
="NONE", scan_freq
="2412",
798 disable_ht
="1", wait_connect
=False)
799 dev
[0].connect("require-ht", key_mgmt
="NONE", scan_freq
="2412")
800 ev
= dev
[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
801 dev
[1].request("DISCONNECT")
803 raise Exception("Association rejection timed out")
804 if "status_code=27" not in ev
:
805 raise Exception("Unexpected rejection status code")
807 def test_ap_ht_capab_not_supported(dev
, apdev
):
808 """HT configuration with driver not supporting all ht_capab entries"""
809 params
= { "ssid": "test-ht40",
811 "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]"}
812 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
813 if "FAIL" not in hapd
.request("ENABLE"):
814 raise Exception("Unexpected ENABLE success")
816 def test_ap_ht_40mhz_intolerant_sta(dev
, apdev
):
817 """Associated STA indicating 40 MHz intolerant"""
818 clear_scan_cache(apdev
[0])
819 params
= { "ssid": "intolerant",
821 "ht_capab": "[HT40-]" }
822 hapd
= hostapd
.add_ap(apdev
[0], params
)
823 if hapd
.get_status_field("num_sta_ht40_intolerant") != "0":
824 raise Exception("Unexpected num_sta_ht40_intolerant value")
825 if hapd
.get_status_field("secondary_channel") != "-1":
826 raise Exception("Unexpected secondary_channel")
828 dev
[0].connect("intolerant", key_mgmt
="NONE", scan_freq
="2437")
829 if hapd
.get_status_field("num_sta_ht40_intolerant") != "0":
830 raise Exception("Unexpected num_sta_ht40_intolerant value")
831 if hapd
.get_status_field("secondary_channel") != "-1":
832 raise Exception("Unexpected secondary_channel")
834 dev
[2].connect("intolerant", key_mgmt
="NONE", scan_freq
="2437",
837 if hapd
.get_status_field("num_sta_ht40_intolerant") != "1":
838 raise Exception("Unexpected num_sta_ht40_intolerant value (expected 1)")
839 if hapd
.get_status_field("secondary_channel") != "0":
840 raise Exception("Unexpected secondary_channel (did not disable 40 MHz)")
842 dev
[2].request("DISCONNECT")
844 if hapd
.get_status_field("num_sta_ht40_intolerant") != "0":
845 raise Exception("Unexpected num_sta_ht40_intolerant value (expected 0)")
846 if hapd
.get_status_field("secondary_channel") != "-1":
847 raise Exception("Unexpected secondary_channel (did not re-enable 40 MHz)")
849 def test_ap_ht_40mhz_intolerant_ap(dev
, apdev
):
850 """Associated STA reports 40 MHz intolerant AP after association"""
851 clear_scan_cache(apdev
[0])
852 params
= { "ssid": "ht",
854 "ht_capab": "[HT40-]",
855 "obss_interval": "3" }
856 hapd
= hostapd
.add_ap(apdev
[0], params
)
858 dev
[0].connect("ht", key_mgmt
="NONE", scan_freq
="2437")
860 if hapd
.get_status_field("secondary_channel") != "-1":
861 raise Exception("Unexpected secondary channel information")
863 logger
.info("Start 40 MHz intolerant AP")
864 params
= { "ssid": "intolerant",
866 "ht_capab": "[40-INTOLERANT]" }
867 hapd2
= hostapd
.add_ap(apdev
[1], params
)
869 logger
.info("Waiting for co-ex report from STA")
871 for i
in range(0, 20):
873 if hapd
.get_status_field("secondary_channel") == "0":
874 logger
.info("AP moved to 20 MHz channel")
878 raise Exception("AP did not move to 20 MHz channel")
880 if "OK" not in hapd2
.request("DISABLE"):
881 raise Exception("Failed to disable 40 MHz intolerant AP")
883 # make sure the intolerant AP disappears from scan results more quickly
884 dev
[0].scan(type="ONLY", freq
="2432", only_new
=True)
885 dev
[0].scan(type="ONLY", freq
="2432", only_new
=True)
886 dev
[0].dump_monitor()
888 logger
.info("Waiting for AP to move back to 40 MHz channel")
890 for i
in range(0, 30):
892 if hapd
.get_status_field("secondary_channel") == "-1":
893 logger
.info("AP moved to 40 MHz channel")
897 raise Exception("AP did not move to 40 MHz channel")
899 def test_ap_ht40_csa(dev
, apdev
):
900 """HT with 40 MHz channel width and CSA"""
901 csa_supported(dev
[0])
904 params
= { "ssid": "ht",
905 "country_code": "US",
908 "ht_capab": "[HT40+]",
910 hapd
= hostapd
.add_ap(apdev
[0], params
)
912 dev
[0].connect("ht", key_mgmt
="NONE", scan_freq
="5180")
913 hwsim_utils
.test_connectivity(dev
[0], hapd
)
915 hapd
.request("CHAN_SWITCH 5 5200 ht sec_channel_offset=-1 bandwidth=40")
916 ev
= hapd
.wait_event(["AP-CSA-FINISHED"], timeout
=10)
918 raise Exception("CSA finished event timed out")
919 if "freq=5200" not in ev
:
920 raise Exception("Unexpected channel in CSA finished event")
921 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=0.5)
923 raise Exception("Unexpected STA disconnection during CSA")
924 hwsim_utils
.test_connectivity(dev
[0], hapd
)
926 hapd
.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
927 ev
= hapd
.wait_event(["AP-CSA-FINISHED"], timeout
=10)
929 raise Exception("CSA finished event timed out")
930 if "freq=5180" not in ev
:
931 raise Exception("Unexpected channel in CSA finished event")
932 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=0.5)
934 raise Exception("Unexpected STA disconnection during CSA")
935 hwsim_utils
.test_connectivity(dev
[0], hapd
)
937 dev
[0].request("DISCONNECT")
939 hapd
.request("DISABLE")
940 set_world_reg(apdev
[0], None, dev
[0])
941 dev
[0].flush_scan_cache()
943 def test_ap_ht40_csa2(dev
, apdev
):
944 """HT with 40 MHz channel width and CSA"""
945 csa_supported(dev
[0])
948 params
= { "ssid": "ht",
949 "country_code": "US",
952 "ht_capab": "[HT40+]",
954 hapd
= hostapd
.add_ap(apdev
[0], params
)
956 dev
[0].connect("ht", key_mgmt
="NONE", scan_freq
="5180")
957 hwsim_utils
.test_connectivity(dev
[0], hapd
)
959 hapd
.request("CHAN_SWITCH 5 5220 ht sec_channel_offset=1 bandwidth=40")
960 ev
= hapd
.wait_event(["AP-CSA-FINISHED"], timeout
=10)
962 raise Exception("CSA finished event timed out")
963 if "freq=5220" not in ev
:
964 raise Exception("Unexpected channel in CSA finished event")
965 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=0.5)
967 raise Exception("Unexpected STA disconnection during CSA")
968 hwsim_utils
.test_connectivity(dev
[0], hapd
)
970 hapd
.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
971 ev
= hapd
.wait_event(["AP-CSA-FINISHED"], timeout
=10)
973 raise Exception("CSA finished event timed out")
974 if "freq=5180" not in ev
:
975 raise Exception("Unexpected channel in CSA finished event")
976 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=0.5)
978 raise Exception("Unexpected STA disconnection during CSA")
979 hwsim_utils
.test_connectivity(dev
[0], hapd
)
981 dev
[0].request("DISCONNECT")
983 hapd
.request("DISABLE")
984 set_world_reg(apdev
[0], None, dev
[0])
985 dev
[0].flush_scan_cache()
987 def test_ap_ht40_csa3(dev
, apdev
):
988 """HT with 40 MHz channel width and CSA"""
989 csa_supported(dev
[0])
992 params
= { "ssid": "ht",
993 "country_code": "US",
996 "ht_capab": "[HT40+]",
998 hapd
= hostapd
.add_ap(apdev
[0], params
)
1000 dev
[0].connect("ht", key_mgmt
="NONE", scan_freq
="5180")
1001 hwsim_utils
.test_connectivity(dev
[0], hapd
)
1003 hapd
.request("CHAN_SWITCH 5 5240 ht sec_channel_offset=-1 bandwidth=40")
1004 ev
= hapd
.wait_event(["AP-CSA-FINISHED"], timeout
=10)
1006 raise Exception("CSA finished event timed out")
1007 if "freq=5240" not in ev
:
1008 raise Exception("Unexpected channel in CSA finished event")
1009 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=0.5)
1011 raise Exception("Unexpected STA disconnection during CSA")
1012 hwsim_utils
.test_connectivity(dev
[0], hapd
)
1014 hapd
.request("CHAN_SWITCH 5 5180 ht sec_channel_offset=1 bandwidth=40")
1015 ev
= hapd
.wait_event(["AP-CSA-FINISHED"], timeout
=10)
1017 raise Exception("CSA finished event timed out")
1018 if "freq=5180" not in ev
:
1019 raise Exception("Unexpected channel in CSA finished event")
1020 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=0.5)
1022 raise Exception("Unexpected STA disconnection during CSA")
1023 hwsim_utils
.test_connectivity(dev
[0], hapd
)
1025 dev
[0].request("DISCONNECT")
1027 hapd
.request("DISABLE")
1028 set_world_reg(apdev
[0], None, dev
[0])
1029 dev
[0].flush_scan_cache()
1031 def test_ap_ht_smps(dev
, apdev
):
1032 """SMPS AP configuration options"""
1033 params
= { "ssid": "ht1", "ht_capab": "[SMPS-STATIC]" }
1035 hapd
= hostapd
.add_ap(apdev
[0], params
)
1037 raise HwsimSkip("Assume mac80211_hwsim was not recent enough to support SMPS")
1038 params
= { "ssid": "ht2", "ht_capab": "[SMPS-DYNAMIC]" }
1039 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1041 dev
[0].connect("ht1", key_mgmt
="NONE", scan_freq
="2412")
1042 dev
[1].connect("ht2", key_mgmt
="NONE", scan_freq
="2412")
1043 hwsim_utils
.test_connectivity(dev
[0], hapd
)
1044 hwsim_utils
.test_connectivity(dev
[1], hapd2
)
1046 def test_prefer_ht20(dev
, apdev
):
1047 """Preference on HT20 over no-HT"""
1048 params
= { "ssid": "test",
1051 hapd
= hostapd
.add_ap(apdev
[0], params
)
1052 bssid
= apdev
[0]['bssid']
1053 params
= { "ssid": "test",
1056 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1057 bssid2
= apdev
[1]['bssid']
1059 dev
[0].scan_for_bss(bssid
, freq
=2412)
1060 dev
[0].scan_for_bss(bssid2
, freq
=2412)
1061 dev
[0].connect("test", key_mgmt
="NONE", scan_freq
="2412")
1062 if dev
[0].get_status_field('bssid') != bssid2
:
1063 raise Exception("Unexpected BSS selected")
1065 est
= dev
[0].get_bss(bssid
)['est_throughput']
1067 raise Exception("Unexpected BSS0 est_throughput: " + est
)
1069 est
= dev
[0].get_bss(bssid2
)['est_throughput']
1071 raise Exception("Unexpected BSS1 est_throughput: " + est
)
1073 def test_prefer_ht40(dev
, apdev
):
1074 """Preference on HT40 over HT20"""
1075 params
= { "ssid": "test",
1078 hapd
= hostapd
.add_ap(apdev
[0], params
)
1079 bssid
= apdev
[0]['bssid']
1080 params
= { "ssid": "test",
1083 "ht_capab": "[HT40+]" }
1084 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1085 bssid2
= apdev
[1]['bssid']
1087 dev
[0].scan_for_bss(bssid
, freq
=2412)
1088 dev
[0].scan_for_bss(bssid2
, freq
=2412)
1089 dev
[0].connect("test", key_mgmt
="NONE", scan_freq
="2412")
1090 if dev
[0].get_status_field('bssid') != bssid2
:
1091 raise Exception("Unexpected BSS selected")
1093 est
= dev
[0].get_bss(bssid
)['est_throughput']
1095 raise Exception("Unexpected BSS0 est_throughput: " + est
)
1097 est
= dev
[0].get_bss(bssid2
)['est_throughput']
1099 raise Exception("Unexpected BSS1 est_throughput: " + est
)
1101 def test_prefer_ht20_during_roam(dev
, apdev
):
1102 """Preference on HT20 over no-HT in roaming consideration"""
1103 params
= { "ssid": "test",
1106 hapd
= hostapd
.add_ap(apdev
[0], params
)
1107 bssid
= apdev
[0]['bssid']
1109 dev
[0].scan_for_bss(bssid
, freq
=2412)
1110 dev
[0].connect("test", key_mgmt
="NONE", scan_freq
="2412")
1112 params
= { "ssid": "test",
1115 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1116 bssid2
= apdev
[1]['bssid']
1117 dev
[0].scan_for_bss(bssid2
, freq
=2412)
1118 dev
[0].scan(freq
=2412)
1119 dev
[0].wait_connected()
1121 if dev
[0].get_status_field('bssid') != bssid2
:
1122 raise Exception("Unexpected BSS selected")
1124 def test_ap_ht40_5ghz_invalid_pair(dev
, apdev
):
1125 """HT40 on 5 GHz with invalid channel pair"""
1126 clear_scan_cache(apdev
[0])
1128 params
= { "ssid": "test-ht40",
1131 "country_code": "US",
1132 "ht_capab": "[HT40+]"}
1133 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
1134 ev
= hapd
.wait_event(["AP-DISABLED", "AP-ENABLED"], timeout
=10)
1136 raise Exception("AP setup failure timed out")
1137 if "AP-ENABLED" in ev
:
1138 sec
= hapd
.get_status_field("secondary_channel")
1140 raise Exception("Invalid 40 MHz channel accepted")
1142 set_world_reg(apdev
[0], None, None)
1144 def test_ap_ht40_5ghz_disabled_sec(dev
, apdev
):
1145 """HT40 on 5 GHz with disabled secondary channel"""
1146 clear_scan_cache(apdev
[0])
1148 params
= { "ssid": "test-ht40",
1151 "country_code": "US",
1152 "ht_capab": "[HT40+]"}
1153 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
1154 ev
= hapd
.wait_event(["AP-DISABLED", "AP-ENABLED"], timeout
=10)
1156 raise Exception("AP setup failure timed out")
1157 if "AP-ENABLED" in ev
:
1158 sec
= hapd
.get_status_field("secondary_channel")
1160 raise Exception("Invalid 40 MHz channel accepted")
1162 set_world_reg(apdev
[0], None, None)
1164 def test_ap_ht40_scan_broken_ap(dev
, apdev
):
1165 """HT40 co-ex scan and broken legacy/HT AP"""
1166 clear_scan_cache(apdev
[0])
1168 # Broken AP: Include HT Capabilities element but not HT Operation element
1169 params
= { "ssid": "legacy-20",
1170 "channel": "7", "ieee80211n": "0",
1172 "vendor_elements": "2d1a0e001bffff000000000000000000000100000000000000000000" }
1173 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1175 params
= { "ssid": "test-ht40",
1177 "ht_capab": "[HT40-]"}
1178 hapd
= hostapd
.add_ap(apdev
[0], params
, wait_enabled
=False)
1180 state
= hapd
.get_status_field("state")
1181 if state
!= "HT_SCAN":
1183 state
= hapd
.get_status_field("state")
1184 if state
!= "HT_SCAN":
1185 raise Exception("Unexpected interface state - expected HT_SCAN")
1187 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
1189 raise Exception("AP setup timed out")
1191 state
= hapd
.get_status_field("state")
1192 if state
!= "ENABLED":
1193 raise Exception("Unexpected interface state - expected ENABLED")
1195 freq
= hapd
.get_status_field("freq")
1197 raise Exception("Unexpected frequency: " + freq
)
1198 pri
= hapd
.get_status_field("channel")
1200 raise Exception("Unexpected primary channel: " + pri
)
1201 sec
= hapd
.get_status_field("secondary_channel")
1203 raise Exception("Unexpected secondary channel: " + sec
)
1205 dev
[0].connect("test-ht40", key_mgmt
="NONE", scan_freq
=freq
)
1206 dev
[1].connect("legacy-20", key_mgmt
="NONE", scan_freq
="2442")
1207 hwsim_utils
.test_connectivity(dev
[0], hapd
)
1208 hwsim_utils
.test_connectivity(dev
[1], hapd2
)