Updated to hostap_2_6
[mech_eap.git] / libeap / tests / hwsim / test_ap_open.py
1 # Open mode AP tests
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 struct
11 import subprocess
12 import time
13 import os
14
15 import hostapd
16 import hwsim_utils
17 from tshark import run_tshark
18 from utils import alloc_fail, fail_test, wait_fail_trigger
19 from wpasupplicant import WpaSupplicant
20
21 @remote_compatible
22 def test_ap_open(dev, apdev):
23     """AP with open mode (no security) configuration"""
24     _test_ap_open(dev, apdev)
25
26 def _test_ap_open(dev, apdev):
27     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
28     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
29                    bg_scan_period="0")
30     ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
31     if ev is None:
32         raise Exception("No connection event received from hostapd")
33     hwsim_utils.test_connectivity(dev[0], hapd)
34
35     dev[0].request("DISCONNECT")
36     ev = hapd.wait_event([ "AP-STA-DISCONNECTED" ], timeout=5)
37     if ev is None:
38         raise Exception("No disconnection event received from hostapd")
39
40 def test_ap_open_packet_loss(dev, apdev):
41     """AP with open mode configuration and large packet loss"""
42     params = { "ssid": "open",
43                "ignore_probe_probability": "0.5",
44                "ignore_auth_probability": "0.5",
45                "ignore_assoc_probability": "0.5",
46                "ignore_reassoc_probability": "0.5" }
47     hapd = hostapd.add_ap(apdev[0], params)
48     for i in range(0, 3):
49         dev[i].connect("open", key_mgmt="NONE", scan_freq="2412",
50                        wait_connect=False)
51     for i in range(0, 3):
52         dev[i].wait_connected(timeout=20)
53
54 @remote_compatible
55 def test_ap_open_unknown_action(dev, apdev):
56     """AP with open mode configuration and unknown Action frame"""
57     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
58     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
59     bssid = apdev[0]['bssid']
60     cmd = "MGMT_TX {} {} freq=2412 action=765432".format(bssid, bssid)
61     if "FAIL" in dev[0].request(cmd):
62         raise Exception("Could not send test Action frame")
63     ev = dev[0].wait_event(["MGMT-TX-STATUS"], timeout=10)
64     if ev is None:
65         raise Exception("Timeout on MGMT-TX-STATUS")
66     if "result=SUCCESS" not in ev:
67         raise Exception("AP did not ack Action frame")
68
69 def test_ap_open_invalid_wmm_action(dev, apdev):
70     """AP with open mode configuration and invalid WMM Action frame"""
71     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
72     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
73     bssid = apdev[0]['bssid']
74     cmd = "MGMT_TX {} {} freq=2412 action=1100".format(bssid, bssid)
75     if "FAIL" in dev[0].request(cmd):
76         raise Exception("Could not send test Action frame")
77     ev = dev[0].wait_event(["MGMT-TX-STATUS"], timeout=10)
78     if ev is None or "result=SUCCESS" not in ev:
79         raise Exception("AP did not ack Action frame")
80
81 @remote_compatible
82 def test_ap_open_reconnect_on_inactivity_disconnect(dev, apdev):
83     """Reconnect to open mode AP after inactivity related disconnection"""
84     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
85     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
86     hapd.request("DEAUTHENTICATE " + dev[0].p2p_interface_addr() + " reason=4")
87     dev[0].wait_disconnected(timeout=5)
88     dev[0].wait_connected(timeout=2, error="Timeout on reconnection")
89
90 @remote_compatible
91 def test_ap_open_assoc_timeout(dev, apdev):
92     """AP timing out association"""
93     ssid = "test"
94     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
95     dev[0].scan(freq="2412")
96     hapd.set("ext_mgmt_frame_handling", "1")
97     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
98                    wait_connect=False)
99     for i in range(0, 10):
100         req = hapd.mgmt_rx()
101         if req is None:
102             raise Exception("MGMT RX wait timed out")
103         if req['subtype'] == 11:
104             break
105         req = None
106     if not req:
107         raise Exception("Authentication frame not received")
108
109     resp = {}
110     resp['fc'] = req['fc']
111     resp['da'] = req['sa']
112     resp['sa'] = req['da']
113     resp['bssid'] = req['bssid']
114     resp['payload'] = struct.pack('<HHH', 0, 2, 0)
115     hapd.mgmt_tx(resp)
116
117     assoc = 0
118     for i in range(0, 10):
119         req = hapd.mgmt_rx()
120         if req is None:
121             raise Exception("MGMT RX wait timed out")
122         if req['subtype'] == 0:
123             assoc += 1
124             if assoc == 3:
125                 break
126     if assoc != 3:
127         raise Exception("Association Request frames not received: assoc=%d" % assoc)
128     hapd.set("ext_mgmt_frame_handling", "0")
129     dev[0].wait_connected(timeout=15)
130
131 @remote_compatible
132 def test_ap_open_id_str(dev, apdev):
133     """AP with open mode and id_str"""
134     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
135     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412", id_str="foo",
136                    wait_connect=False)
137     ev = dev[0].wait_connected(timeout=10)
138     if "id_str=foo" not in ev:
139         raise Exception("CTRL-EVENT-CONNECT did not have matching id_str: " + ev)
140     if dev[0].get_status_field("id_str") != "foo":
141         raise Exception("id_str mismatch")
142
143 @remote_compatible
144 def test_ap_open_select_any(dev, apdev):
145     """AP with open mode and select any network"""
146     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
147     id = dev[0].connect("unknown", key_mgmt="NONE", scan_freq="2412",
148                         only_add_network=True)
149     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
150                    only_add_network=True)
151     dev[0].select_network(id)
152     ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND",
153                             "CTRL-EVENT-CONNECTED"], timeout=10)
154     if ev is None:
155         raise Exception("No result reported")
156     if "CTRL-EVENT-CONNECTED" in ev:
157         raise Exception("Unexpected connection")
158
159     dev[0].select_network("any")
160     dev[0].wait_connected(timeout=10)
161
162 @remote_compatible
163 def test_ap_open_unexpected_assoc_event(dev, apdev):
164     """AP with open mode and unexpected association event"""
165     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
166     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
167     dev[0].request("DISCONNECT")
168     dev[0].wait_disconnected(timeout=15)
169     dev[0].dump_monitor()
170     # This will be accepted due to matching network
171     dev[0].cmd_execute(['iw', 'dev', dev[0].ifname, 'connect', 'open', "2412",
172                         apdev[0]['bssid']])
173     dev[0].wait_connected(timeout=15)
174     dev[0].dump_monitor()
175
176     dev[0].request("REMOVE_NETWORK all")
177     dev[0].wait_disconnected(timeout=5)
178     dev[0].dump_monitor()
179     # This will result in disconnection due to no matching network
180     dev[0].cmd_execute(['iw', 'dev', dev[0].ifname, 'connect', 'open', "2412",
181                         apdev[0]['bssid']])
182     dev[0].wait_disconnected(timeout=15)
183
184 @remote_compatible
185 def test_ap_bss_load(dev, apdev):
186     """AP with open mode (no security) configuration"""
187     hapd = hostapd.add_ap(apdev[0],
188                           { "ssid": "open",
189                             "bss_load_update_period": "10" })
190     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
191     # this does not really get much useful output with mac80211_hwsim currently,
192     # but run through the channel survey update couple of times
193     for i in range(0, 10):
194         hwsim_utils.test_connectivity(dev[0], hapd)
195         hwsim_utils.test_connectivity(dev[0], hapd)
196         hwsim_utils.test_connectivity(dev[0], hapd)
197         time.sleep(0.15)
198
199 def hapd_out_of_mem(hapd, apdev, count, func):
200     with alloc_fail(hapd, count, func):
201         started = False
202         try:
203             hostapd.add_ap(apdev, { "ssid": "open" })
204             started = True
205         except:
206             pass
207         if started:
208             raise Exception("hostapd interface started even with memory allocation failure: %d:%s" % (count, func))
209
210 def test_ap_open_out_of_memory(dev, apdev):
211     """hostapd failing to setup interface due to allocation failure"""
212     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
213     hapd_out_of_mem(hapd, apdev[1], 1, "hostapd_alloc_bss_data")
214
215     for i in range(1, 3):
216         hapd_out_of_mem(hapd, apdev[1], i, "hostapd_iface_alloc")
217
218     for i in range(1, 5):
219         hapd_out_of_mem(hapd, apdev[1], i, "hostapd_config_defaults;hostapd_config_alloc")
220
221     hapd_out_of_mem(hapd, apdev[1], 1, "hostapd_config_alloc")
222
223     hapd_out_of_mem(hapd, apdev[1], 1, "hostapd_driver_init")
224
225     for i in range(1, 3):
226         hapd_out_of_mem(hapd, apdev[1], i, "=wpa_driver_nl80211_drv_init")
227
228     # eloop_register_read_sock() call from i802_init()
229     hapd_out_of_mem(hapd, apdev[1], 1, "eloop_sock_table_add_sock;?eloop_register_sock;?eloop_register_read_sock;=i802_init")
230
231     # verify that a new interface can still be added when memory allocation does
232     # not fail
233     hostapd.add_ap(apdev[1], { "ssid": "open" })
234
235 def test_bssid_black_white_list(dev, apdev):
236     """BSSID black/white list"""
237     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
238     hapd2 = hostapd.add_ap(apdev[1], { "ssid": "open" })
239
240     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
241                    bssid_whitelist=apdev[1]['bssid'])
242     dev[1].connect("open", key_mgmt="NONE", scan_freq="2412",
243                    bssid_blacklist=apdev[1]['bssid'])
244     dev[2].connect("open", key_mgmt="NONE", scan_freq="2412",
245                    bssid_whitelist="00:00:00:00:00:00/00:00:00:00:00:00",
246                    bssid_blacklist=apdev[1]['bssid'])
247     if dev[0].get_status_field('bssid') != apdev[1]['bssid']:
248         raise Exception("dev[0] connected to unexpected AP")
249     if dev[1].get_status_field('bssid') != apdev[0]['bssid']:
250         raise Exception("dev[1] connected to unexpected AP")
251     if dev[2].get_status_field('bssid') != apdev[0]['bssid']:
252         raise Exception("dev[2] connected to unexpected AP")
253     dev[0].request("REMOVE_NETWORK all")
254     dev[1].request("REMOVE_NETWORK all")
255     dev[2].request("REMOVE_NETWORK all")
256
257     dev[2].connect("open", key_mgmt="NONE", scan_freq="2412",
258                    bssid_whitelist="00:00:00:00:00:00", wait_connect=False)
259     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
260                    bssid_whitelist="11:22:33:44:55:66/ff:00:00:00:00:00 " + apdev[1]['bssid'] + " aa:bb:cc:dd:ee:ff")
261     dev[1].connect("open", key_mgmt="NONE", scan_freq="2412",
262                    bssid_blacklist="11:22:33:44:55:66/ff:00:00:00:00:00 " + apdev[1]['bssid'] + " aa:bb:cc:dd:ee:ff")
263     if dev[0].get_status_field('bssid') != apdev[1]['bssid']:
264         raise Exception("dev[0] connected to unexpected AP")
265     if dev[1].get_status_field('bssid') != apdev[0]['bssid']:
266         raise Exception("dev[1] connected to unexpected AP")
267     dev[0].request("REMOVE_NETWORK all")
268     dev[1].request("REMOVE_NETWORK all")
269     ev = dev[2].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.1)
270     if ev is not None:
271         raise Exception("Unexpected dev[2] connectin")
272     dev[2].request("REMOVE_NETWORK all")
273
274 def test_ap_open_wpas_in_bridge(dev, apdev):
275     """Open mode AP and wpas interface in a bridge"""
276     br_ifname='sta-br0'
277     ifname='wlan5'
278     try:
279         _test_ap_open_wpas_in_bridge(dev, apdev)
280     finally:
281         subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'down'])
282         subprocess.call(['brctl', 'delif', br_ifname, ifname])
283         subprocess.call(['brctl', 'delbr', br_ifname])
284         subprocess.call(['iw', ifname, 'set', '4addr', 'off'])
285
286 def _test_ap_open_wpas_in_bridge(dev, apdev):
287     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
288
289     br_ifname='sta-br0'
290     ifname='wlan5'
291     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
292     # First, try a failure case of adding an interface
293     try:
294         wpas.interface_add(ifname, br_ifname=br_ifname)
295         raise Exception("Interface addition succeeded unexpectedly")
296     except Exception, e:
297         if "Failed to add" in str(e):
298             logger.info("Ignore expected interface_add failure due to missing bridge interface: " + str(e))
299         else:
300             raise
301
302     # Next, add the bridge interface and add the interface again
303     subprocess.call(['brctl', 'addbr', br_ifname])
304     subprocess.call(['brctl', 'setfd', br_ifname, '0'])
305     subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'up'])
306     subprocess.call(['iw', ifname, 'set', '4addr', 'on'])
307     subprocess.check_call(['brctl', 'addif', br_ifname, ifname])
308     wpas.interface_add(ifname, br_ifname=br_ifname)
309
310     wpas.connect("open", key_mgmt="NONE", scan_freq="2412")
311
312 @remote_compatible
313 def test_ap_open_start_disabled(dev, apdev):
314     """AP with open mode and beaconing disabled"""
315     hapd = hostapd.add_ap(apdev[0], { "ssid": "open",
316                                       "start_disabled": "1" })
317     bssid = apdev[0]['bssid']
318
319     dev[0].flush_scan_cache()
320     dev[0].scan(freq=2412, only_new=True)
321     if dev[0].get_bss(bssid) is not None:
322         raise Exception("AP was seen beaconing")
323     if "OK" not in hapd.request("RELOAD"):
324         raise Exception("RELOAD failed")
325     dev[0].scan_for_bss(bssid, freq=2412)
326     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
327
328 @remote_compatible
329 def test_ap_open_start_disabled2(dev, apdev):
330     """AP with open mode and beaconing disabled (2)"""
331     hapd = hostapd.add_ap(apdev[0], { "ssid": "open",
332                                       "start_disabled": "1" })
333     bssid = apdev[0]['bssid']
334
335     dev[0].flush_scan_cache()
336     dev[0].scan(freq=2412, only_new=True)
337     if dev[0].get_bss(bssid) is not None:
338         raise Exception("AP was seen beaconing")
339     if "OK" not in hapd.request("UPDATE_BEACON"):
340         raise Exception("UPDATE_BEACON failed")
341     dev[0].scan_for_bss(bssid, freq=2412)
342     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
343     if "OK" not in hapd.request("UPDATE_BEACON"):
344         raise Exception("UPDATE_BEACON failed")
345     dev[0].request("DISCONNECT")
346     dev[0].wait_disconnected()
347     dev[0].request("RECONNECT")
348     dev[0].wait_connected()
349
350 @remote_compatible
351 def test_ap_open_ifdown(dev, apdev):
352     """AP with open mode and external ifconfig down"""
353     params = { "ssid": "open",
354                "ap_max_inactivity": "1" }
355     hapd = hostapd.add_ap(apdev[0], params)
356     bssid = apdev[0]['bssid']
357
358     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
359     dev[1].connect("open", key_mgmt="NONE", scan_freq="2412")
360     hapd.cmd_execute(['ip', 'link', 'set', 'dev', apdev[0]['ifname'], 'down'])
361     ev = hapd.wait_event(["AP-STA-DISCONNECTED"], timeout=10)
362     if ev is None:
363         raise Exception("Timeout on AP-STA-DISCONNECTED (1)")
364     ev = hapd.wait_event(["AP-STA-DISCONNECTED"], timeout=5)
365     if ev is None:
366         raise Exception("Timeout on AP-STA-DISCONNECTED (2)")
367     ev = hapd.wait_event(["INTERFACE-DISABLED"], timeout=5)
368     if ev is None:
369         raise Exception("No INTERFACE-DISABLED event")
370     # The following wait tests beacon loss detection in mac80211 on dev0.
371     # dev1 is used to test stopping of AP side functionality on client polling.
372     dev[1].request("REMOVE_NETWORK all")
373     hapd.cmd_execute(['ip', 'link', 'set', 'dev', apdev[0]['ifname'], 'up'])
374     dev[0].wait_disconnected()
375     dev[1].wait_disconnected()
376     ev = hapd.wait_event(["INTERFACE-ENABLED"], timeout=10)
377     if ev is None:
378         raise Exception("No INTERFACE-ENABLED event")
379     dev[0].wait_connected()
380     hwsim_utils.test_connectivity(dev[0], hapd)
381
382 def test_ap_open_disconnect_in_ps(dev, apdev, params):
383     """Disconnect with the client in PS to regression-test a kernel bug"""
384     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
385     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
386                    bg_scan_period="0")
387     ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
388     if ev is None:
389         raise Exception("No connection event received from hostapd")
390
391     time.sleep(0.2)
392     hwsim_utils.set_powersave(dev[0], hwsim_utils.PS_MANUAL_POLL)
393     try:
394         # inject some traffic
395         sa = hapd.own_addr()
396         da = dev[0].own_addr()
397         hapd.request('DATA_TEST_CONFIG 1')
398         hapd.request('DATA_TEST_TX {} {} 0'.format(da, sa))
399         hapd.request('DATA_TEST_CONFIG 0')
400
401         # let the AP send couple of Beacon frames
402         time.sleep(0.3)
403
404         # disconnect - with traffic pending - shouldn't cause kernel warnings
405         dev[0].request("DISCONNECT")
406     finally:
407         hwsim_utils.set_powersave(dev[0], hwsim_utils.PS_DISABLED)
408
409     time.sleep(0.2)
410     out = run_tshark(os.path.join(params['logdir'], "hwsim0.pcapng"),
411                      "wlan_mgt.tim.partial_virtual_bitmap",
412                      ["wlan_mgt.tim.partial_virtual_bitmap"])
413     if out is not None:
414         state = 0
415         for l in out.splitlines():
416             pvb = int(l, 16)
417             if pvb > 0 and state == 0:
418                 state = 1
419             elif pvb == 0 and state == 1:
420                 state = 2
421         if state != 2:
422             raise Exception("Didn't observe TIM bit getting set and unset (state=%d)" % state)
423
424 @remote_compatible
425 def test_ap_open_select_network(dev, apdev):
426     """Open mode connection and SELECT_NETWORK to change network"""
427     hapd1 = hostapd.add_ap(apdev[0], { "ssid": "open" })
428     bssid1 = apdev[0]['bssid']
429     hapd2 = hostapd.add_ap(apdev[1], { "ssid": "open2" })
430     bssid2 = apdev[1]['bssid']
431
432     id1 = dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
433                          only_add_network=True)
434     id2 = dev[0].connect("open2", key_mgmt="NONE", scan_freq="2412")
435     hwsim_utils.test_connectivity(dev[0], hapd2)
436
437     dev[0].select_network(id1)
438     dev[0].wait_connected()
439     res = dev[0].request("BLACKLIST")
440     if bssid1 in res or bssid2 in res:
441         raise Exception("Unexpected blacklist entry")
442     hwsim_utils.test_connectivity(dev[0], hapd1)
443
444     dev[0].select_network(id2)
445     dev[0].wait_connected()
446     hwsim_utils.test_connectivity(dev[0], hapd2)
447     res = dev[0].request("BLACKLIST")
448     if bssid1 in res or bssid2 in res:
449         raise Exception("Unexpected blacklist entry(2)")
450
451 @remote_compatible
452 def test_ap_open_disable_enable(dev, apdev):
453     """AP with open mode getting disabled and re-enabled"""
454     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
455     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
456                    bg_scan_period="0")
457
458     for i in range(2):
459         hapd.request("DISABLE")
460         dev[0].wait_disconnected()
461         hapd.request("ENABLE")
462         dev[0].wait_connected()
463         hwsim_utils.test_connectivity(dev[0], hapd)
464
465 def sta_enable_disable(dev, bssid):
466     dev.scan_for_bss(bssid, freq=2412)
467     work_id = dev.request("RADIO_WORK add block-work")
468     ev = dev.wait_event(["EXT-RADIO-WORK-START"])
469     if ev is None:
470         raise Exception("Timeout while waiting radio work to start")
471     id = dev.connect("open", key_mgmt="NONE", scan_freq="2412",
472                      only_add_network=True)
473     dev.request("ENABLE_NETWORK %d" % id)
474     if "connect@" not in dev.request("RADIO_WORK show"):
475         raise Exception("connect radio work missing")
476     dev.request("DISABLE_NETWORK %d" % id)
477     dev.request("RADIO_WORK done " + work_id)
478
479     ok = False
480     for i in range(30):
481         if "connect@" not in dev.request("RADIO_WORK show"):
482             ok = True
483             break
484         time.sleep(0.1)
485     if not ok:
486         raise Exception("connect radio work not completed")
487     ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.1)
488     if ev is not None:
489         raise Exception("Unexpected connection")
490     dev.request("DISCONNECT")
491
492 def test_ap_open_sta_enable_disable(dev, apdev):
493     """AP with open mode and wpa_supplicant ENABLE/DISABLE_NETWORK"""
494     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
495     bssid = apdev[0]['bssid']
496
497     sta_enable_disable(dev[0], bssid)
498
499     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
500     wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
501     sta_enable_disable(wpas, bssid)
502
503 @remote_compatible
504 def test_ap_open_select_twice(dev, apdev):
505     """AP with open mode and select network twice"""
506     id = dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
507                         only_add_network=True)
508     dev[0].select_network(id)
509     ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10)
510     if ev is None:
511         raise Exception("No result reported")
512     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
513     # Verify that the second SELECT_NETWORK starts a new scan immediately by
514     # waiting less than the default scan period.
515     dev[0].select_network(id)
516     dev[0].wait_connected(timeout=3)
517
518 @remote_compatible
519 def test_ap_open_reassoc_not_found(dev, apdev):
520     """AP with open mode and REASSOCIATE not finding a match"""
521     id = dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
522                         only_add_network=True)
523     dev[0].select_network(id)
524     ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10)
525     if ev is None:
526         raise Exception("No result reported")
527     dev[0].request("DISCONNECT")
528
529     time.sleep(0.1)
530     dev[0].dump_monitor()
531
532     dev[0].request("REASSOCIATE")
533     ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=10)
534     if ev is None:
535         raise Exception("No result reported")
536     dev[0].request("DISCONNECT")
537
538 @remote_compatible
539 def test_ap_open_sta_statistics(dev, apdev):
540     """AP with open mode and STA statistics"""
541     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
542     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
543     addr = dev[0].own_addr()
544
545     stats1 = hapd.get_sta(addr)
546     logger.info("stats1: " + str(stats1))
547     time.sleep(0.4)
548     stats2 = hapd.get_sta(addr)
549     logger.info("stats2: " + str(stats2))
550     hwsim_utils.test_connectivity(dev[0], hapd)
551     stats3 = hapd.get_sta(addr)
552     logger.info("stats3: " + str(stats3))
553
554     # Cannot require specific inactive_msec changes without getting rid of all
555     # unrelated traffic, so for now, just print out the results in the log for
556     # manual checks.
557
558 @remote_compatible
559 def test_ap_open_poll_sta(dev, apdev):
560     """AP with open mode and STA poll"""
561     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
562     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
563     addr = dev[0].own_addr()
564
565     if "OK" not in hapd.request("POLL_STA " + addr):
566         raise Exception("POLL_STA failed")
567     ev = hapd.wait_event(["AP-STA-POLL-OK"], timeout=5)
568     if ev is None:
569         raise Exception("Poll response not seen")
570     if addr not in ev:
571         raise Exception("Unexpected poll response: " + ev)
572
573 def test_ap_open_pmf_default(dev, apdev):
574     """AP with open mode (no security) configuration and pmf=2"""
575     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
576     dev[1].connect("open", key_mgmt="NONE", scan_freq="2412",
577                    ieee80211w="2", wait_connect=False)
578     dev[2].connect("open", key_mgmt="NONE", scan_freq="2412",
579                    ieee80211w="1")
580     try:
581         dev[0].request("SET pmf 2")
582         dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
583
584         dev[0].request("DISCONNECT")
585         dev[0].wait_disconnected()
586     finally:
587         dev[0].request("SET pmf 0")
588     dev[2].request("DISCONNECT")
589     dev[2].wait_disconnected()
590
591     ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.1)
592     if ev is not None:
593         raise Exception("Unexpected dev[1] connection")
594     dev[1].request("DISCONNECT")
595
596 def test_ap_open_drv_fail(dev, apdev):
597     """AP with open mode and driver operations failing"""
598     hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
599
600     with fail_test(dev[0], 1, "wpa_driver_nl80211_authenticate"):
601         dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
602                        wait_connect=False)
603         wait_fail_trigger(dev[0], "GET_FAIL")
604         dev[0].request("REMOVE_NETWORK all")
605
606     with fail_test(dev[0], 1, "wpa_driver_nl80211_associate"):
607         dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
608                        wait_connect=False)
609         wait_fail_trigger(dev[0], "GET_FAIL")
610         dev[0].request("REMOVE_NETWORK all")