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