]> git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_he.py
tests: sigma_dut controlled STA and beacon protection
[thirdparty/hostap.git] / tests / hwsim / test_he.py
1 # HE tests
2 # Copyright (c) 2019, The Linux Foundation
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 import logging
8 logger = logging.getLogger()
9 import os
10 import subprocess, time
11
12 import hwsim_utils
13 import hostapd
14 from wpasupplicant import WpaSupplicant
15 from utils import *
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 test_he_open(dev, apdev):
21 """HE AP with open mode configuration"""
22 params = {"ssid": "he",
23 "ieee80211ax": "1",
24 "he_bss_color": "42",
25 "he_mu_edca_ac_be_ecwmin": "7",
26 "he_mu_edca_ac_be_ecwmax": "15"}
27 hapd = hostapd.add_ap(apdev[0], params)
28 if hapd.get_status_field("ieee80211ax") != "1":
29 raise Exception("STATUS did not indicate ieee80211ac=1")
30 dev[0].connect("he", key_mgmt="NONE", scan_freq="2412")
31
32 def test_he_params(dev, apdev):
33 """HE AP parameters"""
34 params = {"ssid": "he",
35 "ieee80211ax": "1",
36 "he_bss_color": "42",
37 "he_mu_edca_ac_be_ecwmin": "7",
38 "he_mu_edca_ac_be_ecwmax": "15",
39 "he_su_beamformer": "0",
40 "he_su_beamformee": "0",
41 "he_default_pe_duration": "4",
42 "he_twt_required": "1",
43 "he_rts_threshold": "64",
44 "he_basic_mcs_nss_set": "65535",
45 "he_mu_edca_qos_info_param_count": "0",
46 "he_mu_edca_qos_info_q_ack": "0",
47 "he_mu_edca_qos_info_queue_request": "1",
48 "he_mu_edca_qos_info_txop_request": "0",
49 "he_mu_edca_ac_be_aifsn": "0",
50 "he_mu_edca_ac_be_ecwmin": "15",
51 "he_mu_edca_ac_be_ecwmax": "15",
52 "he_mu_edca_ac_be_timer": "255",
53 "he_mu_edca_ac_bk_aifsn": "0",
54 "he_mu_edca_ac_bk_aci": "1",
55 "he_mu_edca_ac_bk_ecwmin": "15",
56 "he_mu_edca_ac_bk_ecwmax": "15",
57 "he_mu_edca_ac_bk_timer": "255",
58 "he_mu_edca_ac_vi_ecwmin": "15",
59 "he_mu_edca_ac_vi_ecwmax": "15",
60 "he_mu_edca_ac_vi_aifsn": "0",
61 "he_mu_edca_ac_vi_aci": "2",
62 "he_mu_edca_ac_vi_timer": "255",
63 "he_mu_edca_ac_vo_aifsn": "0",
64 "he_mu_edca_ac_vo_aci": "3",
65 "he_mu_edca_ac_vo_ecwmin": "15",
66 "he_mu_edca_ac_vo_ecwmax": "15",
67 "he_mu_edca_ac_vo_timer": "255",
68 "he_spr_sr_control": "0",
69 "he_spr_non_srg_obss_pd_max_offset": "0",
70 "he_spr_srg_obss_pd_min_offset": "0",
71 "he_spr_srg_obss_pd_max_offset": "0",
72 "he_oper_chwidth": "0",
73 "he_oper_centr_freq_seg0_idx": "1",
74 "he_oper_centr_freq_seg1_idx": "0"}
75 hapd = hostapd.add_ap(apdev[0], params)
76 if hapd.get_status_field("ieee80211ax") != "1":
77 raise Exception("STATUS did not indicate ieee80211ac=1")
78 dev[0].connect("he", key_mgmt="NONE", scan_freq="2412")
79
80 def he_supported():
81 cmd = subprocess.Popen(["iw", "reg", "get"], stdout=subprocess.PIPE)
82 reg = cmd.stdout.read().decode()
83 if "@ 80)" in reg or "@ 160)" in reg:
84 return True
85 return False
86
87 def test_he80(dev, apdev):
88 """HE with 80 MHz channel width"""
89 try:
90 hapd = None
91 params = {"ssid": "he",
92 "country_code": "FI",
93 "hw_mode": "a",
94 "channel": "36",
95 "ht_capab": "[HT40+]",
96 "ieee80211n": "1",
97 "ieee80211ac": "1",
98 "ieee80211ax": "1",
99 "vht_oper_chwidth": "1",
100 "vht_capab": "[MAX-MPDU-11454]",
101 "vht_oper_centr_freq_seg0_idx": "42",
102 "he_oper_chwidth": "1",
103 "he_oper_centr_freq_seg0_idx": "42"}
104 hapd = hostapd.add_ap(apdev[0], params)
105 bssid = apdev[0]['bssid']
106
107 dev[0].connect("he", key_mgmt="NONE", scan_freq="5180")
108 hwsim_utils.test_connectivity(dev[0], hapd)
109 sig = dev[0].request("SIGNAL_POLL").splitlines()
110 if "FREQUENCY=5180" not in sig:
111 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
112 if "WIDTH=80 MHz" not in sig:
113 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
114 est = dev[0].get_bss(bssid)['est_throughput']
115 if est != "390001":
116 raise Exception("Unexpected BSS est_throughput: " + est)
117 status = dev[0].get_status()
118 if status["ieee80211ac"] != "1":
119 raise Exception("Unexpected STATUS ieee80211ac value (STA)")
120 status = hapd.get_status()
121 logger.info("hostapd STATUS: " + str(status))
122 if status["ieee80211n"] != "1":
123 raise Exception("Unexpected STATUS ieee80211n value")
124 if status["ieee80211ac"] != "1":
125 raise Exception("Unexpected STATUS ieee80211ac value")
126 if status["ieee80211ax"] != "1":
127 raise Exception("Unexpected STATUS ieee80211ax value")
128 if status["secondary_channel"] != "1":
129 raise Exception("Unexpected STATUS secondary_channel value")
130 if status["vht_oper_chwidth"] != "1":
131 raise Exception("Unexpected STATUS vht_oper_chwidth value")
132 if status["vht_oper_centr_freq_seg0_idx"] != "42":
133 raise Exception("Unexpected STATUS vht_oper_centr_freq_seg0_idx value")
134 if "vht_caps_info" not in status:
135 raise Exception("Missing vht_caps_info")
136 if status["he_oper_chwidth"] != "1":
137 raise Exception("Unexpected STATUS he_oper_chwidth value")
138 if status["he_oper_centr_freq_seg0_idx"] != "42":
139 raise Exception("Unexpected STATUS he_oper_centr_freq_seg0_idx value")
140
141 sta = hapd.get_sta(dev[0].own_addr())
142 logger.info("hostapd STA: " + str(sta))
143 if "[HT]" not in sta['flags']:
144 raise Exception("Missing STA flag: HT")
145 if "[VHT]" not in sta['flags']:
146 raise Exception("Missing STA flag: VHT")
147 if "[HE]" not in sta['flags']:
148 raise Exception("Missing STA flag: HE")
149
150 except Exception as e:
151 if isinstance(e, Exception) and str(e) == "AP startup failed":
152 if not he_supported():
153 raise HwsimSkip("80 MHz channel not supported in regulatory information")
154 raise
155 finally:
156 dev[0].request("DISCONNECT")
157 clear_regdom(hapd, dev)
158
159 def test_he_wifi_generation(dev, apdev):
160 """HE and wifi_generation"""
161 try:
162 hapd = None
163 params = {"ssid": "he",
164 "country_code": "FI",
165 "hw_mode": "a",
166 "channel": "36",
167 "ht_capab": "[HT40+]",
168 "ieee80211n": "1",
169 "ieee80211ac": "1",
170 "ieee80211ax": "1",
171 "vht_oper_chwidth": "1",
172 "vht_capab": "[MAX-MPDU-11454]",
173 "vht_oper_centr_freq_seg0_idx": "42",
174 "he_oper_chwidth": "1",
175 "he_oper_centr_freq_seg0_idx": "42"}
176 hapd = hostapd.add_ap(apdev[0], params)
177 bssid = apdev[0]['bssid']
178
179 dev[0].connect("he", key_mgmt="NONE", scan_freq="5180")
180 status = dev[0].get_status()
181 if 'wifi_generation' not in status:
182 # For now, assume this is because of missing kernel support
183 raise HwsimSkip("Association Request IE reporting not supported")
184 #raise Exception("Missing wifi_generation information")
185 if status['wifi_generation'] != "6":
186 raise Exception("Unexpected wifi_generation value: " + status['wifi_generation'])
187
188 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
189 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
190 wpas.connect("he", key_mgmt="NONE", scan_freq="5180")
191 status = wpas.get_status()
192 if 'wifi_generation' not in status:
193 # For now, assume this is because of missing kernel support
194 raise HwsimSkip("Association Request IE reporting not supported")
195 #raise Exception("Missing wifi_generation information (connect)")
196 if status['wifi_generation'] != "6":
197 raise Exception("Unexpected wifi_generation value (connect): " + status['wifi_generation'])
198 except Exception as e:
199 if isinstance(e, Exception) and str(e) == "AP startup failed":
200 if not he_supported():
201 raise HwsimSkip("80 MHz channel not supported in regulatory information")
202 raise
203 finally:
204 dev[0].request("DISCONNECT")
205 clear_regdom(hapd, dev)
206
207 def he80_test(apdev, dev, channel, ht_capab):
208 clear_scan_cache(apdev)
209 try:
210 hapd = None
211 params = {"ssid": "he",
212 "country_code": "FI",
213 "hw_mode": "a",
214 "channel": str(channel),
215 "ht_capab": ht_capab,
216 "ieee80211n": "1",
217 "ieee80211ac": "1",
218 "ieee80211ax": "1",
219 "vht_oper_chwidth": "1",
220 "vht_oper_centr_freq_seg0_idx": "42",
221 "he_oper_chwidth": "1",
222 "he_oper_centr_freq_seg0_idx": "42"}
223 hapd = hostapd.add_ap(apdev, params)
224 bssid = apdev['bssid']
225
226 dev[0].connect("he", key_mgmt="NONE",
227 scan_freq=str(5000 + 5 * channel))
228 hwsim_utils.test_connectivity(dev[0], hapd)
229 except Exception as e:
230 if isinstance(e, Exception) and str(e) == "AP startup failed":
231 if not he_supported():
232 raise HwsimSkip("80 MHz channel not supported in regulatory information")
233 raise
234 finally:
235 clear_regdom(hapd, dev)
236
237 def test_he80b(dev, apdev):
238 """HE with 80 MHz channel width (HT40- channel 40)"""
239 he80_test(apdev[0], dev, 40, "[HT40-]")
240
241 def test_he80c(dev, apdev):
242 """HE with 80 MHz channel width (HT40+ channel 44)"""
243 he80_test(apdev[0], dev, 44, "[HT40+]")
244
245 def test_he80d(dev, apdev):
246 """HE with 80 MHz channel width (HT40- channel 48)"""
247 he80_test(apdev[0], dev, 48, "[HT40-]")
248
249 def test_he80_params(dev, apdev):
250 """HE with 80 MHz channel width and number of optional features enabled"""
251 try:
252 hapd = None
253 params = {"ssid": "he",
254 "country_code": "FI",
255 "hw_mode": "a",
256 "channel": "36",
257 "ht_capab": "[HT40+][SHORT-GI-40][DSS_CCK-40]",
258 "ieee80211n": "1",
259 "ieee80211ac": "1",
260 "ieee80211ax": "1",
261 "vht_oper_chwidth": "1",
262 "vht_capab": "[MAX-MPDU-11454][RXLDPC][SHORT-GI-80][TX-STBC-2BY1][RX-STBC-1][MAX-A-MPDU-LEN-EXP0]",
263 "vht_oper_centr_freq_seg0_idx": "42",
264 "require_vht": "1",
265 "he_oper_chwidth": "1",
266 "he_oper_centr_freq_seg0_idx": "42",
267 "he_su_beamformer": "1",
268 "he_mu_beamformer": "1",
269 "he_bss_color":"1",
270 "he_default_pe_duration":"1",
271 "he_twt_required":"1",
272 "he_rts_threshold":"1"}
273 hapd = hostapd.add_ap(apdev[0], params)
274
275 dev[1].connect("he", key_mgmt="NONE", scan_freq="5180",
276 disable_vht="1", wait_connect=False)
277 dev[0].connect("he", key_mgmt="NONE", scan_freq="5180")
278 dev[2].connect("he", key_mgmt="NONE", scan_freq="5180",
279 disable_sgi="1")
280 ev = dev[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
281 if ev is None:
282 raise Exception("Association rejection timed out")
283 if "status_code=104" not in ev:
284 raise Exception("Unexpected rejection status code")
285 dev[1].request("DISCONNECT")
286 hwsim_utils.test_connectivity(dev[0], hapd)
287 sta0 = hapd.get_sta(dev[0].own_addr())
288 sta2 = hapd.get_sta(dev[2].own_addr())
289 capab0 = int(sta0['vht_caps_info'], base=16)
290 capab2 = int(sta2['vht_caps_info'], base=16)
291 if capab0 & 0x60 == 0:
292 raise Exception("dev[0] did not support SGI")
293 if capab2 & 0x60 != 0:
294 raise Exception("dev[2] claimed support for SGI")
295 except Exception as e:
296 if isinstance(e, Exception) and str(e) == "AP startup failed":
297 if not he_supported():
298 raise HwsimSkip("80 MHz channel not supported in regulatory information")
299 raise
300 finally:
301 clear_regdom(hapd, dev, count=3)
302
303 def test_he80_invalid(dev, apdev):
304 """HE with invalid 80 MHz channel configuration (seg1)"""
305 try:
306 hapd = None
307 params = {"ssid": "he",
308 "country_code": "US",
309 "hw_mode": "a",
310 "channel": "36",
311 "ht_capab": "[HT40+]",
312 "ieee80211n": "1",
313 "ieee80211ac": "1",
314 "ieee80211ax": "1",
315 "vht_oper_chwidth": "1",
316 "vht_oper_centr_freq_seg0_idx": "42",
317 "vht_oper_centr_freq_seg1_idx": "159",
318 "he_oper_chwidth": "1",
319 "he_oper_centr_freq_seg0_idx": "42",
320 "he_oper_centr_freq_seg1_idx": "155",
321 'ieee80211d': '1',
322 'ieee80211h': '1'}
323 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
324 # This fails due to unexpected seg1 configuration
325 ev = hapd.wait_event(["AP-DISABLED"], timeout=5)
326 if ev is None:
327 raise Exception("AP-DISABLED not reported")
328 except Exception as e:
329 if isinstance(e, Exception) and str(e) == "AP startup failed":
330 if not he_supported():
331 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
332 raise
333 finally:
334 clear_regdom(hapd, dev)
335
336 def test_he80_invalid2(dev, apdev):
337 """HE with invalid 80 MHz channel configuration (seg0)"""
338 try:
339 hapd = None
340 params = {"ssid": "he",
341 "country_code": "US",
342 "hw_mode": "a",
343 "channel": "36",
344 "ht_capab": "[HT40+]",
345 "ieee80211n": "1",
346 "ieee80211ac": "1",
347 "ieee80211ax": "1",
348 "vht_oper_chwidth": "1",
349 "vht_oper_centr_freq_seg0_idx": "42",
350 "he_oper_chwidth": "1",
351 "he_oper_centr_freq_seg0_idx": "46",
352 'ieee80211d': '1',
353 'ieee80211h': '1'}
354 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
355 # This fails due to invalid seg0 configuration
356 ev = hapd.wait_event(["AP-DISABLED"], timeout=5)
357 if ev is None:
358 raise Exception("AP-DISABLED not reported")
359 except Exception as e:
360 if isinstance(e, Exception) and str(e) == "AP startup failed":
361 if not he_supported():
362 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
363 raise
364 finally:
365 clear_regdom(hapd, dev)
366
367 def test_he_20(devs, apdevs):
368 """HE and 20 MHz channel"""
369 dev = devs[0]
370 ap = apdevs[0]
371 try:
372 hapd = None
373 params = {"ssid": "test-he20",
374 "country_code": "DE",
375 "hw_mode": "a",
376 "channel": "36",
377 "ieee80211n": "1",
378 "ieee80211ac": "1",
379 "ieee80211ax": "1",
380 "ht_capab": "",
381 "vht_capab": "",
382 "vht_oper_chwidth": "0",
383 "vht_oper_centr_freq_seg0_idx": "0",
384 "supported_rates": "60 120 240 360 480 540",
385 "require_vht": "1",
386 "he_oper_chwidth": "0",
387 "he_oper_centr_freq_seg0_idx": "0"}
388 hapd = hostapd.add_ap(ap, params)
389 dev.connect("test-he20", scan_freq="5180", key_mgmt="NONE")
390 hwsim_utils.test_connectivity(dev, hapd)
391 finally:
392 dev.request("DISCONNECT")
393 clear_regdom(hapd, devs)
394
395 def test_he_40(devs, apdevs):
396 """HE and 40 MHz channel"""
397 dev = devs[0]
398 ap = apdevs[0]
399 try:
400 hapd = None
401 params = {"ssid": "test-he40",
402 "country_code": "DE",
403 "hw_mode": "a",
404 "channel": "36",
405 "ieee80211n": "1",
406 "ieee80211ac": "1",
407 "ieee80211ax": "1",
408 "ht_capab": "[HT40+]",
409 "vht_capab": "",
410 "vht_oper_chwidth": "0",
411 "vht_oper_centr_freq_seg0_idx": "38",
412 "he_oper_chwidth": "0",
413 "he_oper_centr_freq_seg0_idx": "38",
414 "he_su_beamformer": "1",
415 "he_mu_beamformer": "1"}
416 hapd = hostapd.add_ap(ap, params)
417 dev.connect("test-he40", scan_freq="5180", key_mgmt="NONE")
418 hwsim_utils.test_connectivity(dev, hapd)
419 finally:
420 dev.request("DISCONNECT")
421 clear_regdom(hapd, devs)
422
423 def test_he160(dev, apdev, params):
424 """HE with 160 MHz channel width (1) [long]"""
425 if not params['long']:
426 raise HwsimSkip("Skip test case with long duration due to --long not specified")
427 try:
428 hapd = None
429 params = {"ssid": "he",
430 "country_code": "FI",
431 "hw_mode": "a",
432 "channel": "36",
433 "ht_capab": "[HT40+]",
434 "ieee80211n": "1",
435 "ieee80211ac": "1",
436 "ieee80211ax": "1",
437 "vht_oper_chwidth": "2",
438 "vht_oper_centr_freq_seg0_idx": "50",
439 "he_oper_chwidth": "2",
440 "he_oper_centr_freq_seg0_idx": "50",
441 'ieee80211d': '1',
442 'ieee80211h': '1'}
443 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
444
445 ev = wait_dfs_event(hapd, "DFS-CAC-START", 5)
446 if "DFS-CAC-START" not in ev:
447 raise Exception("Unexpected DFS event")
448
449 state = hapd.get_status_field("state")
450 if state != "DFS":
451 if state == "DISABLED" and not os.path.exists("dfs"):
452 # Not all systems have recent enough CRDA version and
453 # wireless-regdb changes to support 160 MHz and DFS. For now,
454 # do not report failures for this test case.
455 raise HwsimSkip("CRDA or wireless-regdb did not support 160 MHz")
456 raise Exception("Unexpected interface state: " + state)
457
458 logger.info("Waiting for CAC to complete")
459
460 ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
461 if "success=1" not in ev:
462 raise Exception("CAC failed")
463 if "freq=5180" not in ev:
464 raise Exception("Unexpected DFS freq result")
465
466 ev = hapd.wait_event(["AP-ENABLED"], timeout=5)
467 if not ev:
468 raise Exception("AP setup timed out")
469
470 state = hapd.get_status_field("state")
471 if state != "ENABLED":
472 raise Exception("Unexpected interface state")
473
474 dev[0].connect("he", key_mgmt="NONE", scan_freq="5180")
475 dev[0].wait_regdom(country_ie=True)
476 hwsim_utils.test_connectivity(dev[0], hapd)
477 sig = dev[0].request("SIGNAL_POLL").splitlines()
478 if "FREQUENCY=5180" not in sig:
479 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
480 if "WIDTH=160 MHz" not in sig:
481 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
482 except Exception as e:
483 if isinstance(e, Exception) and str(e) == "AP startup failed":
484 if not he_supported():
485 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
486 raise
487 finally:
488 if hapd:
489 hapd.request("DISABLE")
490 dev[0].disconnect_and_stop_scan()
491 subprocess.call(['iw', 'reg', 'set', '00'])
492 dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5)
493 dev[0].flush_scan_cache()
494
495 def test_he160b(dev, apdev, params):
496 """HE with 160 MHz channel width (2) [long]"""
497 if not params['long']:
498 raise HwsimSkip("Skip test case with long duration due to --long not specified")
499 try:
500 hapd = None
501
502 params = {"ssid": "he",
503 "country_code": "FI",
504 "hw_mode": "a",
505 "channel": "104",
506 "ht_capab": "[HT40-]",
507 "ieee80211n": "1",
508 "ieee80211ac": "1",
509 "ieee80211ax": "1",
510 "vht_oper_chwidth": "2",
511 "vht_oper_centr_freq_seg0_idx": "114",
512 "he_oper_chwidth": "2",
513 "he_oper_centr_freq_seg0_idx": "114",
514 'ieee80211d': '1',
515 'ieee80211h': '1'}
516 hapd = hostapd.add_ap(apdev[1], params, wait_enabled=False)
517
518 ev = wait_dfs_event(hapd, "DFS-CAC-START", 5)
519 if "DFS-CAC-START" not in ev:
520 raise Exception("Unexpected DFS event(2)")
521
522 state = hapd.get_status_field("state")
523 if state != "DFS":
524 if state == "DISABLED" and not os.path.exists("dfs"):
525 # Not all systems have recent enough CRDA version and
526 # wireless-regdb changes to support 160 MHz and DFS. For now,
527 # do not report failures for this test case.
528 raise HwsimSkip("CRDA or wireless-regdb did not support 160 MHz")
529 raise Exception("Unexpected interface state: " + state)
530
531 logger.info("Waiting for CAC to complete")
532
533 ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
534 if "success=1" not in ev:
535 raise Exception("CAC failed(2)")
536 if "freq=5520" not in ev:
537 raise Exception("Unexpected DFS freq result(2)")
538
539 ev = hapd.wait_event(["AP-ENABLED"], timeout=5)
540 if not ev:
541 raise Exception("AP setup timed out(2)")
542
543 state = hapd.get_status_field("state")
544 if state != "ENABLED":
545 raise Exception("Unexpected interface state(2)")
546
547 freq = hapd.get_status_field("freq")
548 if freq != "5520":
549 raise Exception("Unexpected frequency(2)")
550
551 dev[0].connect("he", key_mgmt="NONE", scan_freq="5520")
552 dev[0].wait_regdom(country_ie=True)
553 hwsim_utils.test_connectivity(dev[0], hapd)
554 sig = dev[0].request("SIGNAL_POLL").splitlines()
555 if "FREQUENCY=5520" not in sig:
556 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
557 if "WIDTH=160 MHz" not in sig:
558 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
559 except Exception as e:
560 if isinstance(e, Exception) and str(e) == "AP startup failed":
561 if not he_supported():
562 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
563 raise
564 finally:
565 if hapd:
566 hapd.request("DISABLE")
567 dev[0].disconnect_and_stop_scan()
568 subprocess.call(['iw', 'reg', 'set', '00'])
569 dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5)
570 dev[0].flush_scan_cache()
571
572 def test_he160_no_dfs_100_plus(dev, apdev):
573 """HE with 160 MHz channel width and no DFS (100 plus)"""
574 run_ap_he160_no_dfs(dev, apdev, "100", "[HT40+]")
575
576 def test_he160_no_dfs(dev, apdev):
577 """HE with 160 MHz channel width and no DFS (104 minus)"""
578 run_ap_he160_no_dfs(dev, apdev, "104", "[HT40-]")
579
580 def test_he160_no_dfs_108_plus(dev, apdev):
581 """HE with 160 MHz channel width and no DFS (108 plus)"""
582 run_ap_he160_no_dfs(dev, apdev, "108", "[HT40+]")
583
584 def test_he160_no_dfs_112_minus(dev, apdev):
585 """HE with 160 MHz channel width and no DFS (112 minus)"""
586 run_ap_he160_no_dfs(dev, apdev, "112", "[HT40-]")
587
588 def test_he160_no_dfs_116_plus(dev, apdev):
589 """HE with 160 MHz channel width and no DFS (116 plus)"""
590 run_ap_he160_no_dfs(dev, apdev, "116", "[HT40+]")
591
592 def test_he160_no_dfs_120_minus(dev, apdev):
593 """HE with 160 MHz channel width and no DFS (120 minus)"""
594 run_ap_he160_no_dfs(dev, apdev, "120", "[HT40-]")
595
596 def test_he160_no_dfs_124_plus(dev, apdev):
597 """HE with 160 MHz channel width and no DFS (124 plus)"""
598 run_ap_he160_no_dfs(dev, apdev, "124", "[HT40+]")
599
600 def test_he160_no_dfs_128_minus(dev, apdev):
601 """HE with 160 MHz channel width and no DFS (128 minus)"""
602 run_ap_he160_no_dfs(dev, apdev, "128", "[HT40-]")
603
604 def run_ap_he160_no_dfs(dev, apdev, channel, ht_capab):
605 try:
606 hapd = None
607 params = {"ssid": "he",
608 "country_code": "ZA",
609 "hw_mode": "a",
610 "channel": channel,
611 "ht_capab": ht_capab,
612 "ieee80211n": "1",
613 "ieee80211ac": "1",
614 "ieee80211ax": "1",
615 "vht_oper_chwidth": "2",
616 "vht_oper_centr_freq_seg0_idx": "114",
617 "he_oper_chwidth": "2",
618 "he_oper_centr_freq_seg0_idx": "114",
619 'ieee80211d': '1',
620 'ieee80211h': '1'}
621 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
622 ev = hapd.wait_event(["AP-ENABLED"], timeout=2)
623 if not ev:
624 cmd = subprocess.Popen(["iw", "reg", "get"], stdout=subprocess.PIPE)
625 reg = cmd.stdout.readlines()
626 for r in reg:
627 if "5490" in r and "DFS" in r:
628 raise HwsimSkip("ZA regulatory rule did not have DFS requirement removed")
629 raise Exception("AP setup timed out")
630
631 freq = str(int(channel) * 5 + 5000)
632 dev[0].connect("he", key_mgmt="NONE", scan_freq=freq)
633 dev[0].wait_regdom(country_ie=True)
634 hwsim_utils.test_connectivity(dev[0], hapd)
635 sig = dev[0].request("SIGNAL_POLL").splitlines()
636 if "FREQUENCY=" + freq not in sig:
637 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
638 if "WIDTH=160 MHz" not in sig:
639 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
640 except Exception as e:
641 if isinstance(e, Exception) and str(e) == "AP startup failed":
642 if not he_supported():
643 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
644 raise
645 finally:
646 clear_regdom(hapd, dev)
647
648 def test_he160_no_ht40(dev, apdev):
649 """HE with 160 MHz channel width and HT40 disabled"""
650 try:
651 hapd = None
652 params = {"ssid": "he",
653 "country_code": "ZA",
654 "hw_mode": "a",
655 "channel": "108",
656 "ht_capab": "",
657 "ieee80211n": "1",
658 "ieee80211ac": "1",
659 "ieee80211ax": "1",
660 "vht_oper_chwidth": "2",
661 "vht_oper_centr_freq_seg0_idx": "114",
662 "he_oper_chwidth": "2",
663 "he_oper_centr_freq_seg0_idx": "114",
664 'ieee80211d': '1',
665 'ieee80211h': '1'}
666 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
667 ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=2)
668 if not ev:
669 cmd = subprocess.Popen(["iw", "reg", "get"], stdout=subprocess.PIPE)
670 reg = cmd.stdout.readlines()
671 for r in reg:
672 if "5490" in r and "DFS" in r:
673 raise HwsimSkip("ZA regulatory rule did not have DFS requirement removed")
674 raise Exception("AP setup timed out")
675 if "AP-ENABLED" in ev:
676 # This was supposed to fail due to sec_channel_offset == 0
677 raise Exception("Unexpected AP-ENABLED")
678 except Exception as e:
679 if isinstance(e, Exception) and str(e) == "AP startup failed":
680 if not he_supported():
681 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
682 raise
683 finally:
684 clear_regdom(hapd, dev)
685
686 def test_he80plus80(dev, apdev):
687 """HE with 80+80 MHz channel width"""
688 try:
689 hapd = None
690 hapd2 = None
691 params = {"ssid": "he",
692 "country_code": "US",
693 "hw_mode": "a",
694 "channel": "52",
695 "ht_capab": "[HT40+]",
696 "ieee80211n": "1",
697 "ieee80211ac": "1",
698 "ieee80211ax": "1",
699 "vht_oper_chwidth": "3",
700 "vht_oper_centr_freq_seg0_idx": "58",
701 "vht_oper_centr_freq_seg1_idx": "155",
702 "he_oper_chwidth": "3",
703 "he_oper_centr_freq_seg0_idx": "58",
704 "he_oper_centr_freq_seg1_idx": "155",
705 'ieee80211d': '1',
706 'ieee80211h': '1'}
707 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
708 # This will actually fail since DFS on 80+80 is not yet supported
709 ev = hapd.wait_event(["AP-DISABLED"], timeout=5)
710 # ignore result to avoid breaking the test once 80+80 DFS gets enabled
711
712 params = {"ssid": "he2",
713 "country_code": "US",
714 "hw_mode": "a",
715 "channel": "36",
716 "ht_capab": "[HT40+]",
717 "ieee80211n": "1",
718 "ieee80211ac": "1",
719 "ieee80211ax": "1",
720 "vht_oper_chwidth": "3",
721 "vht_oper_centr_freq_seg0_idx": "42",
722 "vht_oper_centr_freq_seg1_idx": "155",
723 "he_oper_chwidth": "3",
724 "he_oper_centr_freq_seg0_idx": "42",
725 "he_oper_centr_freq_seg1_idx": "155"}
726 hapd2 = hostapd.add_ap(apdev[1], params, wait_enabled=False)
727
728 ev = hapd2.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=5)
729 if not ev:
730 raise Exception("AP setup timed out(2)")
731 if "AP-DISABLED" in ev:
732 # Assume this failed due to missing regulatory update for now
733 raise HwsimSkip("80+80 MHz channel not supported in regulatory information")
734
735 state = hapd2.get_status_field("state")
736 if state != "ENABLED":
737 raise Exception("Unexpected interface state(2)")
738
739 dev[1].connect("he2", key_mgmt="NONE", scan_freq="5180")
740 hwsim_utils.test_connectivity(dev[1], hapd2)
741 sig = dev[1].request("SIGNAL_POLL").splitlines()
742 if "FREQUENCY=5180" not in sig:
743 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
744 if "WIDTH=80+80 MHz" not in sig:
745 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
746 if "CENTER_FRQ1=5210" not in sig:
747 raise Exception("Unexpected SIGNAL_POLL value(3): " + str(sig))
748 if "CENTER_FRQ2=5775" not in sig:
749 raise Exception("Unexpected SIGNAL_POLL value(4): " + str(sig))
750 except Exception as e:
751 if isinstance(e, Exception) and str(e) == "AP startup failed":
752 if not he_supported():
753 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
754 raise
755 finally:
756 dev[0].request("DISCONNECT")
757 dev[1].request("DISCONNECT")
758 if hapd:
759 hapd.request("DISABLE")
760 if hapd2:
761 hapd2.request("DISABLE")
762 subprocess.call(['iw', 'reg', 'set', '00'])
763 dev[0].flush_scan_cache()
764 dev[1].flush_scan_cache()
765
766 def test_he80plus80_invalid(dev, apdev):
767 """HE with invalid 80+80 MHz channel"""
768 try:
769 hapd = None
770 params = {"ssid": "he",
771 "country_code": "US",
772 "hw_mode": "a",
773 "channel": "36",
774 "ht_capab": "[HT40+]",
775 "ieee80211n": "1",
776 "ieee80211ac": "1",
777 "ieee80211ax": "1",
778 "vht_oper_chwidth": "3",
779 "vht_oper_centr_freq_seg0_idx": "42",
780 "vht_oper_centr_freq_seg1_idx": "0",
781 "he_oper_chwidth": "3",
782 "he_oper_centr_freq_seg0_idx": "42",
783 "he_oper_centr_freq_seg1_idx": "0",
784 'ieee80211d': '1',
785 'ieee80211h': '1'}
786 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
787 # This fails due to missing(invalid) seg1 configuration
788 ev = hapd.wait_event(["AP-DISABLED"], timeout=5)
789 if ev is None:
790 raise Exception("AP-DISABLED not reported")
791 except Exception as e:
792 if isinstance(e, Exception) and str(e) == "AP startup failed":
793 if not he_supported():
794 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
795 raise
796 finally:
797 clear_regdom(hapd, dev)
798
799 def test_he80_csa(dev, apdev):
800 """HE with 80 MHz channel width and CSA"""
801 csa_supported(dev[0])
802 try:
803 hapd = None
804 params = {"ssid": "he",
805 "country_code": "US",
806 "hw_mode": "a",
807 "channel": "149",
808 "ht_capab": "[HT40+]",
809 "ieee80211n": "1",
810 "ieee80211ac": "1",
811 "ieee80211ax": "1",
812 "vht_oper_chwidth": "1",
813 "vht_oper_centr_freq_seg0_idx": "155",
814 "he_oper_chwidth": "1",
815 "he_oper_centr_freq_seg0_idx": "155"}
816 hapd = hostapd.add_ap(apdev[0], params)
817
818 dev[0].connect("he", key_mgmt="NONE", scan_freq="5745")
819 hwsim_utils.test_connectivity(dev[0], hapd)
820
821 hapd.request("CHAN_SWITCH 5 5180 ht vht he blocktx center_freq1=5210 sec_channel_offset=1 bandwidth=80")
822 ev = hapd.wait_event(["CTRL-EVENT-STARTED-CHANNEL-SWITCH"], timeout=10)
823 if ev is None:
824 raise Exception("Channel switch start event not seen")
825 if "freq=5180" not in ev:
826 raise Exception("Unexpected channel in CS started")
827 ev = hapd.wait_event(["CTRL-EVENT-CHANNEL-SWITCH"], timeout=10)
828 if ev is None:
829 raise Exception("Channel switch completion event not seen")
830 if "freq=5180" not in ev:
831 raise Exception("Unexpected channel in CS completed")
832 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
833 if ev is None:
834 raise Exception("CSA finished event timed out")
835 if "freq=5180" not in ev:
836 raise Exception("Unexpected channel in CSA finished event")
837 time.sleep(0.5)
838 hwsim_utils.test_connectivity(dev[0], hapd)
839
840 hapd.request("CHAN_SWITCH 5 5745")
841 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
842 if ev is None:
843 raise Exception("CSA finished event timed out")
844 if "freq=5745" not in ev:
845 raise Exception("Unexpected channel in CSA finished event")
846 time.sleep(0.5)
847 hwsim_utils.test_connectivity(dev[0], hapd)
848
849 # This CSA to same channel will fail in kernel, so use this only for
850 # extra code coverage.
851 hapd.request("CHAN_SWITCH 5 5745")
852 hapd.wait_event(["AP-CSA-FINISHED"], timeout=1)
853 except Exception as e:
854 if isinstance(e, Exception) and str(e) == "AP startup failed":
855 if not he_supported():
856 raise HwsimSkip("80 MHz channel not supported in regulatory information")
857 raise
858 finally:
859 dev[0].request("DISCONNECT")
860 clear_regdom(hapd, dev)
861
862 def test_he_on_24ghz(dev, apdev):
863 """Subset of HE features on 2.4 GHz"""
864 hapd = None
865 params = {"ssid": "test-he-2g",
866 "hw_mode": "g",
867 "channel": "1",
868 "ieee80211n": "1",
869 "ieee80211ax": "1",
870 "vht_oper_chwidth": "0",
871 "vht_oper_centr_freq_seg0_idx": "1",
872 "he_oper_chwidth": "0",
873 "he_oper_centr_freq_seg0_idx": "1"}
874 hapd = hostapd.add_ap(apdev[0], params)
875 try:
876 dev[0].connect("test-he-2g", scan_freq="2412", key_mgmt="NONE")
877 hwsim_utils.test_connectivity(dev[0], hapd)
878 sta = hapd.get_sta(dev[0].own_addr())
879
880 dev[1].connect("test-he-2g", scan_freq="2412", key_mgmt="NONE")
881 sta = hapd.get_sta(dev[1].own_addr())
882
883 finally:
884 dev[0].request("DISCONNECT")
885 dev[1].request("DISCONNECT")
886 if hapd:
887 hapd.request("DISABLE")
888 subprocess.call(['iw', 'reg', 'set', '00'])
889 dev[0].flush_scan_cache()
890 dev[1].flush_scan_cache()
891
892 def test_he80_pwr_constraint(dev, apdev):
893 """HE with 80 MHz channel width and local power constraint"""
894 hapd = None
895 try:
896 params = {"ssid": "he",
897 "country_code": "FI",
898 "hw_mode": "a",
899 "channel": "36",
900 "ht_capab": "[HT40+]",
901 "ieee80211d": "1",
902 "local_pwr_constraint": "3",
903 "ieee80211n": "1",
904 "ieee80211ac": "1",
905 "ieee80211ax": "1",
906 "vht_oper_chwidth": "1",
907 "vht_oper_centr_freq_seg0_idx": "42",
908 "he_oper_chwidth": "1",
909 "he_oper_centr_freq_seg0_idx": "42"}
910 hapd = hostapd.add_ap(apdev[0], params)
911
912 dev[0].connect("he", key_mgmt="NONE", scan_freq="5180")
913 dev[0].wait_regdom(country_ie=True)
914 except Exception as e:
915 if isinstance(e, Exception) and str(e) == "AP startup failed":
916 if not he_supported():
917 raise HwsimSkip("80 MHz channel not supported in regulatory information")
918 raise
919 finally:
920 if hapd:
921 hapd.request("DISABLE")
922 dev[0].disconnect_and_stop_scan()
923 subprocess.call(['iw', 'reg', 'set', '00'])
924 dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5)
925 dev[0].flush_scan_cache()
926
927 def test_he_use_sta_nsts(dev, apdev):
928 """HE with 80 MHz channel width and use_sta_nsts=1"""
929 try:
930 hapd = None
931 params = {"ssid": "he",
932 "country_code": "FI",
933 "hw_mode": "a",
934 "channel": "36",
935 "ht_capab": "[HT40+]",
936 "ieee80211n": "1",
937 "ieee80211ac": "1",
938 "ieee80211ax": "1",
939 "vht_oper_chwidth": "1",
940 "vht_oper_centr_freq_seg0_idx": "42",
941 "he_oper_chwidth": "1",
942 "he_oper_centr_freq_seg0_idx": "42",
943 "use_sta_nsts": "1"}
944 hapd = hostapd.add_ap(apdev[0], params)
945 bssid = apdev[0]['bssid']
946
947 dev[0].connect("he", key_mgmt="NONE", scan_freq="5180")
948 hwsim_utils.test_connectivity(dev[0], hapd)
949 except Exception as e:
950 if isinstance(e, Exception) and str(e) == "AP startup failed":
951 if not he_supported():
952 raise HwsimSkip("80 MHz channel not supported in regulatory information")
953 raise
954 finally:
955 clear_regdom(hapd, dev)
956
957 def test_he_tkip(dev, apdev):
958 """HE and TKIP"""
959 try:
960 hapd = None
961 params = {"ssid": "he",
962 "wpa": "1",
963 "wpa_key_mgmt": "WPA-PSK",
964 "wpa_pairwise": "TKIP",
965 "wpa_passphrase": "12345678",
966 "country_code": "FI",
967 "hw_mode": "a",
968 "channel": "36",
969 "ht_capab": "[HT40+]",
970 "ieee80211n": "1",
971 "ieee80211ac": "1",
972 "ieee80211ax": "1",
973 "vht_oper_chwidth": "1",
974 "vht_oper_centr_freq_seg0_idx": "42",
975 "he_oper_chwidth": "1",
976 "he_oper_centr_freq_seg0_idx": "42"}
977 hapd = hostapd.add_ap(apdev[0], params)
978 bssid = apdev[0]['bssid']
979
980 dev[0].connect("he", psk="12345678", scan_freq="5180")
981 hwsim_utils.test_connectivity(dev[0], hapd)
982 sig = dev[0].request("SIGNAL_POLL").splitlines()
983 if "FREQUENCY=5180" not in sig:
984 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
985 if "WIDTH=20 MHz (no HT)" not in sig:
986 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
987 status = hapd.get_status()
988 logger.info("hostapd STATUS: " + str(status))
989 if status["ieee80211n"] != "0":
990 raise Exception("Unexpected STATUS ieee80211n value")
991 if status["ieee80211ac"] != "0":
992 raise Exception("Unexpected STATUS ieee80211ac value")
993 if status["ieee80211ax"] != "1":
994 raise Exception("Unexpected STATUS ieee80211ax value")
995 if status["secondary_channel"] != "0":
996 raise Exception("Unexpected STATUS secondary_channel value")
997 except Exception as e:
998 if isinstance(e, Exception) and str(e) == "AP startup failed":
999 if not he_supported():
1000 raise HwsimSkip("80 MHz channel not supported in regulatory information")
1001 raise
1002 finally:
1003 dev[0].request("DISCONNECT")
1004 clear_regdom(hapd, dev)
1005
1006 def test_he_40_fallback_to_20(devs, apdevs):
1007 """HE and 40 MHz channel configuration falling back to 20 MHz"""
1008 dev = devs[0]
1009 ap = apdevs[0]
1010 try:
1011 hapd = None
1012 params = {"ssid": "test-he40",
1013 "country_code": "US",
1014 "hw_mode": "a",
1015 "basic_rates": "60 120 240",
1016 "channel": "161",
1017 "ieee80211d": "1",
1018 "ieee80211h": "1",
1019 "ieee80211n": "1",
1020 "ieee80211ac": "1",
1021 "ieee80211ax": "1",
1022 "ht_capab": "[HT40+][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40]",
1023 "vht_capab": "[RXLDPC][SHORT-GI-80][TX-STBC-2BY1][RX-STBC1][MAX-MPDU-11454][MAX-A-MPDU-LEN-EXP7]",
1024 "vht_oper_chwidth": "0",
1025 "vht_oper_centr_freq_seg0_idx": "155",
1026 "he_oper_chwidth": "0",
1027 "he_oper_centr_freq_seg0_idx": "155"}
1028 hapd = hostapd.add_ap(ap, params)
1029 dev.connect("test-he40", scan_freq="5805", key_mgmt="NONE")
1030 dev.wait_regdom(country_ie=True)
1031 hwsim_utils.test_connectivity(dev, hapd)
1032 finally:
1033 clear_regdom(hapd, devs)
1034
1035 def test_he80_to_24g_he(dev, apdev):
1036 """HE with 80 MHz channel width reconfigured to 2.4 GHz HE"""
1037 try:
1038 hapd = None
1039 params = {"ssid": "he",
1040 "country_code": "FI",
1041 "hw_mode": "a",
1042 "channel": "36",
1043 "ht_capab": "[HT40+]",
1044 "ieee80211n": "1",
1045 "ieee80211ac": "1",
1046 "ieee80211ax": "1",
1047 "vht_oper_chwidth": "1",
1048 "vht_capab": "[MAX-MPDU-11454]",
1049 "vht_oper_centr_freq_seg0_idx": "42",
1050 "he_oper_chwidth": "1",
1051 "he_oper_centr_freq_seg0_idx": "42"}
1052 hapd = hostapd.add_ap(apdev[0], params)
1053 bssid = apdev[0]['bssid']
1054
1055 hapd.disable()
1056 hapd.set("ieee80211ac", "0")
1057 hapd.set("hw_mode", "g")
1058 hapd.set("channel", "1")
1059 hapd.set("ht_capab", "")
1060 hapd.set("vht_capab", "")
1061 hapd.set("he_oper_chwidth", "")
1062 hapd.set("he_oper_centr_freq_seg0_idx", "")
1063 hapd.set("vht_oper_chwidth", "")
1064 hapd.set("vht_oper_centr_freq_seg0_idx", "")
1065 hapd.enable()
1066
1067 dev[0].connect("he", key_mgmt="NONE", scan_freq="2412")
1068 except Exception as e:
1069 if isinstance(e, Exception) and str(e) == "AP startup failed":
1070 if not he_supported():
1071 raise HwsimSkip("80 MHz channel not supported in regulatory information")
1072 raise
1073 finally:
1074 dev[0].request("DISCONNECT")
1075 clear_regdom(hapd, dev)