]> git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_ap_vht.py
tests: Pass full apdev to add_ap() function (1)
[thirdparty/hostap.git] / tests / hwsim / test_ap_vht.py
1 # Test cases for VHT operations with hostapd
2 # Copyright (c) 2014, Qualcomm Atheros, Inc.
3 # Copyright (c) 2013, Intel Corporation
4 #
5 # This software may be distributed under the terms of the BSD license.
6 # See README for more details.
7
8 import logging
9 logger = logging.getLogger()
10 import os
11 import subprocess, time
12
13 import hwsim_utils
14 import hostapd
15 from utils import HwsimSkip
16 from test_dfs import wait_dfs_event
17 from test_ap_csa import csa_supported
18 from test_ap_ht import clear_scan_cache
19
20 def vht_supported():
21 cmd = subprocess.Popen(["iw", "reg", "get"], stdout=subprocess.PIPE)
22 reg = cmd.stdout.read()
23 if "@ 80)" in reg or "@ 160)" in reg:
24 return True
25 return False
26
27 def test_ap_vht80(dev, apdev):
28 """VHT with 80 MHz channel width"""
29 try:
30 hapd = None
31 params = { "ssid": "vht",
32 "country_code": "FI",
33 "hw_mode": "a",
34 "channel": "36",
35 "ht_capab": "[HT40+]",
36 "ieee80211n": "1",
37 "ieee80211ac": "1",
38 "vht_oper_chwidth": "1",
39 "vht_oper_centr_freq_seg0_idx": "42" }
40 hapd = hostapd.add_ap(apdev[0], params)
41 bssid = apdev[0]['bssid']
42
43 dev[0].connect("vht", key_mgmt="NONE", scan_freq="5180")
44 hwsim_utils.test_connectivity(dev[0], hapd)
45 sig = dev[0].request("SIGNAL_POLL").splitlines()
46 if "FREQUENCY=5180" not in sig:
47 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
48 if "WIDTH=80 MHz" not in sig:
49 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
50 est = dev[0].get_bss(bssid)['est_throughput']
51 if est != "390001":
52 raise Exception("Unexpected BSS est_throughput: " + est)
53 except Exception, e:
54 if isinstance(e, Exception) and str(e) == "AP startup failed":
55 if not vht_supported():
56 raise HwsimSkip("80 MHz channel not supported in regulatory information")
57 raise
58 finally:
59 dev[0].request("DISCONNECT")
60 if hapd:
61 hapd.request("DISABLE")
62 subprocess.call(['iw', 'reg', 'set', '00'])
63 dev[0].flush_scan_cache()
64
65 def vht80_test(apdev, dev, channel, ht_capab):
66 clear_scan_cache(apdev['ifname'])
67 try:
68 hapd = None
69 params = { "ssid": "vht",
70 "country_code": "FI",
71 "hw_mode": "a",
72 "channel": str(channel),
73 "ht_capab": ht_capab,
74 "ieee80211n": "1",
75 "ieee80211ac": "1",
76 "vht_oper_chwidth": "1",
77 "vht_oper_centr_freq_seg0_idx": "42" }
78 hapd = hostapd.add_ap(apdev['ifname'], params)
79 bssid = apdev['bssid']
80
81 dev.connect("vht", key_mgmt="NONE", scan_freq=str(5000 + 5 * channel))
82 hwsim_utils.test_connectivity(dev, hapd)
83 except Exception, e:
84 if isinstance(e, Exception) and str(e) == "AP startup failed":
85 if not vht_supported():
86 raise HwsimSkip("80 MHz channel not supported in regulatory information")
87 raise
88 finally:
89 dev.request("DISCONNECT")
90 if hapd:
91 hapd.request("DISABLE")
92 subprocess.call(['iw', 'reg', 'set', '00'])
93 dev.flush_scan_cache()
94
95 def test_ap_vht80b(dev, apdev):
96 """VHT with 80 MHz channel width (HT40- channel 40)"""
97 vht80_test(apdev[0], dev[0], 40, "[HT40-]")
98
99 def test_ap_vht80c(dev, apdev):
100 """VHT with 80 MHz channel width (HT40+ channel 44)"""
101 vht80_test(apdev[0], dev[0], 44, "[HT40+]")
102
103 def test_ap_vht80d(dev, apdev):
104 """VHT with 80 MHz channel width (HT40- channel 48)"""
105 vht80_test(apdev[0], dev[0], 48, "[HT40-]")
106
107 def test_ap_vht80_params(dev, apdev):
108 """VHT with 80 MHz channel width and number of optional features enabled"""
109 try:
110 hapd = None
111 params = { "ssid": "vht",
112 "country_code": "FI",
113 "hw_mode": "a",
114 "channel": "36",
115 "ht_capab": "[HT40+][SHORT-GI-40][DSS_CCK-40]",
116 "ieee80211n": "1",
117 "ieee80211ac": "1",
118 "vht_oper_chwidth": "1",
119 "vht_capab": "[MAX-MPDU-11454][RXLDPC][SHORT-GI-80][TX-STBC-2BY1][RX-STBC-1][MAX-A-MPDU-LEN-EXP0]",
120 "vht_oper_centr_freq_seg0_idx": "42",
121 "require_vht": "1" }
122 hapd = hostapd.add_ap(apdev[0], params)
123
124 dev[1].connect("vht", key_mgmt="NONE", scan_freq="5180",
125 disable_vht="1", wait_connect=False)
126 dev[0].connect("vht", key_mgmt="NONE", scan_freq="5180")
127 ev = dev[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
128 if ev is None:
129 raise Exception("Association rejection timed out")
130 if "status_code=104" not in ev:
131 raise Exception("Unexpected rejection status code")
132 dev[1].request("DISCONNECT")
133 hwsim_utils.test_connectivity(dev[0], hapd)
134 except Exception, e:
135 if isinstance(e, Exception) and str(e) == "AP startup failed":
136 if not vht_supported():
137 raise HwsimSkip("80 MHz channel not supported in regulatory information")
138 raise
139 finally:
140 dev[0].request("DISCONNECT")
141 dev[1].request("DISCONNECT")
142 if hapd:
143 hapd.request("DISABLE")
144 subprocess.call(['iw', 'reg', 'set', '00'])
145 dev[0].flush_scan_cache()
146 dev[1].flush_scan_cache()
147
148 def test_ap_vht80_invalid(dev, apdev):
149 """VHT with invalid 80 MHz channel configuration (seg1)"""
150 try:
151 hapd = None
152 params = { "ssid": "vht",
153 "country_code": "US",
154 "hw_mode": "a",
155 "channel": "36",
156 "ht_capab": "[HT40+]",
157 "ieee80211n": "1",
158 "ieee80211ac": "1",
159 "vht_oper_chwidth": "1",
160 "vht_oper_centr_freq_seg0_idx": "42",
161 "vht_oper_centr_freq_seg1_idx": "155",
162 'ieee80211d': '1',
163 'ieee80211h': '1' }
164 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
165 # This fails due to unexpected seg1 configuration
166 ev = hapd.wait_event(["AP-DISABLED"], timeout=5)
167 if ev is None:
168 raise Exception("AP-DISABLED not reported")
169 except Exception, e:
170 if isinstance(e, Exception) and str(e) == "AP startup failed":
171 if not vht_supported():
172 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
173 raise
174 finally:
175 if hapd:
176 hapd.request("DISABLE")
177 subprocess.call(['iw', 'reg', 'set', '00'])
178
179 def test_ap_vht80_invalid2(dev, apdev):
180 """VHT with invalid 80 MHz channel configuration (seg0)"""
181 try:
182 hapd = None
183 params = { "ssid": "vht",
184 "country_code": "US",
185 "hw_mode": "a",
186 "channel": "36",
187 "ht_capab": "[HT40+]",
188 "ieee80211n": "1",
189 "ieee80211ac": "1",
190 "vht_oper_chwidth": "1",
191 "vht_oper_centr_freq_seg0_idx": "46",
192 'ieee80211d': '1',
193 'ieee80211h': '1' }
194 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
195 # This fails due to invalid seg0 configuration
196 ev = hapd.wait_event(["AP-DISABLED"], timeout=5)
197 if ev is None:
198 raise Exception("AP-DISABLED not reported")
199 except Exception, e:
200 if isinstance(e, Exception) and str(e) == "AP startup failed":
201 if not vht_supported():
202 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
203 raise
204 finally:
205 if hapd:
206 hapd.request("DISABLE")
207 subprocess.call(['iw', 'reg', 'set', '00'])
208
209 def test_ap_vht_20(devs, apdevs):
210 """VHT and 20 MHz channel"""
211 dev = devs[0]
212 ap = apdevs[0]
213 try:
214 hapd = None
215 params = { "ssid": "test-vht20",
216 "country_code": "DE",
217 "hw_mode": "a",
218 "channel": "36",
219 "ieee80211n": "1",
220 "ieee80211ac": "1",
221 "ht_capab": "",
222 "vht_capab": "",
223 "vht_oper_chwidth": "0",
224 "vht_oper_centr_freq_seg0_idx": "0",
225 "supported_rates": "60 120 240 360 480 540",
226 "require_vht": "1",
227 }
228 hapd = hostapd.add_ap(ap['ifname'], params)
229 dev.connect("test-vht20", scan_freq="5180", key_mgmt="NONE")
230 hwsim_utils.test_connectivity(dev, hapd)
231 finally:
232 dev.request("DISCONNECT")
233 if hapd:
234 hapd.request("DISABLE")
235 subprocess.call(['iw', 'reg', 'set', '00'])
236 dev.flush_scan_cache()
237
238 def test_ap_vht_40(devs, apdevs):
239 """VHT and 40 MHz channel"""
240 dev = devs[0]
241 ap = apdevs[0]
242 try:
243 hapd = None
244 params = { "ssid": "test-vht40",
245 "country_code": "DE",
246 "hw_mode": "a",
247 "channel": "36",
248 "ieee80211n": "1",
249 "ieee80211ac": "1",
250 "ht_capab": "[HT40+]",
251 "vht_capab": "",
252 "vht_oper_chwidth": "0",
253 "vht_oper_centr_freq_seg0_idx": "0",
254 }
255 hapd = hostapd.add_ap(ap['ifname'], params)
256 dev.connect("test-vht40", scan_freq="5180", key_mgmt="NONE")
257 hwsim_utils.test_connectivity(dev, hapd)
258 finally:
259 dev.request("DISCONNECT")
260 if hapd:
261 hapd.request("DISABLE")
262 subprocess.call(['iw', 'reg', 'set', '00'])
263 dev.flush_scan_cache()
264
265 def test_ap_vht_capab_not_supported(dev, apdev):
266 """VHT configuration with driver not supporting all vht_capab entries"""
267 try:
268 params = { "ssid": "vht",
269 "country_code": "FI",
270 "hw_mode": "a",
271 "channel": "36",
272 "ht_capab": "[HT40+][SHORT-GI-40][DSS_CCK-40]",
273 "ieee80211n": "1",
274 "ieee80211ac": "1",
275 "vht_oper_chwidth": "1",
276 "vht_capab": "[MAX-MPDU-7991][MAX-MPDU-11454][VHT160][VHT160-80PLUS80][RXLDPC][SHORT-GI-80][SHORT-GI-160][TX-STBC-2BY1][RX-STBC-1][RX-STBC-12][RX-STBC-123][RX-STBC-1234][SU-BEAMFORMER][SU-BEAMFORMEE][BF-ANTENNA-2][BF-ANTENNA-3][BF-ANTENNA-4][SOUNDING-DIMENSION-2][SOUNDING-DIMENSION-3][SOUNDING-DIMENSION-4][MU-BEAMFORMER][VHT-TXOP-PS][HTC-VHT][MAX-A-MPDU-LEN-EXP0][MAX-A-MPDU-LEN-EXP7][VHT-LINK-ADAPT2][VHT-LINK-ADAPT3][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]",
277 "vht_oper_centr_freq_seg0_idx": "42",
278 "require_vht": "1" }
279 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
280 ev = hapd.wait_event(["AP-DISABLED"], timeout=5)
281 if ev is None:
282 raise Exception("Startup failure not reported")
283 for i in range(1, 7):
284 if "OK" not in hapd.request("SET vht_capab [MAX-A-MPDU-LEN-EXP%d]" % i):
285 raise Exception("Unexpected SET failure")
286 finally:
287 subprocess.call(['iw', 'reg', 'set', '00'])
288
289 def test_ap_vht160(dev, apdev):
290 """VHT with 160 MHz channel width"""
291 try:
292 hapd = None
293 hapd2 = None
294 params = { "ssid": "vht",
295 "country_code": "FI",
296 "hw_mode": "a",
297 "channel": "36",
298 "ht_capab": "[HT40+]",
299 "ieee80211n": "1",
300 "ieee80211ac": "1",
301 "vht_oper_chwidth": "2",
302 "vht_oper_centr_freq_seg0_idx": "50",
303 'ieee80211d': '1',
304 'ieee80211h': '1' }
305 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
306
307 ev = wait_dfs_event(hapd, "DFS-CAC-START", 5)
308 if "DFS-CAC-START" not in ev:
309 raise Exception("Unexpected DFS event")
310
311 state = hapd.get_status_field("state")
312 if state != "DFS":
313 if state == "DISABLED" and not os.path.exists("dfs"):
314 # Not all systems have recent enough CRDA version and
315 # wireless-regdb changes to support 160 MHz and DFS. For now,
316 # do not report failures for this test case.
317 raise HwsimSkip("CRDA or wireless-regdb did not support 160 MHz")
318 raise Exception("Unexpected interface state: " + state)
319
320 params = { "ssid": "vht2",
321 "country_code": "FI",
322 "hw_mode": "a",
323 "channel": "104",
324 "ht_capab": "[HT40-]",
325 "ieee80211n": "1",
326 "ieee80211ac": "1",
327 "vht_oper_chwidth": "2",
328 "vht_oper_centr_freq_seg0_idx": "114",
329 'ieee80211d': '1',
330 'ieee80211h': '1' }
331 hapd2 = hostapd.add_ap(apdev[1], params, wait_enabled=False)
332
333 ev = wait_dfs_event(hapd2, "DFS-CAC-START", 5)
334 if "DFS-CAC-START" not in ev:
335 raise Exception("Unexpected DFS event(2)")
336
337 state = hapd2.get_status_field("state")
338 if state != "DFS":
339 raise Exception("Unexpected interface state(2): " + state)
340
341 logger.info("Waiting for CAC to complete")
342
343 ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
344 if "success=1" not in ev:
345 raise Exception("CAC failed")
346 if "freq=5180" not in ev:
347 raise Exception("Unexpected DFS freq result")
348
349 ev = hapd.wait_event(["AP-ENABLED"], timeout=5)
350 if not ev:
351 raise Exception("AP setup timed out")
352
353 state = hapd.get_status_field("state")
354 if state != "ENABLED":
355 raise Exception("Unexpected interface state")
356
357 ev = wait_dfs_event(hapd2, "DFS-CAC-COMPLETED", 70)
358 if "success=1" not in ev:
359 raise Exception("CAC failed(2)")
360 if "freq=5520" not in ev:
361 raise Exception("Unexpected DFS freq result(2)")
362
363 ev = hapd2.wait_event(["AP-ENABLED"], timeout=5)
364 if not ev:
365 raise Exception("AP setup timed out(2)")
366
367 state = hapd2.get_status_field("state")
368 if state != "ENABLED":
369 raise Exception("Unexpected interface state(2)")
370
371 freq = hapd2.get_status_field("freq")
372 if freq != "5520":
373 raise Exception("Unexpected frequency(2)")
374
375 dev[0].connect("vht", key_mgmt="NONE", scan_freq="5180")
376 hwsim_utils.test_connectivity(dev[0], hapd)
377 sig = dev[0].request("SIGNAL_POLL").splitlines()
378 if "FREQUENCY=5180" not in sig:
379 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
380 if "WIDTH=160 MHz" not in sig:
381 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
382 dev[1].connect("vht2", key_mgmt="NONE", scan_freq="5520")
383 hwsim_utils.test_connectivity(dev[1], hapd2)
384 sig = dev[1].request("SIGNAL_POLL").splitlines()
385 if "FREQUENCY=5520" not in sig:
386 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
387 if "WIDTH=160 MHz" not in sig:
388 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
389 except Exception, e:
390 if isinstance(e, Exception) and str(e) == "AP startup failed":
391 if not vht_supported():
392 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
393 raise
394 finally:
395 dev[0].request("DISCONNECT")
396 dev[1].request("DISCONNECT")
397 if hapd:
398 hapd.request("DISABLE")
399 if hapd2:
400 hapd2.request("DISABLE")
401 subprocess.call(['iw', 'reg', 'set', '00'])
402 dev[0].flush_scan_cache()
403 dev[1].flush_scan_cache()
404
405 def test_ap_vht160_no_dfs(dev, apdev):
406 """VHT with 160 MHz channel width and no DFS"""
407 try:
408 hapd = None
409 params = { "ssid": "vht",
410 "country_code": "ZA",
411 "hw_mode": "a",
412 "channel": "104",
413 "ht_capab": "[HT40-]",
414 "ieee80211n": "1",
415 "ieee80211ac": "1",
416 "vht_oper_chwidth": "2",
417 "vht_oper_centr_freq_seg0_idx": "114",
418 'ieee80211d': '1',
419 'ieee80211h': '1' }
420 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
421 ev = hapd.wait_event(["AP-ENABLED"], timeout=2)
422 if not ev:
423 cmd = subprocess.Popen(["iw", "reg", "get"], stdout=subprocess.PIPE)
424 reg = cmd.stdout.readlines()
425 for r in reg:
426 if "5490" in r and "DFS" in r:
427 raise HwsimSkip("ZA regulatory rule did not have DFS requirement removed")
428 raise Exception("AP setup timed out")
429
430 dev[0].connect("vht", key_mgmt="NONE", scan_freq="5520")
431 hwsim_utils.test_connectivity(dev[0], hapd)
432 sig = dev[0].request("SIGNAL_POLL").splitlines()
433 if "FREQUENCY=5520" not in sig:
434 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
435 if "WIDTH=160 MHz" not in sig:
436 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
437 except Exception, e:
438 if isinstance(e, Exception) and str(e) == "AP startup failed":
439 if not vht_supported():
440 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
441 raise
442 finally:
443 dev[0].request("DISCONNECT")
444 if hapd:
445 hapd.request("DISABLE")
446 subprocess.call(['iw', 'reg', 'set', '00'])
447 dev[0].flush_scan_cache()
448
449 def test_ap_vht80plus80(dev, apdev):
450 """VHT with 80+80 MHz channel width"""
451 try:
452 hapd = None
453 hapd2 = None
454 params = { "ssid": "vht",
455 "country_code": "US",
456 "hw_mode": "a",
457 "channel": "52",
458 "ht_capab": "[HT40+]",
459 "ieee80211n": "1",
460 "ieee80211ac": "1",
461 "vht_oper_chwidth": "3",
462 "vht_oper_centr_freq_seg0_idx": "58",
463 "vht_oper_centr_freq_seg1_idx": "155",
464 'ieee80211d': '1',
465 'ieee80211h': '1' }
466 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
467 # This will actually fail since DFS on 80+80 is not yet supported
468 ev = hapd.wait_event(["AP-DISABLED"], timeout=5)
469 # ignore result to avoid breaking the test once 80+80 DFS gets enabled
470
471 params = { "ssid": "vht2",
472 "country_code": "US",
473 "hw_mode": "a",
474 "channel": "36",
475 "ht_capab": "[HT40+]",
476 "ieee80211n": "1",
477 "ieee80211ac": "1",
478 "vht_oper_chwidth": "3",
479 "vht_oper_centr_freq_seg0_idx": "42",
480 "vht_oper_centr_freq_seg1_idx": "155" }
481 hapd2 = hostapd.add_ap(apdev[1], params, wait_enabled=False)
482
483 ev = hapd2.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=5)
484 if not ev:
485 raise Exception("AP setup timed out(2)")
486 if "AP-DISABLED" in ev:
487 # Assume this failed due to missing regulatory update for now
488 raise HwsimSkip("80+80 MHz channel not supported in regulatory information")
489
490 state = hapd2.get_status_field("state")
491 if state != "ENABLED":
492 raise Exception("Unexpected interface state(2)")
493
494 dev[1].connect("vht2", key_mgmt="NONE", scan_freq="5180")
495 hwsim_utils.test_connectivity(dev[1], hapd2)
496 sig = dev[1].request("SIGNAL_POLL").splitlines()
497 if "FREQUENCY=5180" not in sig:
498 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
499 if "WIDTH=80+80 MHz" not in sig:
500 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
501 if "CENTER_FRQ1=5210" not in sig:
502 raise Exception("Unexpected SIGNAL_POLL value(3): " + str(sig))
503 if "CENTER_FRQ2=5775" not in sig:
504 raise Exception("Unexpected SIGNAL_POLL value(4): " + str(sig))
505 except Exception, e:
506 if isinstance(e, Exception) and str(e) == "AP startup failed":
507 if not vht_supported():
508 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
509 raise
510 finally:
511 dev[0].request("DISCONNECT")
512 dev[1].request("DISCONNECT")
513 if hapd:
514 hapd.request("DISABLE")
515 if hapd2:
516 hapd2.request("DISABLE")
517 subprocess.call(['iw', 'reg', 'set', '00'])
518 dev[0].flush_scan_cache()
519 dev[1].flush_scan_cache()
520
521 def test_ap_vht80plus80_invalid(dev, apdev):
522 """VHT with invalid 80+80 MHz channel"""
523 try:
524 hapd = None
525 params = { "ssid": "vht",
526 "country_code": "US",
527 "hw_mode": "a",
528 "channel": "36",
529 "ht_capab": "[HT40+]",
530 "ieee80211n": "1",
531 "ieee80211ac": "1",
532 "vht_oper_chwidth": "3",
533 "vht_oper_centr_freq_seg0_idx": "42",
534 "vht_oper_centr_freq_seg1_idx": "0",
535 'ieee80211d': '1',
536 'ieee80211h': '1' }
537 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
538 # This fails due to missing(invalid) seg1 configuration
539 ev = hapd.wait_event(["AP-DISABLED"], timeout=5)
540 if ev is None:
541 raise Exception("AP-DISABLED not reported")
542 except Exception, e:
543 if isinstance(e, Exception) and str(e) == "AP startup failed":
544 if not vht_supported():
545 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
546 raise
547 finally:
548 if hapd:
549 hapd.request("DISABLE")
550 subprocess.call(['iw', 'reg', 'set', '00'])
551
552 def test_ap_vht80_csa(dev, apdev):
553 """VHT with 80 MHz channel width and CSA"""
554 csa_supported(dev[0])
555 try:
556 hapd = None
557 params = { "ssid": "vht",
558 "country_code": "US",
559 "hw_mode": "a",
560 "channel": "149",
561 "ht_capab": "[HT40+]",
562 "ieee80211n": "1",
563 "ieee80211ac": "1",
564 "vht_oper_chwidth": "1",
565 "vht_oper_centr_freq_seg0_idx": "155" }
566 hapd = hostapd.add_ap(apdev[0], params)
567
568 dev[0].connect("vht", key_mgmt="NONE", scan_freq="5745")
569 hwsim_utils.test_connectivity(dev[0], hapd)
570
571 hapd.request("CHAN_SWITCH 5 5180 ht vht blocktx center_freq1=5210 sec_channel_offset=1 bandwidth=80")
572 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
573 if ev is None:
574 raise Exception("CSA finished event timed out")
575 if "freq=5180" not in ev:
576 raise Exception("Unexpected channel in CSA finished event")
577 time.sleep(0.5)
578 hwsim_utils.test_connectivity(dev[0], hapd)
579
580 hapd.request("CHAN_SWITCH 5 5745")
581 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
582 if ev is None:
583 raise Exception("CSA finished event timed out")
584 if "freq=5745" not in ev:
585 raise Exception("Unexpected channel in CSA finished event")
586 time.sleep(0.5)
587 hwsim_utils.test_connectivity(dev[0], hapd)
588
589 # This CSA to same channel will fail in kernel, so use this only for
590 # extra code coverage.
591 hapd.request("CHAN_SWITCH 5 5745")
592 hapd.wait_event(["AP-CSA-FINISHED"], timeout=1)
593 except Exception, e:
594 if isinstance(e, Exception) and str(e) == "AP startup failed":
595 if not vht_supported():
596 raise HwsimSkip("80 MHz channel not supported in regulatory information")
597 raise
598 finally:
599 dev[0].request("DISCONNECT")
600 if hapd:
601 hapd.request("DISABLE")
602 subprocess.call(['iw', 'reg', 'set', '00'])
603 dev[0].flush_scan_cache()
604
605 def test_ap_vht_on_24ghz(dev, apdev):
606 """Subset of VHT features on 2.4 GHz"""
607 hapd = None
608 params = { "ssid": "test-vht-2g",
609 "hw_mode": "g",
610 "channel": "1",
611 "ieee80211n": "1",
612 "vendor_vht": "1",
613 "vht_capab": "[MAX-MPDU-11454]",
614 "vht_oper_chwidth": "0",
615 "vht_oper_centr_freq_seg0_idx": "1"
616 }
617 hapd = hostapd.add_ap(apdev[0], params)
618 try:
619 if "OK" not in dev[0].request("VENDOR_ELEM_ADD 13 dd1300904c0400bf0c3240820feaff0000eaff0000"):
620 raise Exception("Failed to add vendor element")
621 dev[0].connect("test-vht-2g", scan_freq="2412", key_mgmt="NONE")
622 hwsim_utils.test_connectivity(dev[0], hapd)
623 sta = hapd.get_sta(dev[0].own_addr())
624 if '[VENDOR_VHT]' not in sta['flags']:
625 raise Exception("No VENDOR_VHT STA flag")
626
627 dev[1].connect("test-vht-2g", scan_freq="2412", key_mgmt="NONE")
628 sta = hapd.get_sta(dev[1].own_addr())
629 if '[VENDOR_VHT]' in sta['flags']:
630 raise Exception("Unexpected VENDOR_VHT STA flag")
631 finally:
632 dev[0].request("VENDOR_ELEM_REMOVE 13 *")
633
634 def test_prefer_vht40(dev, apdev):
635 """Preference on VHT40 over HT40"""
636 try:
637 hapd2 = None
638
639 params = { "ssid": "test",
640 "country_code": "FI",
641 "hw_mode": "a",
642 "channel": "36",
643 "ieee80211n": "1",
644 "ht_capab": "[HT40+]" }
645 hapd = hostapd.add_ap(apdev[0], params)
646 bssid = apdev[0]['bssid']
647
648 params = { "ssid": "test",
649 "country_code": "FI",
650 "hw_mode": "a",
651 "channel": "36",
652 "ieee80211n": "1",
653 "ieee80211ac": "1",
654 "ht_capab": "[HT40+]",
655 "vht_capab": "",
656 "vht_oper_chwidth": "0",
657 "vht_oper_centr_freq_seg0_idx": "0",
658 }
659 hapd2 = hostapd.add_ap(apdev[1], params)
660 bssid2 = apdev[1]['bssid']
661
662 dev[0].scan_for_bss(bssid, freq=5180)
663 dev[0].scan_for_bss(bssid2, freq=5180)
664 dev[0].connect("test", scan_freq="5180", key_mgmt="NONE")
665 if dev[0].get_status_field('bssid') != bssid2:
666 raise Exception("Unexpected BSS selected")
667
668 est = dev[0].get_bss(bssid)['est_throughput']
669 if est != "135000":
670 raise Exception("Unexpected BSS0 est_throughput: " + est)
671
672 est = dev[0].get_bss(bssid2)['est_throughput']
673 if est != "135001":
674 raise Exception("Unexpected BSS1 est_throughput: " + est)
675 finally:
676 dev[0].request("DISCONNECT")
677 if hapd2:
678 hapd2.request("DISABLE")
679 subprocess.call(['iw', 'reg', 'set', '00'])
680 dev[0].flush_scan_cache()
681
682 def test_ap_vht80_pwr_constraint(dev, apdev):
683 """VHT with 80 MHz channel width and local power constraint"""
684 hapd = None
685 try:
686 params = { "ssid": "vht",
687 "country_code": "FI",
688 "hw_mode": "a",
689 "channel": "36",
690 "ht_capab": "[HT40+]",
691 "ieee80211d": "1",
692 "local_pwr_constraint": "3",
693 "ieee80211n": "1",
694 "ieee80211ac": "1",
695 "vht_oper_chwidth": "1",
696 "vht_oper_centr_freq_seg0_idx": "42" }
697 hapd = hostapd.add_ap(apdev[0], params)
698
699 dev[0].connect("vht", key_mgmt="NONE", scan_freq="5180")
700 except Exception, e:
701 if isinstance(e, Exception) and str(e) == "AP startup failed":
702 if not vht_supported():
703 raise HwsimSkip("80 MHz channel not supported in regulatory information")
704 raise
705 finally:
706 dev[0].request("DISCONNECT")
707 if hapd:
708 hapd.request("DISABLE")
709 subprocess.call(['iw', 'reg', 'set', '00'])
710 dev[0].flush_scan_cache()