1# Test various AP mode parameters 2# Copyright (c) 2014, Qualcomm Atheros, Inc. 3# 4# This software may be distributed under the terms of the BSD license. 5# See README for more details. 6 7from remotehost import remote_compatible 8import logging 9logger = logging.getLogger() 10import os 11import struct 12import subprocess 13import time 14 15import hwsim_utils 16import hostapd 17from tshark import run_tshark 18from utils import * 19 20@remote_compatible 21def test_ap_fragmentation_rts_set_high(dev, apdev): 22 """WPA2-PSK AP with fragmentation and RTS thresholds larger than frame length""" 23 ssid = "test-wpa2-psk" 24 passphrase = 'qwertyuiop' 25 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) 26 params['rts_threshold'] = "1000" 27 params['fragm_threshold'] = "2000" 28 hapd = hostapd.add_ap(apdev[0], params) 29 dev[0].connect(ssid, psk=passphrase, scan_freq="2412") 30 hwsim_utils.test_connectivity(dev[0], hapd) 31 dev[0].request("DISCONNECT") 32 hapd.disable() 33 hapd.set('fragm_threshold', '-1') 34 hapd.set('rts_threshold', '-1') 35 hapd.enable() 36 37@remote_compatible 38def test_ap_fragmentation_open(dev, apdev): 39 """Open AP with fragmentation threshold""" 40 ssid = "fragmentation" 41 params = {} 42 params['ssid'] = ssid 43 params['fragm_threshold'] = "1000" 44 hapd = hostapd.add_ap(apdev[0], params) 45 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") 46 hwsim_utils.test_connectivity(dev[0], hapd) 47 dev[0].request("DISCONNECT") 48 hapd.disable() 49 hapd.set('fragm_threshold', '-1') 50 hapd.enable() 51 52@remote_compatible 53def test_ap_fragmentation_wpa2(dev, apdev): 54 """WPA2-PSK AP with fragmentation threshold""" 55 ssid = "test-wpa2-psk" 56 passphrase = 'qwertyuiop' 57 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) 58 params['fragm_threshold'] = "1000" 59 hapd = hostapd.add_ap(apdev[0], params) 60 dev[0].connect(ssid, psk=passphrase, scan_freq="2412") 61 hwsim_utils.test_connectivity(dev[0], hapd) 62 dev[0].request("DISCONNECT") 63 hapd.disable() 64 hapd.set('fragm_threshold', '-1') 65 hapd.enable() 66 67def test_ap_vendor_elements(dev, apdev): 68 """WPA2-PSK AP with vendor elements added""" 69 bssid = apdev[0]['bssid'] 70 ssid = "test-wpa2-psk" 71 passphrase = 'qwertyuiop' 72 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) 73 params['vendor_elements'] = "dd0411223301" 74 params['assocresp_elements'] = "dd0411223302" 75 hapd = hostapd.add_ap(apdev[0], params) 76 dev[0].connect(ssid, psk=passphrase, scan_freq="2412") 77 bss = dev[0].get_bss(bssid) 78 if "dd0411223301" not in bss['ie']: 79 raise Exception("Vendor element not shown in scan results") 80 81 hapd.set('vendor_elements', 'dd051122330203dd0400137400dd04001374ff') 82 if "OK" not in hapd.request("UPDATE_BEACON"): 83 raise Exception("UPDATE_BEACON failed") 84 dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412") 85 bss = dev[1].get_bss(bssid) 86 if "dd0411223301" in bss['ie']: 87 raise Exception("Old vendor element still in scan results") 88 if "dd051122330203" not in bss['ie']: 89 raise Exception("New vendor element not shown in scan results") 90 91def test_ap_element_parse(dev, apdev): 92 """Information element parsing - extra coverage""" 93 bssid = apdev[0]['bssid'] 94 ssid = "test-wpa2-psk" 95 params = {'ssid': ssid, 96 'vendor_elements': "380501020304059e009e009e009e009e009e00"} 97 hapd = hostapd.add_ap(apdev[0], params) 98 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412") 99 bss = dev[0].get_bss(bssid) 100 if "38050102030405" not in bss['ie']: 101 raise Exception("Timeout element not shown in scan results") 102 103@remote_compatible 104def test_ap_element_parse_oom(dev, apdev): 105 """Information element parsing OOM""" 106 bssid = apdev[0]['bssid'] 107 ssid = "test-wpa2-psk" 108 params = {'ssid': ssid, 109 'vendor_elements': "dd0d506f9a0a00000600411c440028"} 110 hapd = hostapd.add_ap(apdev[0], params) 111 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412") 112 with alloc_fail(dev[0], 1, "wpabuf_alloc;ieee802_11_vendor_ie_concat"): 113 bss = dev[0].get_bss(bssid) 114 logger.info(str(bss)) 115 116def test_ap_country(dev, apdev): 117 """WPA2-PSK AP setting country code and using 5 GHz band""" 118 try: 119 hapd = None 120 bssid = apdev[0]['bssid'] 121 ssid = "test-wpa2-psk" 122 passphrase = 'qwertyuiop' 123 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) 124 params['country_code'] = 'FI' 125 params['ieee80211d'] = '1' 126 params['hw_mode'] = 'a' 127 params['channel'] = '36' 128 hapd = hostapd.add_ap(apdev[0], params) 129 dev[0].connect(ssid, psk=passphrase, scan_freq="5180") 130 hwsim_utils.test_connectivity(dev[0], hapd) 131 status = hapd.get_status() 132 if "country_code" not in status or "country3" not in status: 133 raise Exception("Country information not available in STATUS") 134 if status["country_code"] != "FI" or status["country3"] != "0x20": 135 raise Exception("Unexpected country information: %s %s" % (status["country_code"], status["country3"])) 136 finally: 137 if hapd: 138 hapd.request("DISABLE") 139 dev[0].disconnect_and_stop_scan() 140 hostapd.cmd_execute(apdev[0], ['iw', 'reg', 'set', '00']) 141 dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5) 142 dev[0].flush_scan_cache() 143 144def test_ap_acl_accept(dev, apdev): 145 """MAC ACL accept list""" 146 ssid = "acl" 147 params = {} 148 filename = hostapd.acl_file(dev, apdev, 'hostapd.macaddr') 149 hostapd.send_file(apdev[0], filename, filename) 150 params['ssid'] = ssid 151 params['accept_mac_file'] = filename 152 hapd = hostapd.add_ap(apdev[0], params) 153 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412") 154 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") 155 dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412") 156 dev[1].connect(ssid, key_mgmt="NONE", scan_freq="2412") 157 dev[0].request("REMOVE_NETWORK all") 158 dev[1].request("REMOVE_NETWORK all") 159 hapd.request("SET macaddr_acl 1") 160 dev[1].dump_monitor() 161 dev[1].connect(ssid, key_mgmt="NONE", scan_freq="2412", wait_connect=False) 162 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") 163 ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1) 164 if ev is not None: 165 raise Exception("Unexpected association") 166 if filename.startswith('/tmp/'): 167 os.unlink(filename) 168 169def test_ap_acl_deny(dev, apdev): 170 """MAC ACL deny list""" 171 ssid = "acl" 172 params = {} 173 filename = hostapd.acl_file(dev, apdev, 'hostapd.macaddr') 174 hostapd.send_file(apdev[0], filename, filename) 175 params['ssid'] = ssid 176 params['deny_mac_file'] = filename 177 hapd = hostapd.add_ap(apdev[0], params) 178 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", passive=True) 179 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412", wait_connect=False) 180 dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412") 181 dev[1].connect(ssid, key_mgmt="NONE", scan_freq="2412") 182 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1) 183 if ev is not None: 184 raise Exception("Unexpected association") 185 if filename.startswith('/tmp/'): 186 os.unlink(filename) 187 188def test_ap_acl_mgmt(dev, apdev): 189 """MAC ACL accept/deny management""" 190 ssid = "acl" 191 params = {} 192 filename = hostapd.acl_file(dev, apdev, 'hostapd.macaddr') 193 hostapd.send_file(apdev[0], filename, filename) 194 params['ssid'] = ssid 195 params['deny_mac_file'] = filename 196 hapd = hostapd.add_ap(apdev[0], params) 197 198 accept = hapd.request("ACCEPT_ACL SHOW").splitlines() 199 logger.info("accept: " + str(accept)) 200 deny = hapd.request("DENY_ACL SHOW").splitlines() 201 logger.info("deny: " + str(deny)) 202 if len(accept) != 0: 203 raise Exception("Unexpected number of accept entries") 204 if len(deny) != 3: 205 raise Exception("Unexpected number of deny entries") 206 if "01:01:01:01:01:01 VLAN_ID=0" not in deny: 207 raise Exception("Missing deny entry") 208 209 if "OK" not in hapd.request("ACCEPT_ACL DEL_MAC 22:33:44:55:66:77"): 210 raise Exception("DEL_MAC with empty list failed") 211 if "FAIL" not in hapd.request("ACCEPT_ACL ADD_MAC 22:33:44:55:66"): 212 raise Exception("ADD_MAC with invalid MAC address accepted") 213 hapd.request("ACCEPT_ACL ADD_MAC 22:33:44:55:66:77") 214 if "FAIL" not in hapd.request("ACCEPT_ACL DEL_MAC 22:33:44:55:66"): 215 raise Exception("DEL_MAC with invalid MAC address accepted") 216 hapd.request("DENY_ACL ADD_MAC 22:33:44:55:66:88 VLAN_ID=2") 217 218 accept = hapd.request("ACCEPT_ACL SHOW").splitlines() 219 logger.info("accept: " + str(accept)) 220 deny = hapd.request("DENY_ACL SHOW").splitlines() 221 logger.info("deny: " + str(deny)) 222 if len(accept) != 1: 223 raise Exception("Unexpected number of accept entries (2)") 224 if len(deny) != 4: 225 raise Exception("Unexpected number of deny entries (2)") 226 if "01:01:01:01:01:01 VLAN_ID=0" not in deny: 227 raise Exception("Missing deny entry (2)") 228 if "22:33:44:55:66:88 VLAN_ID=2" not in deny: 229 raise Exception("Missing deny entry (2)") 230 if "22:33:44:55:66:77 VLAN_ID=0" not in accept: 231 raise Exception("Missing accept entry (2)") 232 233 hapd.request("ACCEPT_ACL DEL_MAC 22:33:44:55:66:77") 234 hapd.request("DENY_ACL DEL_MAC 22:33:44:55:66:88") 235 236 accept = hapd.request("ACCEPT_ACL SHOW").splitlines() 237 logger.info("accept: " + str(accept)) 238 deny = hapd.request("DENY_ACL SHOW").splitlines() 239 logger.info("deny: " + str(deny)) 240 if len(accept) != 0: 241 raise Exception("Unexpected number of accept entries (3)") 242 if len(deny) != 3: 243 raise Exception("Unexpected number of deny entries (3)") 244 if "01:01:01:01:01:01 VLAN_ID=0" not in deny: 245 raise Exception("Missing deny entry (3)") 246 247 hapd.request("ACCEPT_ACL CLEAR") 248 hapd.request("DENY_ACL CLEAR") 249 250 accept = hapd.request("ACCEPT_ACL SHOW").splitlines() 251 logger.info("accept: " + str(accept)) 252 deny = hapd.request("DENY_ACL SHOW").splitlines() 253 logger.info("deny: " + str(deny)) 254 if len(accept) != 0: 255 raise Exception("Unexpected number of accept entries (4)") 256 if len(deny) != 0: 257 raise Exception("Unexpected number of deny entries (4)") 258 259 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412") 260 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") 261 dev[0].dump_monitor() 262 hapd.request("DENY_ACL ADD_MAC " + dev[0].own_addr()) 263 dev[0].wait_disconnected() 264 dev[0].request("DISCONNECT") 265 if filename.startswith('/tmp/'): 266 os.unlink(filename) 267 268def test_ap_acl_accept_changes(dev, apdev): 269 """MAC ACL accept list changes""" 270 ssid = "acl" 271 params = {} 272 params['ssid'] = ssid 273 params['macaddr_acl'] = "1" 274 hapd = hostapd.add_ap(apdev[0], params) 275 hapd.request("ACCEPT_ACL ADD_MAC " + dev[0].own_addr()) 276 hapd.request("ACCEPT_ACL ADD_MAC " + dev[1].own_addr()) 277 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412") 278 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") 279 dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412") 280 dev[1].connect(ssid, key_mgmt="NONE", scan_freq="2412") 281 hapd.request("ACCEPT_ACL DEL_MAC " + dev[0].own_addr()) 282 dev[0].wait_disconnected() 283 dev[0].request("DISCONNECT") 284 ev = dev[1].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.1) 285 if ev is not None: 286 raise Exception("Unexpected disconnection") 287 hapd.request("ACCEPT_ACL CLEAR") 288 dev[1].wait_disconnected() 289 dev[1].request("DISCONNECT") 290 291@remote_compatible 292def test_ap_wds_sta(dev, apdev): 293 """WPA2-PSK AP with STA using 4addr mode""" 294 ssid = "test-wpa2-psk" 295 passphrase = 'qwertyuiop' 296 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) 297 params['wds_sta'] = "1" 298 params['wds_bridge'] = "wds-br0" 299 hapd = hostapd.add_ap(apdev[0], params) 300 301 try: 302 dev[0].cmd_execute(['brctl', 'addbr', 'wds-br0']) 303 dev[0].cmd_execute(['brctl', 'setfd', 'wds-br0', '0']) 304 dev[0].cmd_execute(['ip', 'link', 'set', 'dev', 'wds-br0', 'up']) 305 dev[0].cmd_execute(['iw', dev[0].ifname, 'set', '4addr', 'on']) 306 dev[0].connect(ssid, psk=passphrase, scan_freq="2412") 307 ev = hapd.wait_event(["WDS-STA-INTERFACE-ADDED"], timeout=10) 308 if ev is None: 309 raise Exception("No WDS-STA-INTERFACE-ADDED event seen") 310 if "sta_addr=" + dev[0].own_addr() not in ev: 311 raise Exception("No sta_addr match in " + ev) 312 if "ifname=" + hapd.ifname + ".sta" not in ev: 313 raise Exception("No ifname match in " + ev) 314 sta = hapd.get_sta(dev[0].own_addr()) 315 if "wds_sta_ifname" not in sta: 316 raise Exception("Missing wds_sta_ifname in STA data") 317 if "ifname=" + sta['wds_sta_ifname'] not in ev: 318 raise Exception("wds_sta_ifname %s not in event: %s" % 319 (sta['wds_sta_ifname'], ev)) 320 hwsim_utils.test_connectivity_iface(dev[0], hapd, "wds-br0", 321 max_tries=15) 322 dev[0].request("REATTACH") 323 dev[0].wait_connected() 324 hwsim_utils.test_connectivity_iface(dev[0], hapd, "wds-br0", 325 max_tries=15) 326 dev[0].request("SET reassoc_same_bss_optim 1") 327 dev[0].request("REATTACH") 328 dev[0].wait_connected() 329 hwsim_utils.test_connectivity_iface(dev[0], hapd, "wds-br0", 330 max_tries=5, timeout=1) 331 finally: 332 dev[0].request("SET reassoc_same_bss_optim 0") 333 dev[0].cmd_execute(['iw', dev[0].ifname, 'set', '4addr', 'off']) 334 dev[0].cmd_execute(['ip', 'link', 'set', 'dev', 'wds-br0', 'down']) 335 dev[0].cmd_execute(['brctl', 'delbr', 'wds-br0']) 336 337def test_ap_wds_sta_eap(dev, apdev): 338 """WPA2-EAP AP with STA using 4addr mode""" 339 ssid = "test-wpa2-eap" 340 params = hostapd.wpa2_eap_params(ssid=ssid) 341 params['wds_sta'] = "1" 342 params['wds_bridge'] = "wds-br0" 343 hapd = hostapd.add_ap(apdev[0], params) 344 345 try: 346 dev[0].cmd_execute(['brctl', 'addbr', 'wds-br0']) 347 dev[0].cmd_execute(['brctl', 'setfd', 'wds-br0', '0']) 348 dev[0].cmd_execute(['ip', 'link', 'set', 'dev', 'wds-br0', 'up']) 349 dev[0].cmd_execute(['iw', dev[0].ifname, 'set', '4addr', 'on']) 350 dev[0].connect(ssid, key_mgmt="WPA-EAP", eap="GPSK", 351 identity="gpsk user", 352 password="abcdefghijklmnop0123456789abcdef", 353 scan_freq="2412") 354 ev = hapd.wait_event(["WDS-STA-INTERFACE-ADDED"], timeout=10) 355 if ev is None: 356 raise Exception("No WDS-STA-INTERFACE-ADDED event seen") 357 if "sta_addr=" + dev[0].own_addr() not in ev: 358 raise Exception("No sta_addr match in " + ev) 359 if "ifname=" + hapd.ifname + ".sta" not in ev: 360 raise Exception("No ifname match in " + ev) 361 sta = hapd.get_sta(dev[0].own_addr()) 362 if "wds_sta_ifname" not in sta: 363 raise Exception("Missing wds_sta_ifname in STA data") 364 if "ifname=" + sta['wds_sta_ifname'] not in ev: 365 raise Exception("wds_sta_ifname %s not in event: %s" % 366 (sta['wds_sta_ifname'], ev)) 367 hwsim_utils.test_connectivity_iface(dev[0], hapd, "wds-br0", 368 max_tries=15) 369 finally: 370 dev[0].cmd_execute(['iw', dev[0].ifname, 'set', '4addr', 'off']) 371 dev[0].cmd_execute(['ip', 'link', 'set', 'dev', 'wds-br0', 'down']) 372 dev[0].cmd_execute(['brctl', 'delbr', 'wds-br0']) 373 374def test_ap_wds_sta_open(dev, apdev): 375 """Open AP with STA using 4addr mode""" 376 ssid = "test-wds-open" 377 params = {} 378 params['ssid'] = ssid 379 params['wds_sta'] = "1" 380 params['wds_bridge'] = "wds-br0" 381 hapd = hostapd.add_ap(apdev[0], params) 382 383 try: 384 dev[0].cmd_execute(['brctl', 'addbr', 'wds-br0']) 385 dev[0].cmd_execute(['brctl', 'setfd', 'wds-br0', '0']) 386 dev[0].cmd_execute(['ip', 'link', 'set', 'dev', 'wds-br0', 'up']) 387 dev[0].cmd_execute(['iw', dev[0].ifname, 'set', '4addr', 'on']) 388 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") 389 hwsim_utils.test_connectivity_iface(dev[0], hapd, "wds-br0", 390 max_tries=15) 391 dev[0].request("REATTACH") 392 dev[0].wait_connected() 393 hwsim_utils.test_connectivity_iface(dev[0], hapd, "wds-br0", 394 max_tries=15) 395 dev[0].request("SET reassoc_same_bss_optim 1") 396 dev[0].request("REATTACH") 397 dev[0].wait_connected() 398 hwsim_utils.test_connectivity_iface(dev[0], hapd, "wds-br0", 399 max_tries=5, timeout=1) 400 finally: 401 dev[0].request("SET reassoc_same_bss_optim 0") 402 dev[0].cmd_execute(['iw', dev[0].ifname, 'set', '4addr', 'off']) 403 dev[0].cmd_execute(['ip', 'link', 'set', 'dev', 'wds-br0', 'down']) 404 dev[0].cmd_execute(['brctl', 'delbr', 'wds-br0']) 405 406def test_ap_wds_sta_wep(dev, apdev): 407 """WEP AP with STA using 4addr mode""" 408 check_wep_capa(dev[0]) 409 ssid = "test-wds-wep" 410 params = {} 411 params['ssid'] = ssid 412 params["ieee80211n"] = "0" 413 params['wep_key0'] = '"hello"' 414 params['wds_sta'] = "1" 415 params['wds_bridge'] = "wds-br0" 416 hapd = hostapd.add_ap(apdev[0], params) 417 418 try: 419 dev[0].cmd_execute(['brctl', 'addbr', 'wds-br0']) 420 dev[0].cmd_execute(['brctl', 'setfd', 'wds-br0', '0']) 421 dev[0].cmd_execute(['ip', 'link', 'set', 'dev', 'wds-br0', 'up']) 422 dev[0].cmd_execute(['iw', dev[0].ifname, 'set', '4addr', 'on']) 423 dev[0].connect(ssid, key_mgmt="NONE", wep_key0='"hello"', 424 scan_freq="2412") 425 hwsim_utils.test_connectivity_iface(dev[0], hapd, "wds-br0", 426 max_tries=15) 427 dev[0].request("REATTACH") 428 dev[0].wait_connected() 429 hwsim_utils.test_connectivity_iface(dev[0], hapd, "wds-br0", 430 max_tries=15) 431 dev[0].request("SET reassoc_same_bss_optim 1") 432 dev[0].request("REATTACH") 433 dev[0].wait_connected() 434 hwsim_utils.test_connectivity_iface(dev[0], hapd, "wds-br0", 435 max_tries=5, timeout=1) 436 finally: 437 dev[0].request("SET reassoc_same_bss_optim 0") 438 dev[0].cmd_execute(['iw', dev[0].ifname, 'set', '4addr', 'off']) 439 dev[0].cmd_execute(['ip', 'link', 'set', 'dev', 'wds-br0', 'down']) 440 dev[0].cmd_execute(['brctl', 'delbr', 'wds-br0']) 441 442@remote_compatible 443def test_ap_inactivity_poll(dev, apdev): 444 """AP using inactivity poll""" 445 ssid = "test-wpa2-psk" 446 passphrase = 'qwertyuiop' 447 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) 448 params['ap_max_inactivity'] = "1" 449 hapd = hostapd.add_ap(apdev[0], params) 450 dev[0].connect(ssid, psk=passphrase, scan_freq="2412") 451 hapd.set("ext_mgmt_frame_handling", "1") 452 dev[0].request("DISCONNECT") 453 ev = hapd.wait_event(["MGMT-RX"], timeout=5) 454 if ev is None: 455 raise Exception("MGMT RX wait timed out for Deauth") 456 hapd.set("ext_mgmt_frame_handling", "0") 457 ev = hapd.wait_event(["AP-STA-DISCONNECTED"], timeout=30) 458 if ev is None: 459 raise Exception("STA disconnection on inactivity was not reported") 460 461@remote_compatible 462def test_ap_inactivity_disconnect(dev, apdev): 463 """AP using inactivity disconnect""" 464 ssid = "test-wpa2-psk" 465 passphrase = 'qwertyuiop' 466 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) 467 params['ap_max_inactivity'] = "1" 468 params['skip_inactivity_poll'] = "1" 469 hapd = hostapd.add_ap(apdev[0], params) 470 dev[0].connect(ssid, psk=passphrase, scan_freq="2412") 471 hapd.set("ext_mgmt_frame_handling", "1") 472 dev[0].request("DISCONNECT") 473 ev = hapd.wait_event(["MGMT-RX"], timeout=5) 474 if ev is None: 475 raise Exception("MGMT RX wait timed out for Deauth") 476 hapd.set("ext_mgmt_frame_handling", "0") 477 ev = hapd.wait_event(["AP-STA-DISCONNECTED"], timeout=30) 478 if ev is None: 479 raise Exception("STA disconnection on inactivity was not reported") 480 481@remote_compatible 482def test_ap_basic_rates(dev, apdev): 483 """Open AP with lots of basic rates""" 484 ssid = "basic rates" 485 params = {} 486 params['ssid'] = ssid 487 params['basic_rates'] = "10 20 55 110 60 90 120 180 240 360 480 540" 488 hostapd.add_ap(apdev[0], params) 489 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") 490 491@remote_compatible 492def test_ap_short_preamble(dev, apdev): 493 """Open AP with short preamble""" 494 ssid = "short preamble" 495 params = {} 496 params['ssid'] = ssid 497 params['preamble'] = "1" 498 hostapd.add_ap(apdev[0], params) 499 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") 500 501def test_ap_spectrum_management_required(dev, apdev): 502 """Open AP with spectrum management required""" 503 ssid = "spectrum mgmt" 504 params = {} 505 params['ssid'] = ssid 506 params["country_code"] = "JP" 507 params["hw_mode"] = "a" 508 params["channel"] = "36" 509 params["ieee80211d"] = "1" 510 params["local_pwr_constraint"] = "3" 511 params['spectrum_mgmt_required'] = "1" 512 try: 513 hapd = None 514 hapd = hostapd.add_ap(apdev[0], params) 515 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="5180") 516 dev[0].wait_regdom(country_ie=True) 517 finally: 518 if hapd: 519 hapd.request("DISABLE") 520 dev[0].disconnect_and_stop_scan() 521 hostapd.cmd_execute(apdev[0], ['iw', 'reg', 'set', '00']) 522 dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5) 523 dev[0].flush_scan_cache() 524 525@remote_compatible 526def test_ap_max_listen_interval(dev, apdev): 527 """Open AP with maximum listen interval limit""" 528 ssid = "listen" 529 params = {} 530 params['ssid'] = ssid 531 params['max_listen_interval'] = "1" 532 hostapd.add_ap(apdev[0], params) 533 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412", wait_connect=False) 534 ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"]) 535 if ev is None: 536 raise Exception("Association rejection not reported") 537 if "status_code=51" not in ev: 538 raise Exception("Unexpected ASSOC-REJECT reason") 539 540@remote_compatible 541def test_ap_max_num_sta(dev, apdev): 542 """Open AP with maximum STA count""" 543 ssid = "max" 544 params = {} 545 params['ssid'] = ssid 546 params['max_num_sta'] = "1" 547 hostapd.add_ap(apdev[0], params) 548 dev[1].connect(ssid, key_mgmt="NONE", scan_freq="2412") 549 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412", wait_connect=False) 550 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1) 551 if ev is not None: 552 raise Exception("Unexpected association") 553 554def test_ap_max_num_sta_no_probe_resp(dev, apdev, params): 555 """Maximum STA count and limit on Probe Response frames""" 556 logdir = params['logdir'] 557 dev[0].flush_scan_cache() 558 ssid = "max" 559 params = {} 560 params['ssid'] = ssid 561 params['beacon_int'] = "2000" 562 params['max_num_sta'] = "1" 563 params['no_probe_resp_if_max_sta'] = "1" 564 hostapd.add_ap(apdev[0], params) 565 dev[1].connect(ssid, key_mgmt="NONE", scan_freq="2412") 566 dev[0].scan(freq=2412, type="ONLY") 567 dev[0].scan(freq=2412, type="ONLY") 568 seen = dev[0].get_bss(apdev[0]['bssid']) != None 569 dev[1].scan(freq=2412, type="ONLY") 570 if seen: 571 out = run_tshark(os.path.join(logdir, "hwsim0.pcapng"), 572 "wlan.fc.type_subtype == 5", ["wlan.da"]) 573 if out: 574 if dev[0].own_addr() not in out: 575 # Discovery happened through Beacon frame reception. That's not 576 # an error case. 577 seen = False 578 if dev[1].own_addr() not in out: 579 raise Exception("No Probe Response frames to dev[1] seen") 580 if seen: 581 raise Exception("AP found unexpectedly") 582 583@remote_compatible 584def test_ap_tx_queue_params(dev, apdev): 585 """Open AP with TX queue params set""" 586 ssid = "tx" 587 params = {} 588 params['ssid'] = ssid 589 params['tx_queue_data2_aifs'] = "4" 590 params['tx_queue_data2_cwmin'] = "7" 591 params['tx_queue_data2_cwmax'] = "1023" 592 params['tx_queue_data2_burst'] = "4.2" 593 params['tx_queue_data1_aifs'] = "4" 594 params['tx_queue_data1_cwmin'] = "7" 595 params['tx_queue_data1_cwmax'] = "1023" 596 params['tx_queue_data1_burst'] = "2" 597 hapd = hostapd.add_ap(apdev[0], params) 598 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") 599 hwsim_utils.test_connectivity(dev[0], hapd) 600 601def test_ap_tx_queue_params_invalid(dev, apdev): 602 """Invalid TX queue params set (cwmin/cwmax)""" 603 ssid = "tx" 604 params = {} 605 params['ssid'] = ssid 606 params['tx_queue_data2_aifs'] = "4" 607 params['tx_queue_data2_cwmin'] = "7" 608 params['tx_queue_data2_cwmax'] = "1023" 609 params['tx_queue_data2_burst'] = "4.2" 610 params['wmm_ac_bk_cwmin'] = "4" 611 params['wmm_ac_bk_cwmax'] = "10" 612 params['wmm_ac_bk_aifs'] = "7" 613 params['wmm_ac_bk_txop_limit'] = "0" 614 params['wmm_ac_bk_acm'] = "0" 615 616 hapd = hostapd.add_ap(apdev[0], params) 617 618 # Valid WMM change 619 hapd.set("wmm_ac_be_cwmin", "3") 620 621 # "Invalid TX queue cwMin/cwMax values. cwMin(7) greater than cwMax(3)" 622 if "FAIL" not in hapd.request('SET tx_queue_data2_cwmax 3'): 623 raise Exception("TX cwMax < cwMin accepted") 624 # "Invalid WMM AC cwMin/cwMax values. cwMin(4) greater than cwMax(3)" 625 if "FAIL" not in hapd.request('SET wmm_ac_bk_cwmax 3'): 626 raise Exception("AC cwMax < cwMin accepted") 627 628 hapd.request("SET tx_queue_data2_cwmax 1023") 629 hapd.set("wmm_ac_bk_cwmax", "10") 630 # Invalid IEs to cause WMM parameter update failing 631 hapd.set("vendor_elements", "dd04112233") 632 hapd.set("wmm_ac_be_cwmin", "3") 633 # Valid IEs to cause WMM parameter update succeeding 634 hapd.set("vendor_elements", "dd0411223344") 635 hapd.set("wmm_ac_be_cwmin", "3") 636 637 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") 638 639def test_ap_beacon_rate_legacy(dev, apdev): 640 """Open AP with Beacon frame TX rate 5.5 Mbps""" 641 hapd = hostapd.add_ap(apdev[0], {'ssid': 'beacon-rate'}) 642 res = hapd.get_driver_status_field('capa.flags') 643 if (int(res, 0) & 0x0000080000000000) == 0: 644 raise HwsimSkip("Setting Beacon frame TX rate not supported") 645 hapd.disable() 646 hapd.set('beacon_rate', '55') 647 hapd.enable() 648 dev[0].connect('beacon-rate', key_mgmt="NONE", scan_freq="2412") 649 time.sleep(0.5) 650 651def test_ap_beacon_rate_legacy2(dev, apdev): 652 """Open AP with Beacon frame TX rate 12 Mbps in VHT BSS""" 653 run_ap_beacon_rate_legacy(dev, apdev, "120") 654 655def test_ap_beacon_rate_legacy3(dev, apdev): 656 """Open AP with Beacon frame TX rate 54 Mbps in VHT BSS""" 657 run_ap_beacon_rate_legacy(dev, apdev, "540") 658 659def run_ap_beacon_rate_legacy(dev, apdev, rate): 660 hapd = hostapd.add_ap(apdev[0], {'ssid': 'beacon-rate'}) 661 res = hapd.get_driver_status_field('capa.flags') 662 if (int(res, 0) & 0x0000080000000000) == 0: 663 raise HwsimSkip("Setting Beacon frame TX rate not supported") 664 hapd.disable() 665 hapd.set('beacon_rate', rate) 666 hapd.set("country_code", "DE") 667 hapd.set("hw_mode", "a") 668 hapd.set("channel", "36") 669 hapd.set("ieee80211n", "1") 670 hapd.set("ieee80211ac", "1") 671 hapd.set("ht_capab", "[HT40+]") 672 hapd.set("vht_capab", "") 673 hapd.set("vht_oper_chwidth", "0") 674 hapd.set("vht_oper_centr_freq_seg0_idx", "0") 675 try: 676 hapd.enable() 677 dev[0].scan_for_bss(hapd.own_addr(), freq="5180") 678 dev[0].connect('beacon-rate', key_mgmt="NONE", scan_freq="5180") 679 time.sleep(0.5) 680 finally: 681 dev[0].request("DISCONNECT") 682 hapd.request("DISABLE") 683 subprocess.call(['iw', 'reg', 'set', '00']) 684 dev[0].flush_scan_cache() 685 686def test_ap_beacon_rate_ht(dev, apdev): 687 """Open AP with Beacon frame TX rate HT-MCS 0""" 688 hapd = hostapd.add_ap(apdev[0], {'ssid': 'beacon-rate'}) 689 res = hapd.get_driver_status_field('capa.flags') 690 if (int(res, 0) & 0x0000100000000000) == 0: 691 raise HwsimSkip("Setting Beacon frame TX rate not supported") 692 hapd.disable() 693 hapd.set('beacon_rate', 'ht:0') 694 hapd.enable() 695 dev[0].connect('beacon-rate', key_mgmt="NONE", scan_freq="2412") 696 time.sleep(0.5) 697 698def test_ap_beacon_rate_ht2(dev, apdev): 699 """Open AP with Beacon frame TX rate HT-MCS 1 in VHT BSS""" 700 hapd = hostapd.add_ap(apdev[0], {'ssid': 'beacon-rate'}) 701 res = hapd.get_driver_status_field('capa.flags') 702 if (int(res, 0) & 0x0000100000000000) == 0: 703 raise HwsimSkip("Setting Beacon frame TX rate not supported") 704 hapd.disable() 705 hapd.set('beacon_rate', 'ht:1') 706 hapd.set("country_code", "DE") 707 hapd.set("hw_mode", "a") 708 hapd.set("channel", "36") 709 hapd.set("ieee80211n", "1") 710 hapd.set("ieee80211ac", "1") 711 hapd.set("ht_capab", "[HT40+]") 712 hapd.set("vht_capab", "") 713 hapd.set("vht_oper_chwidth", "0") 714 hapd.set("vht_oper_centr_freq_seg0_idx", "0") 715 try: 716 hapd.enable() 717 dev[0].scan_for_bss(hapd.own_addr(), freq="5180") 718 dev[0].connect('beacon-rate', key_mgmt="NONE", scan_freq="5180") 719 time.sleep(0.5) 720 finally: 721 dev[0].request("DISCONNECT") 722 hapd.request("DISABLE") 723 subprocess.call(['iw', 'reg', 'set', '00']) 724 dev[0].flush_scan_cache() 725 726def test_ap_beacon_rate_vht(dev, apdev): 727 """Open AP with Beacon frame TX rate VHT-MCS 0""" 728 hapd = hostapd.add_ap(apdev[0], {'ssid': 'beacon-rate'}) 729 res = hapd.get_driver_status_field('capa.flags') 730 if (int(res, 0) & 0x0000200000000000) == 0: 731 raise HwsimSkip("Setting Beacon frame TX rate not supported") 732 hapd.disable() 733 hapd.set('beacon_rate', 'vht:0') 734 hapd.set("country_code", "DE") 735 hapd.set("hw_mode", "a") 736 hapd.set("channel", "36") 737 hapd.set("ieee80211n", "1") 738 hapd.set("ieee80211ac", "1") 739 hapd.set("ht_capab", "[HT40+]") 740 hapd.set("vht_capab", "") 741 hapd.set("vht_oper_chwidth", "0") 742 hapd.set("vht_oper_centr_freq_seg0_idx", "0") 743 try: 744 hapd.enable() 745 dev[0].scan_for_bss(hapd.own_addr(), freq="5180") 746 dev[0].connect('beacon-rate', key_mgmt="NONE", scan_freq="5180") 747 time.sleep(0.5) 748 finally: 749 dev[0].request("DISCONNECT") 750 hapd.request("DISABLE") 751 subprocess.call(['iw', 'reg', 'set', '00']) 752 dev[0].flush_scan_cache() 753 754def test_ap_wep_to_wpa(dev, apdev): 755 """WEP to WPA2-PSK configuration change in hostapd""" 756 check_wep_capa(dev[0]) 757 hapd = hostapd.add_ap(apdev[0], 758 {"ssid": "wep-to-wpa", 759 "wep_key0": '"hello"'}) 760 dev[0].flush_scan_cache() 761 dev[0].connect("wep-to-wpa", key_mgmt="NONE", wep_key0='"hello"', 762 scan_freq="2412") 763 hwsim_utils.test_connectivity(dev[0], hapd) 764 dev[0].request("DISCONNECT") 765 dev[0].wait_disconnected() 766 767 hapd.disable() 768 hapd.set("wep_key0", "") 769 hapd.set("wpa_passphrase", "12345678") 770 hapd.set("wpa", "2") 771 hapd.set("wpa_key_mgmt", "WPA-PSK") 772 hapd.set("rsn_pairwise", "CCMP") 773 hapd.enable() 774 775 dev[0].connect("wep-to-wpa", psk="12345678", scan_freq="2412") 776 hwsim_utils.test_connectivity(dev[0], hapd) 777 778def test_ap_missing_psk(dev, apdev): 779 """WPA2-PSK AP and no PSK configured""" 780 ssid = "test-wpa2-psk" 781 params = hostapd.wpa2_params(ssid=ssid) 782 try: 783 # "WPA-PSK enabled, but PSK or passphrase is not configured." 784 hostapd.add_ap(apdev[0], params) 785 raise Exception("AP setup succeeded unexpectedly") 786 except Exception as e: 787 if "Failed to enable hostapd" in str(e): 788 pass 789 else: 790 raise 791 792def test_ap_eapol_version(dev, apdev): 793 """hostapd eapol_version configuration""" 794 passphrase = "asdfghjkl" 795 params = hostapd.wpa2_params(ssid="test1", passphrase=passphrase) 796 hapd = hostapd.add_ap(apdev[0], params) 797 params = hostapd.wpa2_params(ssid="test2", passphrase=passphrase) 798 params['eapol_version'] = '1' 799 hapd2 = hostapd.add_ap(apdev[1], params) 800 801 hapd.request("SET ext_eapol_frame_io 1") 802 dev[0].connect("test1", psk=passphrase, scan_freq="2412", 803 wait_connect=False) 804 ev1 = hapd.wait_event(["EAPOL-TX"], timeout=15) 805 if ev1 is None: 806 raise Exception("Timeout on EAPOL-TX from hostapd") 807 hapd.request("SET ext_eapol_frame_io 0") 808 809 hapd2.request("SET ext_eapol_frame_io 1") 810 dev[1].connect("test2", psk=passphrase, scan_freq="2412", 811 wait_connect=False) 812 ev2 = hapd2.wait_event(["EAPOL-TX"], timeout=15) 813 if ev2 is None: 814 raise Exception("Timeout on EAPOL-TX from hostapd") 815 hapd2.request("SET ext_eapol_frame_io 0") 816 817 dev[0].wait_connected() 818 dev[1].wait_connected() 819 820 ver1 = ev1.split(' ')[2][0:2] 821 ver2 = ev2.split(' ')[2][0:2] 822 if ver1 != "02": 823 raise Exception("Unexpected default eapol_version: " + ver1) 824 if ver2 != "01": 825 raise Exception("eapol_version did not match configuration: " + ver2) 826 827def test_ap_dtim_period(dev, apdev): 828 """DTIM period configuration""" 829 ssid = "dtim-period" 830 params = {'ssid': ssid, 'dtim_period': "10"} 831 hapd = hostapd.add_ap(apdev[0], params) 832 bssid = hapd.own_addr() 833 dev[0].flush_scan_cache() 834 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") 835 for i in range(10): 836 dev[0].scan(freq="2412") 837 bss = dev[0].get_bss(bssid) 838 if 'beacon_ie' in bss: 839 break 840 time.sleep(0.2) 841 if 'beacon_ie' not in bss: 842 raise Exception("Did not find Beacon IEs") 843 844 ie = parse_ie(bss['beacon_ie']) 845 if 5 not in ie: 846 raise Exception("TIM element missing") 847 count, period = struct.unpack('BB', ie[5][0:2]) 848 logger.info("DTIM count %d DTIM period %d" % (count, period)) 849 if period != 10: 850 raise Exception("Unexpected DTIM period: %d" % period) 851 if count >= period: 852 raise Exception("Unexpected DTIM count: %d" % count) 853 854def test_ap_no_probe_resp(dev, apdev): 855 """AP with Probe Response frame sending from hostapd disabled""" 856 ssid = "no-probe-resp" 857 params = {'ssid': ssid, 'send_probe_response': "0"} 858 hapd = hostapd.add_ap(apdev[0], params) 859 bssid = hapd.own_addr() 860 dev[0].scan_for_bss(bssid, freq="2412", passive=True) 861 dev[0].scan_for_bss(bssid, freq="2412", force_scan=True) 862 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") 863 bss = dev[0].get_bss(bssid) 864 if 'ie' in bss and 'beacon_ie' in bss and \ 865 len(bss['ie']) != len(bss['beacon_ie']): 866 raise Exception("Probe Response frames seen") 867 868def test_ap_long_preamble(dev, apdev): 869 """AP with long preamble""" 870 ssid = "long-preamble" 871 params = {'ssid': ssid, 'preamble': "0", 872 'hw_mode': 'b', 'ieee80211n': '0', 873 'supported_rates': '10', 'basic_rates': '10'} 874 hapd = hostapd.add_ap(apdev[0], params) 875 bssid = hapd.own_addr() 876 dev[0].scan_for_bss(bssid, freq="2412") 877 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") 878 hwsim_utils.test_connectivity(dev[0], hapd) 879 880def test_ap_wmm_uapsd(dev, apdev): 881 """AP with U-APSD advertisement""" 882 ssid = "uapsd" 883 params = {'ssid': ssid, 'uapsd_advertisement_enabled': "1"} 884 hapd = hostapd.add_ap(apdev[0], params) 885 bssid = hapd.own_addr() 886 dev[0].scan_for_bss(bssid, freq="2412") 887 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") 888 hwsim_utils.test_connectivity(dev[0], hapd) 889 890def test_ap_wowlan_triggers(dev, apdev): 891 """AP with wowlan_triggers""" 892 ssid = "wowlan" 893 params = {'ssid': ssid, 'wowlan_triggers': "any"} 894 hapd = hostapd.add_ap(apdev[0], params) 895 bssid = hapd.own_addr() 896 dev[0].scan_for_bss(bssid, freq="2412") 897 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") 898 hwsim_utils.test_connectivity(dev[0], hapd) 899 900def test_ap_notify_mgmt_frames(dev, apdev): 901 """hostapd notify_mgmt_frames configuration enabled""" 902 ssid = "mgmt_frames" 903 params = {'ssid': ssid, 'notify_mgmt_frames': "1"} 904 hapd = hostapd.add_ap(apdev[0], params) 905 bssid = hapd.own_addr() 906 dev[0].scan_for_bss(bssid, freq="2412") 907 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") 908 ev = hapd.wait_event(["AP-MGMT-FRAME-RECEIVED"], timeout=5) 909 if ev is None: 910 raise Exception("AP-MGMT-FRAME-RECEIVED wait timed out") 911 if "buf=b0" not in ev: 912 raise Exception("Expected auth request in AP-MGMT-FRAME-RECEIVED") 913 914def test_ap_notify_mgmt_frames_disabled(dev, apdev): 915 """hostapd notify_mgmt_frames configuration disabled""" 916 ssid = "mgmt_frames" 917 params = {'ssid': ssid, 'notify_mgmt_frames': "0"} 918 hapd = hostapd.add_ap(apdev[0], params) 919 bssid = hapd.own_addr() 920 dev[0].scan_for_bss(bssid, freq="2412") 921 dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") 922 ev = hapd.wait_event(["AP-MGMT-FRAME-RECEIVED"], timeout=0.1) 923 if ev is not None: 924 raise Exception("Unexpected AP-MGMT-FRAME-RECEIVED") 925 926def test_ap_airtime_policy_static(dev, apdev): 927 """Airtime policy - static""" 928 ssid = "test-wpa2-psk" 929 passphrase = 'qwertyuiop' 930 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) 931 params['airtime_mode'] = "1" 932 params['airtime_update_interval'] = "200" 933 params['airtime_sta_weight'] = dev[0].own_addr() + " 512" 934 hapd = hostapd.add_ap(apdev[0], params) 935 dev[0].connect(ssid, psk=passphrase, scan_freq="2412") 936 dev[1].connect(ssid, psk=passphrase, scan_freq="2412") 937 time.sleep(1) 938 939def test_ap_airtime_policy_per_bss_dynamic(dev, apdev): 940 """Airtime policy - per-BSS dynamic""" 941 ssid = "test-wpa2-psk" 942 passphrase = 'qwertyuiop' 943 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) 944 params['airtime_mode'] = "2" 945 params['airtime_update_interval'] = "200" 946 params['airtime_bss_weight'] = "2" 947 hapd = hostapd.add_ap(apdev[0], params) 948 dev[0].connect(ssid, psk=passphrase, scan_freq="2412") 949 dev[1].connect(ssid, psk=passphrase, scan_freq="2412") 950 time.sleep(1) 951 952def test_ap_airtime_policy_per_bss_limit(dev, apdev): 953 """Airtime policy - per-BSS limit""" 954 ssid = "test-wpa2-psk" 955 passphrase = 'qwertyuiop' 956 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) 957 params['airtime_mode'] = "3" 958 params['airtime_update_interval'] = "200" 959 params['airtime_bss_weight'] = "2" 960 params['airtime_bss_limit'] = "1" 961 hapd = hostapd.add_ap(apdev[0], params) 962 dev[0].connect(ssid, psk=passphrase, scan_freq="2412") 963 dev[1].connect(ssid, psk=passphrase, scan_freq="2412") 964 time.sleep(1) 965 hapd.set("force_backlog_bytes", "1") 966 time.sleep(1) 967 968def test_ap_airtime_policy_per_bss_limit_invalid(dev, apdev): 969 """Airtime policy - per-BSS limit (invalid)""" 970 ssid = "test-wpa2-psk" 971 passphrase = 'qwertyuiop' 972 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) 973 params['airtime_mode'] = "3" 974 params['airtime_update_interval'] = "0" 975 params['airtime_bss_weight'] = "2" 976 params['airtime_bss_limit'] = "1" 977 hapd = hostapd.add_ap(apdev[0], params, no_enable=True) 978 if "FAIL" not in hapd.request("ENABLE"): 979 raise Exception("Invalid airtime policy configuration accepted") 980 hapd.set("airtime_update_interval", "200") 981 hapd.enable() 982 hapd.set("airtime_update_interval", "0") 983 dev[0].connect(ssid, psk=passphrase, scan_freq="2412") 984 dev[1].connect(ssid, psk=passphrase, scan_freq="2412") 985 time.sleep(1) 986