2 # Copyright (c) 2013-2015, Jouni Malinen <j@w1.fi>
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
7 from remotehost import remote_compatible
10 logger = logging.getLogger()
15 from wpasupplicant import WpaSupplicant
16 from utils import HwsimSkip, fail_test, alloc_fail, wait_fail_trigger
17 from tshark import run_tshark
19 def check_scan(dev, params, other_started=False, test_busy=False):
22 id = dev.request("SCAN " + params)
24 raise Exception("Failed to start scan")
28 if "FAIL-BUSY" not in dev.request("SCAN"):
29 raise Exception("SCAN command while already scanning not rejected")
32 ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"])
34 raise Exception("Other scan did not start")
35 if "id=" + str(id) in ev:
36 raise Exception("Own scan id unexpectedly included in start event")
38 ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"])
40 raise Exception("Other scan did not complete")
41 if "id=" + str(id) in ev:
42 raise Exception("Own scan id unexpectedly included in completed event")
44 ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"])
46 raise Exception("Scan did not start")
47 if "id=" + str(id) not in ev:
48 raise Exception("Scan id not included in start event")
50 if "FAIL-BUSY" not in dev.request("SCAN"):
51 raise Exception("SCAN command while already scanning not rejected")
53 ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"])
55 raise Exception("Scan did not complete")
56 if "id=" + str(id) not in ev:
57 raise Exception("Scan id not included in completed event")
59 def check_scan_retry(dev, params, bssid):
61 check_scan(dev, "freq=2412-2462,5180 use_id=1")
62 if int(dev.get_bss(bssid)['age']) <= 1:
64 raise Exception("Unexpectedly old BSS entry")
67 def test_scan(dev, apdev):
68 """Control interface behavior on scan parameters"""
69 hostapd.add_ap(apdev[0], { "ssid": "test-scan" })
70 bssid = apdev[0]['bssid']
72 logger.info("Full scan")
73 check_scan(dev[0], "use_id=1", test_busy=True)
75 logger.info("Limited channel scan")
76 check_scan_retry(dev[0], "freq=2412-2462,5180 use_id=1", bssid)
78 # wait long enough to allow next scans to be verified not to find the AP
81 logger.info("Passive single-channel scan")
82 check_scan(dev[0], "freq=2457 passive=1 use_id=1")
83 logger.info("Active single-channel scan")
84 check_scan(dev[0], "freq=2452 passive=0 use_id=1")
85 if int(dev[0].get_bss(bssid)['age']) < 2:
86 raise Exception("Unexpectedly updated BSS entry")
88 logger.info("Active single-channel scan on AP's operating channel")
89 check_scan_retry(dev[0], "freq=2412 passive=0 use_id=1", bssid)
92 def test_scan_tsf(dev, apdev):
93 """Scan and TSF updates from Beacon/Probe Response frames"""
94 hostapd.add_ap(apdev[0], { "ssid": "test-scan",
95 'beacon_int': "100" })
96 bssid = apdev[0]['bssid']
99 for passive in [ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1 ]:
100 check_scan(dev[0], "freq=2412 passive=%d use_id=1" % passive)
101 bss = dev[0].get_bss(bssid)
103 tsf.append(int(bss['tsf']))
104 logger.info("TSF: " + bss['tsf'])
105 if tsf[-3] <= tsf[-4]:
106 # For now, only write this in the log without failing the test case
107 # since mac80211_hwsim does not yet update the Timestamp field in
108 # Probe Response frames.
109 logger.info("Probe Response did not update TSF")
110 #raise Exception("Probe Response did not update TSF")
111 if tsf[-1] <= tsf[-3]:
112 raise Exception("Beacon did not update TSF")
114 raise Exception("0 TSF reported")
117 def test_scan_only(dev, apdev):
118 """Control interface behavior on scan parameters with type=only"""
119 hostapd.add_ap(apdev[0], { "ssid": "test-scan" })
120 bssid = apdev[0]['bssid']
122 logger.info("Full scan")
123 check_scan(dev[0], "type=only use_id=1")
125 logger.info("Limited channel scan")
126 check_scan_retry(dev[0], "type=only freq=2412-2462,5180 use_id=1", bssid)
128 # wait long enough to allow next scans to be verified not to find the AP
131 logger.info("Passive single-channel scan")
132 check_scan(dev[0], "type=only freq=2457 passive=1 use_id=1")
133 logger.info("Active single-channel scan")
134 check_scan(dev[0], "type=only freq=2452 passive=0 use_id=1")
135 if int(dev[0].get_bss(bssid)['age']) < 2:
136 raise Exception("Unexpectedly updated BSS entry")
138 logger.info("Active single-channel scan on AP's operating channel")
139 check_scan_retry(dev[0], "type=only freq=2412 passive=0 use_id=1", bssid)
142 def test_scan_external_trigger(dev, apdev):
143 """Avoid operations during externally triggered scan"""
144 hostapd.add_ap(apdev[0], { "ssid": "test-scan" })
145 bssid = apdev[0]['bssid']
146 dev[0].cmd_execute(['iw', dev[0].ifname, 'scan', 'trigger'])
147 check_scan(dev[0], "use_id=1", other_started=True)
149 def test_scan_bss_expiration_count(dev, apdev):
150 """BSS entry expiration based on scan results without match"""
151 if "FAIL" not in dev[0].request("BSS_EXPIRE_COUNT 0"):
152 raise Exception("Invalid BSS_EXPIRE_COUNT accepted")
153 if "OK" not in dev[0].request("BSS_EXPIRE_COUNT 2"):
154 raise Exception("BSS_EXPIRE_COUNT failed")
155 hapd = hostapd.add_ap(apdev[0], { "ssid": "test-scan" })
156 bssid = apdev[0]['bssid']
157 dev[0].scan(freq="2412", only_new=True)
158 if bssid not in dev[0].request("SCAN_RESULTS"):
159 raise Exception("BSS not found in initial scan")
160 hapd.request("DISABLE")
161 dev[0].scan(freq="2412", only_new=True)
162 if bssid not in dev[0].request("SCAN_RESULTS"):
163 raise Exception("BSS not found in first scan without match")
164 dev[0].scan(freq="2412", only_new=True)
165 if bssid in dev[0].request("SCAN_RESULTS"):
166 raise Exception("BSS found after two scans without match")
169 def test_scan_bss_expiration_age(dev, apdev):
170 """BSS entry expiration based on age"""
172 if "FAIL" not in dev[0].request("BSS_EXPIRE_AGE COUNT 9"):
173 raise Exception("Invalid BSS_EXPIRE_AGE accepted")
174 if "OK" not in dev[0].request("BSS_EXPIRE_AGE 10"):
175 raise Exception("BSS_EXPIRE_AGE failed")
176 hapd = hostapd.add_ap(apdev[0], { "ssid": "test-scan" })
177 bssid = apdev[0]['bssid']
178 # Allow couple more retries to avoid reporting errors during heavy load
180 dev[0].scan(freq="2412")
181 if bssid in dev[0].request("SCAN_RESULTS"):
183 if bssid not in dev[0].request("SCAN_RESULTS"):
184 raise Exception("BSS not found in initial scan")
185 hapd.request("DISABLE")
186 logger.info("Waiting for BSS entry to expire")
188 if bssid not in dev[0].request("SCAN_RESULTS"):
189 raise Exception("BSS expired too quickly")
190 ev = dev[0].wait_event(["CTRL-EVENT-BSS-REMOVED"], timeout=15)
192 raise Exception("BSS entry expiration timed out")
193 if bssid in dev[0].request("SCAN_RESULTS"):
194 raise Exception("BSS not removed after expiration time")
196 dev[0].request("BSS_EXPIRE_AGE 180")
199 def test_scan_filter(dev, apdev):
200 """Filter scan results based on SSID"""
202 if "OK" not in dev[0].request("SET filter_ssids 1"):
203 raise Exception("SET failed")
204 id = dev[0].connect("test-scan", key_mgmt="NONE", only_add_network=True)
205 hostapd.add_ap(apdev[0], { "ssid": "test-scan" })
206 bssid = apdev[0]['bssid']
207 hostapd.add_ap(apdev[1], { "ssid": "test-scan2" })
208 bssid2 = apdev[1]['bssid']
209 dev[0].scan(freq="2412", only_new=True)
210 if bssid not in dev[0].request("SCAN_RESULTS"):
211 raise Exception("BSS not found in scan results")
212 if bssid2 in dev[0].request("SCAN_RESULTS"):
213 raise Exception("Unexpected BSS found in scan results")
214 dev[0].set_network_quoted(id, "ssid", "")
215 dev[0].scan(freq="2412")
216 id2 = dev[0].connect("test", key_mgmt="NONE", only_add_network=True)
217 dev[0].scan(freq="2412")
219 dev[0].request("SET filter_ssids 0")
222 def test_scan_int(dev, apdev):
223 """scan interval configuration"""
225 if "FAIL" not in dev[0].request("SCAN_INTERVAL -1"):
226 raise Exception("Accepted invalid scan interval")
227 if "OK" not in dev[0].request("SCAN_INTERVAL 1"):
228 raise Exception("Failed to set scan interval")
229 dev[0].connect("not-used", key_mgmt="NONE", scan_freq="2412",
232 for i in range(0, 3):
233 logger.info("Waiting for scan to start")
234 start = os.times()[4]
235 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=5)
237 raise Exception("did not start a scan")
239 times[i] = stop - start
240 logger.info("Waiting for scan to complete")
241 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
243 raise Exception("did not complete a scan")
244 logger.info("times=" + str(times))
245 if times[0] > 1 or times[1] < 0.5 or times[1] > 1.5 or times[2] < 0.5 or times[2] > 1.5:
246 raise Exception("Unexpected scan timing: " + str(times))
248 dev[0].request("SCAN_INTERVAL 5")
250 def test_scan_bss_operations(dev, apdev):
251 """Control interface behavior on BSS parameters"""
252 hostapd.add_ap(apdev[0], { "ssid": "test-scan" })
253 bssid = apdev[0]['bssid']
254 hostapd.add_ap(apdev[1], { "ssid": "test2-scan" })
255 bssid2 = apdev[1]['bssid']
257 dev[0].scan(freq="2412")
258 dev[0].scan(freq="2412")
259 dev[0].scan(freq="2412")
261 id1 = dev[0].request("BSS FIRST MASK=0x1").splitlines()[0].split('=')[1]
262 id2 = dev[0].request("BSS LAST MASK=0x1").splitlines()[0].split('=')[1]
264 res = dev[0].request("BSS RANGE=ALL MASK=0x20001")
265 if "id=" + id1 not in res:
266 raise Exception("Missing BSS " + id1)
267 if "id=" + id2 not in res:
268 raise Exception("Missing BSS " + id2)
269 if "====" not in res:
270 raise Exception("Missing delim")
271 if "####" not in res:
272 raise Exception("Missing end")
274 res = dev[0].request("BSS RANGE=ALL MASK=0")
275 if "id=" + id1 not in res:
276 raise Exception("Missing BSS " + id1)
277 if "id=" + id2 not in res:
278 raise Exception("Missing BSS " + id2)
280 raise Exception("Unexpected delim")
282 raise Exception("Unexpected end delim")
284 res = dev[0].request("BSS RANGE=ALL MASK=0x1").splitlines()
286 raise Exception("Unexpected result: " + str(res))
287 res = dev[0].request("BSS FIRST MASK=0x1")
288 if "id=" + id1 not in res:
289 raise Exception("Unexpected result: " + res)
290 res = dev[0].request("BSS LAST MASK=0x1")
291 if "id=" + id2 not in res:
292 raise Exception("Unexpected result: " + res)
293 res = dev[0].request("BSS ID-" + id1 + " MASK=0x1")
294 if "id=" + id1 not in res:
295 raise Exception("Unexpected result: " + res)
296 res = dev[0].request("BSS NEXT-" + id1 + " MASK=0x1")
297 if "id=" + id2 not in res:
298 raise Exception("Unexpected result: " + res)
299 res = dev[0].request("BSS NEXT-" + id2 + " MASK=0x1")
301 raise Exception("Unexpected result: " + res)
303 if len(dev[0].request("BSS RANGE=" + id2 + " MASK=0x1").splitlines()) != 0:
304 raise Exception("Unexpected RANGE=1 result")
305 if len(dev[0].request("BSS RANGE=" + id1 + "- MASK=0x1").splitlines()) != 2:
306 raise Exception("Unexpected RANGE=0- result")
307 if len(dev[0].request("BSS RANGE=-" + id2 + " MASK=0x1").splitlines()) != 2:
308 raise Exception("Unexpected RANGE=-1 result")
309 if len(dev[0].request("BSS RANGE=" + id1 + "-" + id2 + " MASK=0x1").splitlines()) != 2:
310 raise Exception("Unexpected RANGE=0-1 result")
311 if len(dev[0].request("BSS RANGE=" + id2 + "-" + id2 + " MASK=0x1").splitlines()) != 1:
312 raise Exception("Unexpected RANGE=1-1 result")
313 if len(dev[0].request("BSS RANGE=" + str(int(id2) + 1) + "-" + str(int(id2) + 10) + " MASK=0x1").splitlines()) != 0:
314 raise Exception("Unexpected RANGE=2-10 result")
315 if len(dev[0].request("BSS RANGE=0-" + str(int(id2) + 10) + " MASK=0x1").splitlines()) != 2:
316 raise Exception("Unexpected RANGE=0-10 result")
317 if len(dev[0].request("BSS RANGE=" + id1 + "-" + id1 + " MASK=0x1").splitlines()) != 1:
318 raise Exception("Unexpected RANGE=0-0 result")
320 res = dev[0].request("BSS p2p_dev_addr=FOO")
321 if "FAIL" in res or "id=" in res:
322 raise Exception("Unexpected result: " + res)
323 res = dev[0].request("BSS p2p_dev_addr=00:11:22:33:44:55")
324 if "FAIL" in res or "id=" in res:
325 raise Exception("Unexpected result: " + res)
327 dev[0].request("BSS_FLUSH 1000")
328 res = dev[0].request("BSS RANGE=ALL MASK=0x1").splitlines()
330 raise Exception("Unexpected result after BSS_FLUSH 1000")
331 dev[0].request("BSS_FLUSH 0")
332 res = dev[0].request("BSS RANGE=ALL MASK=0x1").splitlines()
334 raise Exception("Unexpected result after BSS_FLUSH 0")
337 def test_scan_and_interface_disabled(dev, apdev):
338 """Scan operation when interface gets disabled"""
340 dev[0].request("SCAN")
341 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
343 raise Exception("Scan did not start")
344 dev[0].request("DRIVER_EVENT INTERFACE_DISABLED")
345 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=7)
347 raise Exception("Scan completed unexpectedly")
349 # verify that scan is rejected
350 if "FAIL" not in dev[0].request("SCAN"):
351 raise Exception("New scan request was accepted unexpectedly")
353 dev[0].request("DRIVER_EVENT INTERFACE_ENABLED")
354 dev[0].scan(freq="2412")
356 dev[0].request("DRIVER_EVENT INTERFACE_ENABLED")
359 def test_scan_for_auth(dev, apdev):
360 """cfg80211 workaround with scan-for-auth"""
361 hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
362 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
363 # Block sme-connect radio work with an external radio work item, so that
364 # SELECT_NETWORK can decide to use fast associate without a new scan while
365 # cfg80211 still has the matching BSS entry, but the actual connection is
367 id = dev[0].request("RADIO_WORK add block-work")
368 ev = dev[0].wait_event(["EXT-RADIO-WORK-START"])
370 raise Exception("Timeout while waiting radio work to start")
371 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
373 dev[0].dump_monitor()
374 # Clear cfg80211 BSS table.
375 res, data = dev[0].cmd_execute(['iw', dev[0].ifname, 'scan', 'trigger',
376 'freq', '2457', 'flush'])
378 raise HwsimSkip("iw scan trigger flush not supported")
379 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
381 raise Exception("External flush scan timed out")
382 # Release blocking radio work to allow connection to go through with the
383 # cfg80211 BSS entry missing.
384 dev[0].request("RADIO_WORK done " + id)
386 dev[0].wait_connected(timeout=15)
389 def test_scan_for_auth_fail(dev, apdev):
390 """cfg80211 workaround with scan-for-auth failing"""
391 hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
392 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
393 # Block sme-connect radio work with an external radio work item, so that
394 # SELECT_NETWORK can decide to use fast associate without a new scan while
395 # cfg80211 still has the matching BSS entry, but the actual connection is
397 id = dev[0].request("RADIO_WORK add block-work")
398 ev = dev[0].wait_event(["EXT-RADIO-WORK-START"])
400 raise Exception("Timeout while waiting radio work to start")
401 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
403 dev[0].dump_monitor()
405 # Clear cfg80211 BSS table.
406 res, data = dev[0].cmd_execute(['iw', dev[0].ifname, 'scan', 'trigger',
407 'freq', '2457', 'flush'])
409 raise HwsimSkip("iw scan trigger flush not supported")
410 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
412 raise Exception("External flush scan timed out")
413 # Release blocking radio work to allow connection to go through with the
414 # cfg80211 BSS entry missing.
415 dev[0].request("RADIO_WORK done " + id)
417 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS",
418 "CTRL-EVENT-CONNECTED"], 15)
420 raise Exception("Scan event missing")
421 if "CTRL-EVENT-CONNECTED" in ev:
422 raise Exception("Unexpected connection")
423 dev[0].request("DISCONNECT")
426 def test_scan_for_auth_wep(dev, apdev):
427 """cfg80211 scan-for-auth workaround with WEP keys"""
428 dev[0].flush_scan_cache()
429 hapd = hostapd.add_ap(apdev[0],
430 { "ssid": "wep", "wep_key0": '"abcde"',
432 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
433 # Block sme-connect radio work with an external radio work item, so that
434 # SELECT_NETWORK can decide to use fast associate without a new scan while
435 # cfg80211 still has the matching BSS entry, but the actual connection is
437 id = dev[0].request("RADIO_WORK add block-work")
438 ev = dev[0].wait_event(["EXT-RADIO-WORK-START"])
440 raise Exception("Timeout while waiting radio work to start")
441 dev[0].connect("wep", key_mgmt="NONE", wep_key0='"abcde"',
442 auth_alg="SHARED", scan_freq="2412", wait_connect=False)
443 dev[0].dump_monitor()
444 # Clear cfg80211 BSS table.
445 res, data = dev[0].cmd_execute(['iw', dev[0].ifname, 'scan', 'trigger',
446 'freq', '2457', 'flush'])
448 raise HwsimSkip("iw scan trigger flush not supported")
449 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
451 raise Exception("External flush scan timed out")
452 # Release blocking radio work to allow connection to go through with the
453 # cfg80211 BSS entry missing.
454 dev[0].request("RADIO_WORK done " + id)
456 dev[0].wait_connected(timeout=15)
459 def test_scan_hidden(dev, apdev):
460 """Control interface behavior on scan parameters"""
461 hapd = hostapd.add_ap(apdev[0], { "ssid": "test-scan",
462 "ignore_broadcast_ssid": "1" })
463 bssid = apdev[0]['bssid']
465 check_scan(dev[0], "freq=2412 use_id=1")
466 if "test-scan" in dev[0].request("SCAN_RESULTS"):
467 raise Exception("BSS unexpectedly found in initial scan")
469 id1 = dev[0].connect("foo", key_mgmt="NONE", scan_ssid="1",
470 only_add_network=True)
471 id2 = dev[0].connect("test-scan", key_mgmt="NONE", scan_ssid="1",
472 only_add_network=True)
473 id3 = dev[0].connect("bar", key_mgmt="NONE", only_add_network=True)
475 check_scan(dev[0], "freq=2412 use_id=1")
476 if "test-scan" in dev[0].request("SCAN_RESULTS"):
477 raise Exception("BSS unexpectedly found in scan")
479 # Allow multiple attempts to be more robust under heavy CPU load that can
480 # result in Probe Response frames getting sent only after the station has
481 # already stopped waiting for the response on the channel.
484 check_scan(dev[0], "scan_id=%d,%d,%d freq=2412 use_id=1" % (id1, id2, id3))
485 if "test-scan" in dev[0].request("SCAN_RESULTS"):
489 raise Exception("BSS not found in scan")
491 if "FAIL" not in dev[0].request("SCAN scan_id=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17"):
492 raise Exception("Too many scan_id values accepted")
494 # Duplicate SSID removal
495 check_scan(dev[0], "scan_id=%d,%d,%d freq=2412 use_id=1" % (id1, id1, id2))
497 dev[0].request("REMOVE_NETWORK all")
499 dev[0].flush_scan_cache(freq=2432)
500 dev[0].flush_scan_cache()
502 def test_scan_and_bss_entry_removed(dev, apdev):
503 """Last scan result and connect work processing on BSS entry update"""
504 hapd = hostapd.add_ap(apdev[0], { "ssid": "open",
507 bssid = apdev[0]['bssid']
509 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
510 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
513 dev[0].scan_for_bss(bssid, freq="2412")
514 wpas.scan_for_bss(bssid, freq="2412")
516 # Start a connect radio work with a blocking entry preventing this from
517 # proceeding; this stores a pointer to the selected BSS entry.
518 id = dev[0].request("RADIO_WORK add block-work")
519 w_id = wpas.request("RADIO_WORK add block-work")
520 dev[0].wait_event(["EXT-RADIO-WORK-START"], timeout=1)
521 wpas.wait_event(["EXT-RADIO-WORK-START"], timeout=1)
522 nid = dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
524 w_nid = wpas.connect("open", key_mgmt="NONE", scan_freq="2412",
528 # Remove the BSS entry
529 dev[0].request("BSS_FLUSH 0")
530 wpas.request("BSS_FLUSH 0")
532 # Allow the connect radio work to continue. The bss entry stored in the
533 # pending connect work is now stale. This will result in the connection
534 # attempt failing since the BSS entry does not exist.
535 dev[0].request("RADIO_WORK done " + id)
536 wpas.request("RADIO_WORK done " + w_id)
538 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
540 raise Exception("Unexpected connection")
541 dev[0].remove_network(nid)
542 ev = wpas.wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
544 raise Exception("Unexpected connection")
545 wpas.remove_network(w_nid)
547 dev[0].request("BSS_FLUSH 0")
548 wpas.request("BSS_FLUSH 0")
551 dev[0].scan_for_bss(bssid, freq="2412")
552 wpas.scan_for_bss(bssid, freq="2412")
554 # Start a connect radio work with a blocking entry preventing this from
555 # proceeding; this stores a pointer to the selected BSS entry.
556 id = dev[0].request("RADIO_WORK add block-work")
557 w_id = wpas.request("RADIO_WORK add block-work")
558 dev[0].wait_event(["EXT-RADIO-WORK-START"], timeout=1)
559 wpas.wait_event(["EXT-RADIO-WORK-START"], timeout=1)
561 # Schedule a connection based on the current BSS entry.
562 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
564 wpas.connect("open", key_mgmt="NONE", scan_freq="2412",
567 # Update scan results with results that have longer set of IEs so that new
568 # memory needs to be allocated for the BSS entry.
569 hapd.request("WPS_PBC")
571 subprocess.call(['iw', dev[0].ifname, 'scan', 'trigger', 'freq', '2412'])
572 subprocess.call(['iw', wpas.ifname, 'scan', 'trigger', 'freq', '2412'])
575 # Allow the connect radio work to continue. The bss entry stored in the
576 # pending connect work becomes stale during the scan and it must have been
577 # updated for the connection to work.
578 dev[0].request("RADIO_WORK done " + id)
579 wpas.request("RADIO_WORK done " + w_id)
581 dev[0].wait_connected(timeout=15, error="No connection (sme-connect)")
582 wpas.wait_connected(timeout=15, error="No connection (connect)")
583 dev[0].request("DISCONNECT")
584 wpas.request("DISCONNECT")
585 dev[0].flush_scan_cache()
586 wpas.flush_scan_cache()
589 def test_scan_reqs_with_non_scan_radio_work(dev, apdev):
590 """SCAN commands while non-scan radio_work is in progress"""
591 id = dev[0].request("RADIO_WORK add test-work-a")
592 ev = dev[0].wait_event(["EXT-RADIO-WORK-START"])
594 raise Exception("Timeout while waiting radio work to start")
596 if "OK" not in dev[0].request("SCAN"):
597 raise Exception("SCAN failed")
598 if "FAIL-BUSY" not in dev[0].request("SCAN"):
599 raise Exception("SCAN accepted while one is already pending")
600 if "FAIL-BUSY" not in dev[0].request("SCAN"):
601 raise Exception("SCAN accepted while one is already pending")
603 res = dev[0].request("RADIO_WORK show").splitlines()
610 raise Exception("Unexpected number of scan radio work items")
612 dev[0].dump_monitor()
613 dev[0].request("RADIO_WORK done " + id)
614 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=5)
616 raise Exception("Scan did not start")
617 if "FAIL-BUSY" not in dev[0].request("SCAN"):
618 raise Exception("SCAN accepted while one is already in progress")
620 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
622 print "Scan did not complete"
623 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.2)
625 raise Exception("Unexpected scan started")
627 def test_scan_setband(dev, apdev):
628 """Band selection for scan operations"""
632 params = { "ssid": "test-setband",
635 "country_code": "US" }
636 hapd = hostapd.add_ap(apdev[0], params)
637 bssid = apdev[0]['bssid']
639 params = { "ssid": "test-setband",
642 hapd2 = hostapd.add_ap(apdev[1], params)
643 bssid2 = apdev[1]['bssid']
645 if "FAIL" not in dev[0].request("SET setband FOO"):
646 raise Exception("Invalid set setband accepted")
647 if "OK" not in dev[0].request("SET setband AUTO"):
648 raise Exception("Failed to set setband")
649 if "OK" not in dev[1].request("SET setband 5G"):
650 raise Exception("Failed to set setband")
651 if "OK" not in dev[2].request("SET setband 2G"):
652 raise Exception("Failed to set setband")
654 # Allow a retry to avoid reporting errors during heavy load
657 dev[i].request("SCAN only_new=1")
660 ev = dev[i].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15)
662 raise Exception("Scan timed out")
664 res0 = dev[0].request("SCAN_RESULTS")
665 res1 = dev[1].request("SCAN_RESULTS")
666 res2 = dev[2].request("SCAN_RESULTS")
667 if bssid in res0 and bssid2 in res0 and bssid in res1 and bssid2 in res2:
670 res = dev[0].request("SCAN_RESULTS")
671 if bssid not in res or bssid2 not in res:
672 raise Exception("Missing scan result(0)")
674 res = dev[1].request("SCAN_RESULTS")
676 raise Exception("Missing scan result(1)")
678 raise Exception("Unexpected scan result(1)")
680 res = dev[2].request("SCAN_RESULTS")
681 if bssid2 not in res:
682 raise Exception("Missing scan result(2)")
684 raise Exception("Unexpected scan result(2)")
687 hapd.request("DISABLE")
689 hapd2.request("DISABLE")
690 subprocess.call(['iw', 'reg', 'set', '00'])
692 dev[i].request("SET setband AUTO")
693 dev[i].flush_scan_cache()
696 def test_scan_hidden_many(dev, apdev):
697 """scan_ssid=1 with large number of profile with hidden SSID"""
699 _test_scan_hidden_many(dev, apdev)
701 dev[0].flush_scan_cache(freq=2432)
702 dev[0].flush_scan_cache()
703 dev[0].request("SCAN_INTERVAL 5")
705 def _test_scan_hidden_many(dev, apdev):
706 hapd = hostapd.add_ap(apdev[0], { "ssid": "test-scan-ssid",
707 "ignore_broadcast_ssid": "1" })
708 bssid = apdev[0]['bssid']
710 dev[0].request("SCAN_INTERVAL 1")
713 id = dev[0].add_network()
714 dev[0].set_network_quoted(id, "ssid", "foo")
715 dev[0].set_network(id, "key_mgmt", "NONE")
716 dev[0].set_network(id, "disabled", "0")
717 dev[0].set_network(id, "scan_freq", "2412")
718 dev[0].set_network(id, "scan_ssid", "1")
720 dev[0].set_network_quoted(id, "ssid", "test-scan-ssid")
721 dev[0].set_network(id, "key_mgmt", "NONE")
722 dev[0].set_network(id, "disabled", "0")
723 dev[0].set_network(id, "scan_freq", "2412")
724 dev[0].set_network(id, "scan_ssid", "1")
727 id = dev[0].add_network()
728 dev[0].set_network_quoted(id, "ssid", "foo")
729 dev[0].set_network(id, "key_mgmt", "NONE")
730 dev[0].set_network(id, "disabled", "0")
731 dev[0].set_network(id, "scan_freq", "2412")
732 dev[0].set_network(id, "scan_ssid", "1")
734 dev[0].request("REASSOCIATE")
735 dev[0].wait_connected(timeout=30)
736 dev[0].request("REMOVE_NETWORK all")
739 def test_scan_random_mac(dev, apdev, params):
740 """Random MAC address in scans"""
742 _test_scan_random_mac(dev, apdev, params)
744 dev[0].request("MAC_RAND_SCAN all enable=0")
746 def _test_scan_random_mac(dev, apdev, params):
747 hostapd.add_ap(apdev[0], { "ssid": "test-scan" })
748 bssid = apdev[0]['bssid']
754 "all enable=1 mask=00:11:22:33:44:55",
755 "all enable=1 addr=00:11:22:33:44:55",
756 "all enable=1 addr=01:11:22:33:44:55 mask=ff:ff:ff:ff:ff:ff",
757 "all enable=1 addr=00:11:22:33:44:55 mask=fe:ff:ff:ff:ff:ff",
758 "enable=2 scan sched pno all",
763 if "FAIL" not in dev[0].request("MAC_RAND_SCAN " + args):
764 raise Exception("Invalid MAC_RAND_SCAN accepted: " + args)
766 if dev[0].get_driver_status_field('capa.mac_addr_rand_scan_supported') != '1':
767 raise HwsimSkip("Driver does not support random MAC address for scanning")
769 tests = [ "all enable=1",
770 "all enable=1 addr=f2:11:22:33:44:55 mask=ff:ff:ff:ff:ff:ff",
771 "all enable=1 addr=f2:11:33:00:00:00 mask=ff:ff:ff:00:00:00" ]
773 dev[0].request("MAC_RAND_SCAN " + args)
774 dev[0].scan_for_bss(bssid, freq=2412, force_scan=True)
776 out = run_tshark(os.path.join(params['logdir'], "hwsim0.pcapng"),
777 "wlan.fc.type_subtype == 4", ["wlan.ta" ])
779 addr = out.splitlines()
780 logger.info("Probe Request frames seen from: " + str(addr))
781 if dev[0].own_addr() in addr:
782 raise Exception("Real address used to transmit Probe Request frame")
783 if "f2:11:22:33:44:55" not in addr:
784 raise Exception("Fully configured random address not seen")
787 if a.startswith('f2:11:33'):
791 raise Exception("Fixed OUI random address not seen")
794 def test_scan_trigger_failure(dev, apdev):
795 """Scan trigger to the driver failing"""
796 hostapd.add_ap(apdev[0], { "ssid": "test-scan" })
797 bssid = apdev[0]['bssid']
799 if "OK" not in dev[0].request("SET test_failure 1"):
800 raise Exception("Failed to set test_failure")
802 if "OK" not in dev[0].request("SCAN"):
803 raise Exception("SCAN command failed")
804 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED"], timeout=10)
806 raise Exception("Did not receive CTRL-EVENT-SCAN-FAILED event")
808 raise Exception("Unexpected scan retry indicated")
809 if dev[0].get_status_field('wpa_state') == "SCANNING":
810 raise Exception("wpa_state SCANNING not cleared")
812 id = dev[0].connect("test-scan", key_mgmt="NONE", scan_freq="2412",
813 only_add_network=True)
814 dev[0].select_network(id)
815 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED"], timeout=10)
817 raise Exception("Did not receive CTRL-EVENT-SCAN-FAILED event")
818 if "retry=1" not in ev:
819 raise Exception("No scan retry indicated for connection")
820 if dev[0].get_status_field('wpa_state') == "SCANNING":
821 raise Exception("wpa_state SCANNING not cleared")
822 dev[0].request("SET test_failure 0")
823 dev[0].wait_connected()
825 dev[0].request("SET test_failure 1")
826 if "OK" not in dev[0].request("SCAN"):
827 raise Exception("SCAN command failed")
828 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED"], timeout=10)
830 raise Exception("Did not receive CTRL-EVENT-SCAN-FAILED event")
832 raise Exception("Unexpected scan retry indicated")
833 if dev[0].get_status_field('wpa_state') != "COMPLETED":
834 raise Exception("wpa_state COMPLETED not restored")
835 dev[0].request("SET test_failure 0")
838 def test_scan_specify_ssid(dev, apdev):
839 """Control interface behavior on scan SSID parameter"""
840 dev[0].flush_scan_cache()
841 hapd = hostapd.add_ap(apdev[0], { "ssid": "test-hidden",
842 "ignore_broadcast_ssid": "1" })
843 bssid = apdev[0]['bssid']
844 check_scan(dev[0], "freq=2412 use_id=1 ssid 414243")
845 bss = dev[0].get_bss(bssid)
846 if bss is not None and bss['ssid'] == 'test-hidden':
847 raise Exception("BSS entry for hidden AP present unexpectedly")
848 # Allow couple more retries to avoid reporting errors during heavy load
850 check_scan(dev[0], "freq=2412 ssid 414243 ssid 746573742d68696464656e ssid 616263313233 use_id=1")
851 bss = dev[0].get_bss(bssid)
852 if bss and 'test-hidden' in dev[0].request("SCAN_RESULTS"):
855 raise Exception("BSS entry for hidden AP not found")
856 if 'test-hidden' not in dev[0].request("SCAN_RESULTS"):
857 raise Exception("Expected SSID not included in the scan results")
860 dev[0].flush_scan_cache(freq=2432)
861 dev[0].flush_scan_cache()
863 if "FAIL" not in dev[0].request("SCAN ssid foo"):
864 raise Exception("Invalid SCAN command accepted")
867 def test_scan_ap_scan_2_ap_mode(dev, apdev):
868 """AP_SCAN 2 AP mode and scan()"""
870 _test_scan_ap_scan_2_ap_mode(dev, apdev)
872 dev[0].request("AP_SCAN 1")
874 def _test_scan_ap_scan_2_ap_mode(dev, apdev):
875 if "OK" not in dev[0].request("AP_SCAN 2"):
876 raise Exception("Failed to set AP_SCAN 2")
878 id = dev[0].add_network()
879 dev[0].set_network(id, "mode", "2")
880 dev[0].set_network_quoted(id, "ssid", "wpas-ap-open")
881 dev[0].set_network(id, "key_mgmt", "NONE")
882 dev[0].set_network(id, "frequency", "2412")
883 dev[0].set_network(id, "scan_freq", "2412")
884 dev[0].set_network(id, "disabled", "0")
885 dev[0].select_network(id)
886 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=5)
888 raise Exception("AP failed to start")
890 with fail_test(dev[0], 1, "wpa_driver_nl80211_scan"):
891 if "OK" not in dev[0].request("SCAN freq=2412"):
892 raise Exception("SCAN command failed unexpectedly")
893 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED",
894 "AP-DISABLED"], timeout=5)
896 raise Exception("CTRL-EVENT-SCAN-FAILED not seen")
897 if "AP-DISABLED" in ev:
898 raise Exception("Unexpected AP-DISABLED event")
900 # Wait for the retry to scan happen
901 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED",
902 "AP-DISABLED"], timeout=5)
904 raise Exception("CTRL-EVENT-SCAN-FAILED not seen - retry")
905 if "AP-DISABLED" in ev:
906 raise Exception("Unexpected AP-DISABLED event - retry")
908 dev[1].connect("wpas-ap-open", key_mgmt="NONE", scan_freq="2412")
909 dev[1].request("DISCONNECT")
910 dev[1].wait_disconnected()
911 dev[0].request("DISCONNECT")
912 dev[0].wait_disconnected()
914 def test_scan_bss_expiration_on_ssid_change(dev, apdev):
915 """BSS entry expiration when AP changes SSID"""
916 dev[0].flush_scan_cache()
917 hapd = hostapd.add_ap(apdev[0], { "ssid": "test-scan" })
918 bssid = apdev[0]['bssid']
919 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
921 hapd.request("DISABLE")
922 hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
923 if "OK" not in dev[0].request("BSS_EXPIRE_COUNT 3"):
924 raise Exception("BSS_EXPIRE_COUNT failed")
925 dev[0].scan(freq="2412")
926 dev[0].scan(freq="2412")
927 if "OK" not in dev[0].request("BSS_EXPIRE_COUNT 2"):
928 raise Exception("BSS_EXPIRE_COUNT failed")
929 res = dev[0].request("SCAN_RESULTS")
930 if "test-scan" not in res:
931 raise Exception("The first SSID not in scan results")
932 if "open" not in res:
933 raise Exception("The second SSID not in scan results")
934 dev[0].connect("open", key_mgmt="NONE")
936 dev[0].request("BSS_FLUSH 0")
937 res = dev[0].request("SCAN_RESULTS")
938 if "test-scan" in res:
939 raise Exception("The BSS entry with the old SSID was not removed")
940 dev[0].request("DISCONNECT")
941 dev[0].wait_disconnected()
943 def test_scan_dfs(dev, apdev, params):
944 """Scan on DFS channels"""
946 _test_scan_dfs(dev, apdev, params)
948 subprocess.call(['iw', 'reg', 'set', '00'])
950 def _test_scan_dfs(dev, apdev, params):
951 subprocess.call(['iw', 'reg', 'set', 'US'])
954 ev = dev[i].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=5)
956 raise Exception("No regdom change event")
957 if "alpha2=US" in ev:
959 dev[i].dump_monitor()
961 if "OK" not in dev[0].request("SCAN"):
962 raise Exception("SCAN command failed")
963 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
965 raise Exception("Scan did not complete")
967 if "OK" not in dev[0].request("SCAN freq=2412,5180,5260,5500,5600,5745"):
968 raise Exception("SCAN command failed")
969 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
971 raise Exception("Scan did not complete")
973 out = run_tshark(os.path.join(params['logdir'], "hwsim0.pcapng"),
974 "wlan.fc.type_subtype == 4", [ "radiotap.channel.freq" ])
976 freq = out.splitlines()
977 freq = [int(f) for f in freq]
978 freq = list(set(freq))
980 logger.info("Active scan seen on channels: " + str(freq))
982 if (f >= 5260 and f <= 5320) or (f >= 5500 and f <= 5700):
983 raise Exception("Active scan on DFS channel: %d" % f)
984 if f in [ 2467, 2472 ]:
985 raise Exception("Active scan on US-disallowed channel: %d" % f)
988 def test_scan_abort(dev, apdev):
989 """Aborting a full scan"""
990 dev[0].request("SCAN")
991 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
993 raise Exception("Scan did not start")
994 if "OK" not in dev[0].request("ABORT_SCAN"):
995 raise Exception("ABORT_SCAN command failed")
996 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=2)
998 raise Exception("Scan did not terminate")
1001 def test_scan_abort_on_connect(dev, apdev):
1002 """Aborting a full scan on connection request"""
1003 hostapd.add_ap(apdev[0], { "ssid": "test-scan" })
1004 bssid = apdev[0]['bssid']
1006 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1007 dev[0].dump_monitor()
1008 dev[0].request("SCAN")
1009 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
1011 raise Exception("Scan did not start")
1012 dev[0].connect("test-scan", key_mgmt="NONE")
1015 def test_scan_ext(dev, apdev):
1016 """Custom IE in Probe Request frame"""
1017 hostapd.add_ap(apdev[0], { "ssid": "test-scan" })
1018 bssid = apdev[0]['bssid']
1021 if "OK" not in dev[0].request("VENDOR_ELEM_ADD 14 dd050011223300"):
1022 raise Exception("VENDOR_ELEM_ADD failed")
1023 check_scan(dev[0], "freq=2412 use_id=1")
1025 dev[0].request("VENDOR_ELEM_REMOVE 14 *")
1027 def test_scan_fail(dev, apdev):
1029 with fail_test(dev[0], 1, "wpa_driver_nl80211_scan"):
1030 dev[0].request("DISCONNECT")
1031 if "OK" not in dev[0].request("SCAN freq=2412"):
1032 raise Exception("SCAN failed")
1033 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED"], timeout=5)
1035 raise Exception("Did not see scan failure event")
1036 dev[0].dump_monitor()
1038 for i in range(1, 5):
1039 with alloc_fail(dev[0], i,
1040 "wpa_scan_clone_params;wpa_supplicant_trigger_scan"):
1041 if "OK" not in dev[0].request("SCAN ssid 112233 freq=2412"):
1042 raise Exception("SCAN failed")
1043 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED"], timeout=5)
1045 raise Exception("Did not see scan failure event")
1046 dev[0].dump_monitor()
1048 with alloc_fail(dev[0], 1, "radio_add_work;wpa_supplicant_trigger_scan"):
1049 if "OK" not in dev[0].request("SCAN freq=2412"):
1050 raise Exception("SCAN failed")
1051 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED"], timeout=5)
1053 raise Exception("Did not see scan failure event")
1054 dev[0].dump_monitor()
1057 if "OK" not in dev[0].request("SET filter_ssids 1"):
1058 raise Exception("SET failed")
1059 id = dev[0].connect("test-scan", key_mgmt="NONE", only_add_network=True)
1060 with alloc_fail(dev[0], 1, "wpa_supplicant_build_filter_ssids"):
1061 # While the filter list cannot be created due to memory allocation
1062 # failure, this scan is expected to be completed without SSID
1064 if "OK" not in dev[0].request("SCAN freq=2412"):
1065 raise Exception("SCAN failed")
1066 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
1068 raise Exception("Scan did not complete")
1069 dev[0].remove_network(id)
1071 dev[0].request("SET filter_ssids 0")
1072 dev[0].dump_monitor()
1074 with alloc_fail(dev[0], 1, "nl80211_get_scan_results"):
1075 if "OK" not in dev[0].request("SCAN freq=2412"):
1076 raise Exception("SCAN failed")
1077 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=5)
1079 raise Exception("Did not see scan started event")
1080 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1081 dev[0].dump_monitor()
1084 if "OK" not in dev[0].request("SET setband 2G"):
1085 raise Exception("SET setband failed")
1086 with alloc_fail(dev[0], 1, "=wpa_setband_scan_freqs_list"):
1087 # While the frequency list cannot be created due to memory
1088 # allocation failure, this scan is expected to be completed without
1089 # frequency filtering.
1090 if "OK" not in dev[0].request("SCAN"):
1091 raise Exception("SCAN failed")
1092 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1093 dev[0].request("ABORT_SCAN")
1094 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
1096 raise Exception("Scan did not complete")
1098 dev[0].request("SET setband AUTO")
1099 dev[0].dump_monitor()
1101 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1102 wpas.interface_add("wlan5")
1103 wpas.request("SET preassoc_mac_addr 1")
1104 with fail_test(wpas, 1, "nl80211_set_mac_addr;wpas_trigger_scan_cb"):
1105 if "OK" not in wpas.request("SCAN freq=2412"):
1106 raise Exception("SCAN failed")
1107 ev = wpas.wait_event(["CTRL-EVENT-SCAN-FAILED"], timeout=5)
1109 raise Exception("Did not see scan failure event")
1110 wpas.request("SET preassoc_mac_addr 0")
1113 hapd = hostapd.add_ap(apdev[0], { "ssid": "open" })
1114 with alloc_fail(dev[0], 1, "wpa_bss_add"):
1115 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1118 def test_scan_freq_list(dev, apdev):
1119 """Scan with SET freq_list and scan_cur_freq"""
1121 if "OK" not in dev[0].request("SET freq_list 2412 2417"):
1122 raise Exception("SET freq_list failed")
1123 check_scan(dev[0], "use_id=1")
1125 dev[0].request("SET freq_list ")
1127 hapd = hostapd.add_ap(apdev[0], { "ssid": "test-scan" })
1128 dev[0].connect("test-scan", key_mgmt="NONE", scan_freq="2412")
1130 if "OK" not in dev[0].request("SET scan_cur_freq 1"):
1131 raise Exception("SET scan_cur_freq failed")
1132 check_scan(dev[0], "use_id=1")
1134 dev[0].request("SET scan_cur_freq 0")
1135 dev[0].request("REMOVE_NETWORK all")
1136 dev[0].wait_disconnected()
1138 def test_scan_bss_limit(dev, apdev):
1139 """Scan and wpa_supplicant BSS entry limit"""
1141 _test_scan_bss_limit(dev, apdev)
1143 dev[0].request("SET bss_max_count 200")
1146 def _test_scan_bss_limit(dev, apdev):
1147 # Trigger 'Increasing the MAX BSS count to 2 because all BSSes are in use.
1148 # We should normally not get here!' message by limiting the maximum BSS
1149 # count to one so that the second AP would not fit in the BSS list and the
1150 # first AP cannot be removed from the list since it is still in use.
1151 dev[0].request("SET bss_max_count 1")
1152 hapd = hostapd.add_ap(apdev[0], { "ssid": "test-scan" })
1153 dev[0].connect("test-scan", key_mgmt="NONE", scan_freq="2412")
1154 hapd2 = hostapd.add_ap(apdev[1], { "ssid": "test-scan-2",
1156 dev[0].scan_for_bss(apdev[1]['bssid'], freq=2437, force_scan=True)