tests: Verify SIGNAL_POLL values in ap_vht80
[mech_eap.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]['ifname'], 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]['ifname'], 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_vht_20(devs, apdevs):
149     """VHT and 20 MHz channel"""
150     dev = devs[0]
151     ap = apdevs[0]
152     try:
153         hapd = None
154         params = { "ssid": "test-vht20",
155                    "country_code": "DE",
156                    "hw_mode": "a",
157                    "channel": "36",
158                    "ieee80211n": "1",
159                    "ieee80211ac": "1",
160                    "ht_capab": "",
161                    "vht_capab": "",
162                    "vht_oper_chwidth": "0",
163                    "vht_oper_centr_freq_seg0_idx": "0",
164                    "supported_rates": "60 120 240 360 480 540",
165                    "require_vht": "1",
166                  }
167         hapd = hostapd.add_ap(ap['ifname'], params)
168         dev.connect("test-vht20", scan_freq="5180", key_mgmt="NONE")
169         hwsim_utils.test_connectivity(dev, hapd)
170     finally:
171         dev.request("DISCONNECT")
172         if hapd:
173             hapd.request("DISABLE")
174         subprocess.call(['iw', 'reg', 'set', '00'])
175         dev.flush_scan_cache()
176
177 def test_ap_vht_40(devs, apdevs):
178     """VHT and 40 MHz channel"""
179     dev = devs[0]
180     ap = apdevs[0]
181     try:
182         hapd = None
183         params = { "ssid": "test-vht40",
184                    "country_code": "DE",
185                    "hw_mode": "a",
186                    "channel": "36",
187                    "ieee80211n": "1",
188                    "ieee80211ac": "1",
189                    "ht_capab": "[HT40+]",
190                    "vht_capab": "",
191                    "vht_oper_chwidth": "0",
192                    "vht_oper_centr_freq_seg0_idx": "0",
193                  }
194         hapd = hostapd.add_ap(ap['ifname'], params)
195         dev.connect("test-vht40", scan_freq="5180", key_mgmt="NONE")
196         hwsim_utils.test_connectivity(dev, hapd)
197     finally:
198         dev.request("DISCONNECT")
199         if hapd:
200             hapd.request("DISABLE")
201         subprocess.call(['iw', 'reg', 'set', '00'])
202         dev.flush_scan_cache()
203
204 def test_ap_vht_capab_not_supported(dev, apdev):
205     """VHT configuration with driver not supporting all vht_capab entries"""
206     try:
207         params = { "ssid": "vht",
208                    "country_code": "FI",
209                    "hw_mode": "a",
210                    "channel": "36",
211                    "ht_capab": "[HT40+][SHORT-GI-40][DSS_CCK-40]",
212                    "ieee80211n": "1",
213                    "ieee80211ac": "1",
214                    "vht_oper_chwidth": "1",
215                    "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]",
216                    "vht_oper_centr_freq_seg0_idx": "42",
217                    "require_vht": "1" }
218         hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
219         ev = hapd.wait_event(["AP-DISABLED"], timeout=5)
220         if ev is None:
221             raise Exception("Startup failure not reported")
222         for i in range(1, 7):
223             if "OK" not in hapd.request("SET vht_capab [MAX-A-MPDU-LEN-EXP%d]" % i):
224                 raise Exception("Unexpected SET failure")
225     finally:
226         subprocess.call(['iw', 'reg', 'set', '00'])
227
228 def test_ap_vht160(dev, apdev):
229     """VHT with 160 MHz channel width"""
230     try:
231         hapd = None
232         hapd2 = None
233         params = { "ssid": "vht",
234                    "country_code": "FI",
235                    "hw_mode": "a",
236                    "channel": "36",
237                    "ht_capab": "[HT40+]",
238                    "ieee80211n": "1",
239                    "ieee80211ac": "1",
240                    "vht_oper_chwidth": "2",
241                    "vht_oper_centr_freq_seg0_idx": "50",
242                    'ieee80211d': '1',
243                    'ieee80211h': '1' }
244         hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
245
246         ev = wait_dfs_event(hapd, "DFS-CAC-START", 5)
247         if "DFS-CAC-START" not in ev:
248             raise Exception("Unexpected DFS event")
249
250         state = hapd.get_status_field("state")
251         if state != "DFS":
252             if state == "DISABLED" and not os.path.exists("dfs"):
253                 # Not all systems have recent enough CRDA version and
254                 # wireless-regdb changes to support 160 MHz and DFS. For now,
255                 # do not report failures for this test case.
256                 raise HwsimSkip("CRDA or wireless-regdb did not support 160 MHz")
257             raise Exception("Unexpected interface state: " + state)
258
259         params = { "ssid": "vht2",
260                    "country_code": "FI",
261                    "hw_mode": "a",
262                    "channel": "104",
263                    "ht_capab": "[HT40-]",
264                    "ieee80211n": "1",
265                    "ieee80211ac": "1",
266                    "vht_oper_chwidth": "2",
267                    "vht_oper_centr_freq_seg0_idx": "114",
268                    'ieee80211d': '1',
269                    'ieee80211h': '1' }
270         hapd2 = hostapd.add_ap(apdev[1]['ifname'], params, wait_enabled=False)
271
272         ev = wait_dfs_event(hapd2, "DFS-CAC-START", 5)
273         if "DFS-CAC-START" not in ev:
274             raise Exception("Unexpected DFS event(2)")
275
276         state = hapd2.get_status_field("state")
277         if state != "DFS":
278             raise Exception("Unexpected interface state(2): " + state)
279
280         logger.info("Waiting for CAC to complete")
281
282         ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
283         if "success=1" not in ev:
284             raise Exception("CAC failed")
285         if "freq=5180" not in ev:
286             raise Exception("Unexpected DFS freq result")
287
288         ev = hapd.wait_event(["AP-ENABLED"], timeout=5)
289         if not ev:
290             raise Exception("AP setup timed out")
291
292         state = hapd.get_status_field("state")
293         if state != "ENABLED":
294             raise Exception("Unexpected interface state")
295
296         ev = wait_dfs_event(hapd2, "DFS-CAC-COMPLETED", 70)
297         if "success=1" not in ev:
298             raise Exception("CAC failed(2)")
299         if "freq=5520" not in ev:
300             raise Exception("Unexpected DFS freq result(2)")
301
302         ev = hapd2.wait_event(["AP-ENABLED"], timeout=5)
303         if not ev:
304             raise Exception("AP setup timed out(2)")
305
306         state = hapd2.get_status_field("state")
307         if state != "ENABLED":
308             raise Exception("Unexpected interface state(2)")
309
310         freq = hapd2.get_status_field("freq")
311         if freq != "5520":
312             raise Exception("Unexpected frequency(2)")
313
314         dev[0].connect("vht", key_mgmt="NONE", scan_freq="5180")
315         hwsim_utils.test_connectivity(dev[0], hapd)
316         sig = dev[0].request("SIGNAL_POLL").splitlines()
317         if "FREQUENCY=5180" not in sig:
318             raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
319         if "WIDTH=160 MHz" not in sig:
320             raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
321         dev[1].connect("vht2", key_mgmt="NONE", scan_freq="5520")
322         hwsim_utils.test_connectivity(dev[1], hapd2)
323         sig = dev[1].request("SIGNAL_POLL").splitlines()
324         if "FREQUENCY=5520" not in sig:
325             raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
326         if "WIDTH=160 MHz" not in sig:
327             raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
328     except Exception, e:
329         if isinstance(e, Exception) and str(e) == "AP startup failed":
330             if not vht_supported():
331                 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
332         raise
333     finally:
334         dev[0].request("DISCONNECT")
335         dev[1].request("DISCONNECT")
336         if hapd:
337             hapd.request("DISABLE")
338         if hapd2:
339             hapd2.request("DISABLE")
340         subprocess.call(['iw', 'reg', 'set', '00'])
341         dev[0].flush_scan_cache()
342         dev[1].flush_scan_cache()
343
344 def test_ap_vht160_no_dfs(dev, apdev):
345     """VHT with 160 MHz channel width and no DFS"""
346     try:
347         hapd = None
348         params = { "ssid": "vht",
349                    "country_code": "ZA",
350                    "hw_mode": "a",
351                    "channel": "104",
352                    "ht_capab": "[HT40-]",
353                    "ieee80211n": "1",
354                    "ieee80211ac": "1",
355                    "vht_oper_chwidth": "2",
356                    "vht_oper_centr_freq_seg0_idx": "114",
357                    'ieee80211d': '1',
358                    'ieee80211h': '1' }
359         hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
360         ev = hapd.wait_event(["AP-ENABLED"], timeout=2)
361         if not ev:
362             cmd = subprocess.Popen(["iw", "reg", "get"], stdout=subprocess.PIPE)
363             reg = cmd.stdout.readlines()
364             for r in reg:
365                 if "5490" in r and "DFS" in r:
366                     raise HwsimSkip("ZA regulatory rule did not have DFS requirement removed")
367             raise Exception("AP setup timed out")
368
369         dev[0].connect("vht", key_mgmt="NONE", scan_freq="5520")
370         hwsim_utils.test_connectivity(dev[0], hapd)
371         sig = dev[0].request("SIGNAL_POLL").splitlines()
372         if "FREQUENCY=5520" not in sig:
373             raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
374         if "WIDTH=160 MHz" not in sig:
375             raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
376     except Exception, e:
377         if isinstance(e, Exception) and str(e) == "AP startup failed":
378             if not vht_supported():
379                 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
380         raise
381     finally:
382         dev[0].request("DISCONNECT")
383         if hapd:
384             hapd.request("DISABLE")
385         subprocess.call(['iw', 'reg', 'set', '00'])
386         dev[0].flush_scan_cache()
387
388 def test_ap_vht80plus80(dev, apdev):
389     """VHT with 80+80 MHz channel width"""
390     try:
391         hapd = None
392         hapd2 = None
393         params = { "ssid": "vht",
394                    "country_code": "US",
395                    "hw_mode": "a",
396                    "channel": "52",
397                    "ht_capab": "[HT40+]",
398                    "ieee80211n": "1",
399                    "ieee80211ac": "1",
400                    "vht_oper_chwidth": "3",
401                    "vht_oper_centr_freq_seg0_idx": "58",
402                    "vht_oper_centr_freq_seg1_idx": "155",
403                    'ieee80211d': '1',
404                    'ieee80211h': '1' }
405         hapd = hostapd.add_ap(apdev[0]['ifname'], params, wait_enabled=False)
406         # This will actually fail since DFS on 80+80 is not yet supported
407         ev = hapd.wait_event(["AP-DISABLED"], timeout=5)
408         # ignore result to avoid breaking the test once 80+80 DFS gets enabled
409
410         params = { "ssid": "vht2",
411                    "country_code": "US",
412                    "hw_mode": "a",
413                    "channel": "36",
414                    "ht_capab": "[HT40+]",
415                    "ieee80211n": "1",
416                    "ieee80211ac": "1",
417                    "vht_oper_chwidth": "3",
418                    "vht_oper_centr_freq_seg0_idx": "42",
419                    "vht_oper_centr_freq_seg1_idx": "155" }
420         hapd2 = hostapd.add_ap(apdev[1]['ifname'], params, wait_enabled=False)
421
422         ev = hapd2.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=5)
423         if not ev:
424             raise Exception("AP setup timed out(2)")
425         if "AP-DISABLED" in ev:
426             # Assume this failed due to missing regulatory update for now
427             raise HwsimSkip("80+80 MHz channel not supported in regulatory information")
428
429         state = hapd2.get_status_field("state")
430         if state != "ENABLED":
431             raise Exception("Unexpected interface state(2)")
432
433         dev[1].connect("vht2", key_mgmt="NONE", scan_freq="5180")
434         hwsim_utils.test_connectivity(dev[1], hapd2)
435         sig = dev[1].request("SIGNAL_POLL").splitlines()
436         if "FREQUENCY=5180" not in sig:
437             raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
438         if "WIDTH=80+80 MHz" not in sig:
439             raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
440         if "CENTER_FRQ1=5210" not in sig:
441             raise Exception("Unexpected SIGNAL_POLL value(3): " + str(sig))
442         if "CENTER_FRQ2=5775" not in sig:
443             raise Exception("Unexpected SIGNAL_POLL value(4): " + str(sig))
444     except Exception, e:
445         if isinstance(e, Exception) and str(e) == "AP startup failed":
446             if not vht_supported():
447                 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
448         raise
449     finally:
450         dev[0].request("DISCONNECT")
451         dev[1].request("DISCONNECT")
452         if hapd:
453             hapd.request("DISABLE")
454         if hapd2:
455             hapd2.request("DISABLE")
456         subprocess.call(['iw', 'reg', 'set', '00'])
457         dev[0].flush_scan_cache()
458         dev[1].flush_scan_cache()
459
460 def test_ap_vht80_csa(dev, apdev):
461     """VHT with 80 MHz channel width and CSA"""
462     csa_supported(dev[0])
463     try:
464         hapd = None
465         params = { "ssid": "vht",
466                    "country_code": "US",
467                    "hw_mode": "a",
468                    "channel": "149",
469                    "ht_capab": "[HT40+]",
470                    "ieee80211n": "1",
471                    "ieee80211ac": "1",
472                    "vht_oper_chwidth": "1",
473                    "vht_oper_centr_freq_seg0_idx": "155" }
474         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
475
476         dev[0].connect("vht", key_mgmt="NONE", scan_freq="5745")
477         hwsim_utils.test_connectivity(dev[0], hapd)
478
479         hapd.request("CHAN_SWITCH 5 5180 ht vht blocktx center_freq1=5210 sec_channel_offset=1 bandwidth=80")
480         ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
481         if ev is None:
482             raise Exception("CSA finished event timed out")
483         if "freq=5180" not in ev:
484             raise Exception("Unexpected channel in CSA finished event")
485         time.sleep(0.5)
486         hwsim_utils.test_connectivity(dev[0], hapd)
487
488         hapd.request("CHAN_SWITCH 5 5745")
489         ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
490         if ev is None:
491             raise Exception("CSA finished event timed out")
492         if "freq=5745" not in ev:
493             raise Exception("Unexpected channel in CSA finished event")
494         time.sleep(0.5)
495         hwsim_utils.test_connectivity(dev[0], hapd)
496
497         # This CSA to same channel will fail in kernel, so use this only for
498         # extra code coverage.
499         hapd.request("CHAN_SWITCH 5 5745")
500         hapd.wait_event(["AP-CSA-FINISHED"], timeout=1)
501     except Exception, e:
502         if isinstance(e, Exception) and str(e) == "AP startup failed":
503             if not vht_supported():
504                 raise HwsimSkip("80 MHz channel not supported in regulatory information")
505         raise
506     finally:
507         dev[0].request("DISCONNECT")
508         if hapd:
509             hapd.request("DISABLE")
510         subprocess.call(['iw', 'reg', 'set', '00'])
511         dev[0].flush_scan_cache()
512
513 def test_ap_vht_on_24ghz(dev, apdev):
514     """Subset of VHT features on 2.4 GHz"""
515     hapd = None
516     params = { "ssid": "test-vht-2g",
517                "hw_mode": "g",
518                "channel": "1",
519                "ieee80211n": "1",
520                "vendor_vht": "1",
521                "vht_capab": "[MAX-MPDU-11454]",
522                "vht_oper_chwidth": "0",
523                "vht_oper_centr_freq_seg0_idx": "1"
524     }
525     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
526     try:
527         if "OK" not in dev[0].request("VENDOR_ELEM_ADD 13 dd1300904c0400bf0c3240820feaff0000eaff0000"):
528             raise Exception("Failed to add vendor element")
529         dev[0].connect("test-vht-2g", scan_freq="2412", key_mgmt="NONE")
530         hwsim_utils.test_connectivity(dev[0], hapd)
531         sta = hapd.get_sta(dev[0].own_addr())
532         if '[VENDOR_VHT]' not in sta['flags']:
533             raise Exception("No VENDOR_VHT STA flag")
534
535         dev[1].connect("test-vht-2g", scan_freq="2412", key_mgmt="NONE")
536         sta = hapd.get_sta(dev[1].own_addr())
537         if '[VENDOR_VHT]' in sta['flags']:
538             raise Exception("Unexpected VENDOR_VHT STA flag")
539     finally:
540         dev[0].request("VENDOR_ELEM_REMOVE 13 *")
541
542 def test_prefer_vht40(dev, apdev):
543     """Preference on VHT40 over HT40"""
544     try:
545         hapd2 = None
546
547         params = { "ssid": "test",
548                    "country_code": "FI",
549                    "hw_mode": "a",
550                    "channel": "36",
551                    "ieee80211n": "1",
552                    "ht_capab": "[HT40+]" }
553         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
554         bssid = apdev[0]['bssid']
555
556         params = { "ssid": "test",
557                    "country_code": "FI",
558                    "hw_mode": "a",
559                    "channel": "36",
560                    "ieee80211n": "1",
561                    "ieee80211ac": "1",
562                    "ht_capab": "[HT40+]",
563                    "vht_capab": "",
564                    "vht_oper_chwidth": "0",
565                    "vht_oper_centr_freq_seg0_idx": "0",
566                  }
567         hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
568         bssid2 = apdev[1]['bssid']
569
570         dev[0].scan_for_bss(bssid, freq=5180)
571         dev[0].scan_for_bss(bssid2, freq=5180)
572         dev[0].connect("test", scan_freq="5180", key_mgmt="NONE")
573         if dev[0].get_status_field('bssid') != bssid2:
574             raise Exception("Unexpected BSS selected")
575
576         est = dev[0].get_bss(bssid)['est_throughput']
577         if est != "135000":
578             raise Exception("Unexpected BSS0 est_throughput: " + est)
579
580         est = dev[0].get_bss(bssid2)['est_throughput']
581         if est != "135001":
582             raise Exception("Unexpected BSS1 est_throughput: " + est)
583     finally:
584         dev[0].request("DISCONNECT")
585         if hapd2:
586             hapd2.request("DISABLE")
587         subprocess.call(['iw', 'reg', 'set', '00'])
588         dev[0].flush_scan_cache()
589
590 def test_ap_vht80_pwr_constraint(dev, apdev):
591     """VHT with 80 MHz channel width and local power constraint"""
592     hapd = None
593     try:
594         params = { "ssid": "vht",
595                    "country_code": "FI",
596                    "hw_mode": "a",
597                    "channel": "36",
598                    "ht_capab": "[HT40+]",
599                    "ieee80211d": "1",
600                    "local_pwr_constraint": "3",
601                    "ieee80211n": "1",
602                    "ieee80211ac": "1",
603                    "vht_oper_chwidth": "1",
604                    "vht_oper_centr_freq_seg0_idx": "42" }
605         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
606
607         dev[0].connect("vht", key_mgmt="NONE", scan_freq="5180")
608     except Exception, e:
609         if isinstance(e, Exception) and str(e) == "AP startup failed":
610             if not vht_supported():
611                 raise HwsimSkip("80 MHz channel not supported in regulatory information")
612         raise
613     finally:
614         dev[0].request("DISCONNECT")
615         if hapd:
616             hapd.request("DISABLE")
617         subprocess.call(['iw', 'reg', 'set', '00'])
618         dev[0].flush_scan_cache()