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 
7 from remotehost import remote_compatible
8 import logging
9 logger = logging.getLogger()
10 import os
11 import struct
12 import subprocess
13 import time
14 
15 import hwsim_utils
16 import hostapd
17 from tshark import run_tshark
18 from utils import *
19 
20 @remote_compatible
21 def 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
38 def 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
53 def 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 
67 def 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 
91 def 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
104 def 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 
116 def 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 
144 def 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 
169 def 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 
188 def 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 
268 def 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
292 def 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 
337 def 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 
374 def 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 
406 def 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
443 def 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
462 def 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
482 def 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
492 def 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 
501 def 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
526 def 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
541 def 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 
554 def 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
584 def 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 
601 def 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 
639 def 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 
651 def 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 
655 def 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 
659 def 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 
686 def 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 
698 def 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 
726 def 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 
754 def 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 
778 def 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 
792 def 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 
827 def 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 
854 def 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 
868 def 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 
880 def 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 
890 def 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 
900 def 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 
914 def 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 
926 def 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 
939 def 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 
952 def 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 
968 def 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