Updated through tag hostap_2_5 from git://w1.fi/hostap.git
[mech_eap.git] / libeap / tests / hwsim / test_p2p_discovery.py
1 # P2P device discovery test cases
2 # Copyright (c) 2013, Jouni Malinen <j@w1.fi>
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 import logging
8 logger = logging.getLogger()
9 import time
10
11 import hwsim_utils
12 from wpasupplicant import WpaSupplicant
13
14 def test_discovery(dev):
15     """P2P device discovery and provision discovery"""
16     addr0 = dev[0].p2p_dev_addr()
17     addr1 = dev[1].p2p_dev_addr()
18     logger.info("Start device discovery")
19     dev[0].p2p_find(social=True, delay=1)
20     if not dev[1].discover_peer(addr0):
21         raise Exception("Device discovery timed out")
22     if not dev[0].discover_peer(addr1):
23         raise Exception("Device discovery timed out")
24
25     logger.info("Test provision discovery for display")
26     dev[0].global_request("P2P_PROV_DISC " + addr1 + " display")
27     ev1 = dev[1].wait_global_event(["P2P-PROV-DISC-SHOW-PIN"], timeout=15)
28     if ev1 is None:
29         raise Exception("Provision discovery timed out (display/dev1)")
30     if addr0 not in ev1:
31         raise Exception("Dev0 not in provision discovery event")
32     ev0 = dev[0].wait_global_event(["P2P-PROV-DISC-ENTER-PIN",
33                                     "P2P-PROV-DISC-FAILURE"], timeout=15)
34     if ev0 is None:
35         raise Exception("Provision discovery timed out (display/dev0)")
36     if "P2P-PROV-DISC-FAILURE" in ev0:
37         raise Exception("Provision discovery failed (display/dev0)")
38     if addr1 not in ev0:
39         raise Exception("Dev1 not in provision discovery event")
40
41     logger.info("Test provision discovery for keypad")
42     dev[0].global_request("P2P_PROV_DISC " + addr1 + " keypad")
43     ev1 = dev[1].wait_global_event(["P2P-PROV-DISC-ENTER-PIN"], timeout=15)
44     if ev1 is None:
45         raise Exception("Provision discovery timed out (keypad/dev1)")
46     if addr0 not in ev1:
47         raise Exception("Dev0 not in provision discovery event")
48     ev0 = dev[0].wait_global_event(["P2P-PROV-DISC-SHOW-PIN",
49                                     "P2P-PROV-DISC-FAILURE"],
50                                    timeout=15)
51     if ev0 is None:
52         raise Exception("Provision discovery timed out (keypad/dev0)")
53     if "P2P-PROV-DISC-FAILURE" in ev0:
54         raise Exception("Provision discovery failed (keypad/dev0)")
55     if addr1 not in ev0:
56         raise Exception("Dev1 not in provision discovery event")
57
58     logger.info("Test provision discovery for push button")
59     dev[0].global_request("P2P_PROV_DISC " + addr1 + " pbc")
60     ev1 = dev[1].wait_global_event(["P2P-PROV-DISC-PBC-REQ"], timeout=15)
61     if ev1 is None:
62         raise Exception("Provision discovery timed out (pbc/dev1)")
63     if addr0 not in ev1:
64         raise Exception("Dev0 not in provision discovery event")
65     ev0 = dev[0].wait_global_event(["P2P-PROV-DISC-PBC-RESP",
66                                     "P2P-PROV-DISC-FAILURE"],
67                                    timeout=15)
68     if ev0 is None:
69         raise Exception("Provision discovery timed out (pbc/dev0)")
70     if "P2P-PROV-DISC-FAILURE" in ev0:
71         raise Exception("Provision discovery failed (pbc/dev0)")
72     if addr1 not in ev0:
73         raise Exception("Dev1 not in provision discovery event")
74
75     dev[0].p2p_stop_find
76     dev[1].p2p_stop_find
77
78     if "FAIL" not in dev[0].p2p_find(dev_id="foo"):
79         raise Exception("P2P_FIND with invalid dev_id accepted")
80     if "FAIL" not in dev[0].p2p_find(dev_type="foo"):
81         raise Exception("P2P_FIND with invalid dev_type accepted")
82     if "FAIL" not in dev[0].p2p_find(dev_type="1-foo-2"):
83         raise Exception("P2P_FIND with invalid dev_type accepted")
84     if "FAIL" not in dev[0].p2p_find(dev_type="1-11223344"):
85         raise Exception("P2P_FIND with invalid dev_type accepted")
86
87     if "FAIL" not in dev[0].global_request("P2P_PROV_DISC foo pbc"):
88         raise Exception("Invalid P2P_PROV_DISC accepted")
89     if "FAIL" not in dev[0].global_request("P2P_PROV_DISC 00:11:22:33:44:55"):
90         raise Exception("Invalid P2P_PROV_DISC accepted")
91     if "FAIL" not in dev[0].global_request("P2P_PROV_DISC 00:11:22:33:44:55 pbc join"):
92         raise Exception("Invalid P2P_PROV_DISC accepted")
93     if "FAIL" not in dev[0].global_request("P2P_PROV_DISC 00:11:22:33:44:55 foo"):
94         raise Exception("Invalid P2P_PROV_DISC accepted")
95
96 def test_discovery_pd_retries(dev):
97     """P2P device discovery and provision discovery retries"""
98     addr0 = dev[0].p2p_dev_addr()
99     addr1 = dev[1].p2p_dev_addr()
100     dev[1].p2p_listen()
101     if not dev[0].discover_peer(addr1):
102         raise Exception("Device discovery timed out")
103     dev[1].p2p_stop_find()
104     dev[0].p2p_stop_find()
105     dev[0].global_request("P2P_PROV_DISC " + addr1 + " display")
106     ev = dev[0].wait_global_event(["P2P-PROV-DISC-FAILURE"], timeout=60)
107     if ev is None:
108         raise Exception("No PD failure reported")
109
110 def test_discovery_group_client(dev):
111     """P2P device discovery for a client in a group"""
112     logger.info("Start autonomous GO " + dev[0].ifname)
113     res = dev[0].p2p_start_go(freq="2422")
114     logger.debug("res: " + str(res))
115     logger.info("Connect a client to the GO")
116     pin = dev[1].wps_read_pin()
117     dev[0].p2p_go_authorize_client(pin)
118     dev[1].p2p_connect_group(dev[0].p2p_dev_addr(), pin, timeout=60)
119     logger.info("Client connected")
120     hwsim_utils.test_connectivity_p2p(dev[0], dev[1])
121     logger.info("Try to discover a P2P client in a group")
122     if not dev[2].discover_peer(dev[1].p2p_dev_addr(), social=False, timeout=10):
123         if not dev[2].discover_peer(dev[1].p2p_dev_addr(), social=False, timeout=10):
124             if not dev[2].discover_peer(dev[1].p2p_dev_addr(), social=False, timeout=10):
125                 raise Exception("Could not discover group client")
126
127     # This is not really perfect, but something to get a bit more testing
128     # coverage.. For proper discoverability mechanism validation, the P2P
129     # client would need to go to sleep to avoid acknowledging the GO Negotiation
130     # Request frame. Offchannel Listen mode operation on the P2P Client with
131     # mac80211_hwsim is apparently not enough to avoid the acknowledgement on
132     # the operating channel, so need to disconnect from the group which removes
133     # the GO-to-P2P Client part of the discoverability exchange in practice.
134
135     pin = dev[2].wps_read_pin()
136     # make group client non-responsive on operating channel
137     dev[1].dump_monitor()
138     dev[1].group_request("DISCONNECT")
139     ev = dev[1].wait_group_event(["CTRL-EVENT-DISCONNECTED"], timeout=10)
140     if ev is None:
141         raise Exception("Timeout on waiting disconnection")
142     dev[2].request("P2P_CONNECT {} {} display".format(dev[1].p2p_dev_addr(),
143                                                       pin))
144     ev = dev[1].wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=2)
145     if ev:
146         raise Exception("Unexpected frame RX on P2P client")
147     # make group client available on operating channe
148     dev[1].group_request("REASSOCIATE")
149     ev = dev[1].wait_global_event(["CTRL-EVENT-CONNECTED",
150                                    "P2P-GO-NEG-REQUEST"], timeout=10)
151     if ev is None:
152         raise Exception("Timeout on reconnection to group")
153     if "P2P-GO-NEG-REQUEST" not in ev:
154         ev = dev[1].wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=10)
155         if ev is None:
156             raise Exception("Timeout on waiting for GO Negotiation Request")
157
158 def test_discovery_dev_type(dev):
159     """P2P device discovery with Device Type filter"""
160     dev[1].request("SET sec_device_type 1-0050F204-2")
161     dev[1].p2p_listen()
162     dev[0].p2p_find(social=True, dev_type="5-0050F204-1")
163     ev = dev[0].wait_global_event(['P2P-DEVICE-FOUND'], timeout=1)
164     if ev:
165         raise Exception("Unexpected P2P device found")
166     dev[0].p2p_find(social=True, dev_type="1-0050F204-2")
167     ev = dev[0].wait_global_event(['P2P-DEVICE-FOUND'], timeout=2)
168     if ev is None:
169         raise Exception("P2P device not found")
170     peer = dev[0].get_peer(dev[1].p2p_dev_addr())
171     if "1-0050F204-2" not in peer['sec_dev_type']:
172         raise Exception("sec_device_type not reported properly")
173
174 def test_discovery_dev_type_go(dev):
175     """P2P device discovery with Device Type filter on GO"""
176     addr1 = dev[1].p2p_dev_addr()
177     dev[1].request("SET sec_device_type 1-0050F204-2")
178     res = dev[0].p2p_start_go(freq="2412")
179     pin = dev[1].wps_read_pin()
180     dev[0].p2p_go_authorize_client(pin)
181     dev[1].p2p_connect_group(dev[0].p2p_dev_addr(), pin, timeout=60)
182
183     dev[2].p2p_find(social=True, dev_type="5-0050F204-1")
184     ev = dev[2].wait_global_event(['P2P-DEVICE-FOUND'], timeout=1)
185     if ev:
186         raise Exception("Unexpected P2P device found")
187     dev[2].p2p_find(social=True, dev_type="1-0050F204-2")
188     ev = dev[2].wait_global_event(['P2P-DEVICE-FOUND ' + addr1], timeout=2)
189     if ev is None:
190         raise Exception("P2P device not found")
191
192 def test_discovery_dev_id(dev):
193     """P2P device discovery with Device ID filter"""
194     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
195     wpas.interface_add("wlan5")
196     wpas.request("P2P_LISTEN 1")
197     status = wpas.global_request("STATUS")
198     if "p2p_state=LISTEN_ONLY" not in status:
199         raise Exception("Unexpected status: " + status)
200     addr1 = dev[1].p2p_dev_addr()
201     dev[1].p2p_listen()
202     dev[0].p2p_find(social=True, dev_id="02:03:04:05:06:07")
203     ev = dev[0].wait_global_event(['P2P-DEVICE-FOUND'], timeout=1)
204     if ev:
205         raise Exception("Unexpected P2P device found")
206     dev[0].p2p_find(social=True, dev_id=addr1)
207     ev = dev[0].wait_global_event(['P2P-DEVICE-FOUND'], timeout=5)
208     if ev is None:
209         raise Exception("P2P device not found")
210     if addr1 not in ev:
211         raise Exception("Unexpected P2P peer found")
212     status = wpas.global_request("STATUS")
213     for i in range(0, 2):
214         if "p2p_state=IDLE" in status:
215             break
216         time.sleep(0.5)
217         status = wpas.global_request("STATUS")
218     if "p2p_state=IDLE" not in status:
219         raise Exception("Unexpected status: " + status)
220
221 def test_discovery_dev_id_go(dev):
222     """P2P device discovery with Device ID filter on GO"""
223     addr1 = dev[1].p2p_dev_addr()
224     res = dev[0].p2p_start_go(freq="2412")
225     pin = dev[1].wps_read_pin()
226     dev[0].p2p_go_authorize_client(pin)
227     dev[1].p2p_connect_group(dev[0].p2p_dev_addr(), pin, timeout=60)
228
229     dev[2].p2p_find(social=True, dev_id="02:03:04:05:06:07")
230     ev = dev[2].wait_global_event(['P2P-DEVICE-FOUND'], timeout=1)
231     if ev:
232         raise Exception("Unexpected P2P device found")
233     dev[2].p2p_find(social=True, dev_id=addr1)
234     ev = dev[2].wait_global_event(['P2P-DEVICE-FOUND ' + addr1], timeout=2)
235     if ev is None:
236         raise Exception("P2P device not found")
237
238 def test_discovery_social_plus_one(dev):
239     """P2P device discovery with social-plus-one"""
240     logger.info("Start autonomous GO " + dev[0].ifname)
241     dev[1].p2p_find(social=True)
242     dev[0].p2p_find(progressive=True)
243     logger.info("Wait for initial progressive find phases")
244     dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
245     dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
246     go = dev[2].p2p_dev_addr()
247     dev[2].p2p_start_go(freq="2422")
248     logger.info("Verify whether the GO on non-social channel can be found")
249     ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=15)
250     if ev is None:
251         raise Exception("Peer not found")
252     if go not in ev:
253         ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=15)
254         if ev is None:
255             raise Exception("Peer not found")
256     ev = dev[1].wait_global_event(["P2P-DEVICE-FOUND"], timeout=15)
257     if ev is None:
258         raise Exception("Peer not found")
259     dev[0].p2p_stop_find()
260     dev[1].p2p_stop_find()
261     if not dev[0].peer_known(go):
262         raise Exception("GO not found in progressive scan")
263     if dev[1].peer_known(go):
264         raise Exception("GO found in social-only scan")
265
266 def test_discovery_and_interface_disabled(dev):
267     """P2P device discovery with interface getting didabled"""
268     try:
269         if "OK" not in dev[0].p2p_find():
270             raise Exception("Failed to start P2P find")
271         ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
272         if ev is None:
273             raise Exception("Scan did not start")
274         dev[0].request("DRIVER_EVENT INTERFACE_DISABLED")
275         time.sleep(1)
276
277         # verify that P2P_FIND is rejected
278         if "FAIL" not in dev[0].p2p_find():
279             raise Exception("New P2P_FIND request was accepted unexpectedly")
280
281         dev[0].request("DRIVER_EVENT INTERFACE_ENABLED")
282         time.sleep(3)
283         dev[0].scan(freq="2412")
284         if "OK" not in dev[0].p2p_find():
285             raise Exception("Failed to start P2P find")
286         dev[0].dump_monitor()
287         dev[1].p2p_listen()
288         ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=15)
289         if ev is None:
290             raise Exception("Peer not found")
291     finally:
292         dev[0].request("DRIVER_EVENT INTERFACE_ENABLED")
293
294 def test_discovery_auto(dev):
295     """P2P device discovery and provision discovery with auto GO/dev selection"""
296     dev[0].flush_scan_cache()
297     addr0 = dev[0].p2p_dev_addr()
298     addr1 = dev[1].p2p_dev_addr()
299     addr2 = dev[2].p2p_dev_addr()
300     dev[2].p2p_start_go(freq="2412")
301     logger.info("Start device discovery")
302     dev[0].p2p_listen()
303     if not dev[1].discover_peer(addr0):
304         raise Exception("Device discovery timed out")
305     dev[1].p2p_listen()
306     if not dev[0].discover_peer(addr1):
307         raise Exception("Device discovery timed out")
308     if not dev[0].discover_peer(addr2):
309         raise Exception("Device discovery timed out")
310
311     logger.info("Test provision discovery for display (device)")
312     dev[0].global_request("P2P_PROV_DISC " + addr1 + " display auto")
313     ev1 = dev[1].wait_global_event(["P2P-PROV-DISC-SHOW-PIN"], timeout=15)
314     if ev1 is None:
315         raise Exception("Provision discovery timed out (display/dev1)")
316     if addr0 not in ev1:
317         raise Exception("Dev0 not in provision discovery event")
318     if " group=" in ev1:
319         raise Exception("Unexpected group parameter from non-GO")
320     ev0 = dev[0].wait_global_event(["P2P-PROV-DISC-ENTER-PIN",
321                                     "P2P-PROV-DISC-FAILURE"], timeout=15)
322     if ev0 is None:
323         raise Exception("Provision discovery timed out (display/dev0)")
324     if "P2P-PROV-DISC-FAILURE" in ev0:
325         raise Exception("Provision discovery failed (display/dev0)")
326     if addr1 not in ev0:
327         raise Exception("Dev1 not in provision discovery event")
328     if "peer_go=0" not in ev0:
329         raise Exception("peer_go incorrect in PD response from non-GO")
330
331     logger.info("Test provision discovery for display (GO)")
332     dev[0].global_request("P2P_PROV_DISC " + addr2 + " display auto")
333     ev2 = dev[2].wait_global_event(["P2P-PROV-DISC-SHOW-PIN"], timeout=15)
334     if ev2 is None:
335         raise Exception("Provision discovery timed out (display/dev2)")
336     if addr0 not in ev2:
337         raise Exception("Dev0 not in provision discovery event")
338     if " group=" not in ev2:
339         raise Exception("Group parameter missing from GO")
340     ev0 = dev[0].wait_global_event(["P2P-PROV-DISC-ENTER-PIN",
341                                     "P2P-PROV-DISC-FAILURE"], timeout=15)
342     if ev0 is None:
343         raise Exception("Provision discovery timed out (display/dev0)")
344     if "P2P-PROV-DISC-FAILURE" in ev0:
345         raise Exception("Provision discovery failed (display/dev0)")
346     if addr2 not in ev0:
347         raise Exception("Dev1 not in provision discovery event")
348     if "peer_go=1" not in ev0:
349         raise Exception("peer_go incorrect in PD response from GO")
350
351 def test_discovery_stop(dev):
352     """P2P device discovery and p2p_stop_find"""
353     addr0 = dev[0].p2p_dev_addr()
354     addr1 = dev[1].p2p_dev_addr()
355     dev[1].p2p_listen()
356     dev[2].p2p_listen()
357
358     dev[0].p2p_find(social=False)
359     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.5)
360     if ev is None:
361         logger.info("No CTRL-EVENT-SCAN-STARTED event")
362     dev[0].p2p_stop_find()
363     ev = dev[0].wait_global_event(["P2P-FIND-STOPPED"], timeout=1)
364     if ev is None:
365         raise Exception("P2P_STOP not reported")
366     ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=5)
367     if ev is not None:
368         raise Exception("Peer found unexpectedly: " + ev)
369
370     dev[0].p2p_find(social=False)
371     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.5)
372     if ev is None:
373         logger.info("No CTRL-EVENT-SCAN-STARTED event")
374     dev[0].global_request("P2P_FLUSH")
375     ev = dev[0].wait_global_event(["P2P-FIND-STOPPED"], timeout=1)
376     if ev is None:
377         raise Exception("P2P_STOP not reported")
378     ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=5)
379     if ev is not None:
380         raise Exception("Peer found unexpectedly: " + ev)
381
382 def test_p2p_peer_command(dev):
383     """P2P_PEER command"""
384     addr0 = dev[0].p2p_dev_addr()
385     addr1 = dev[1].p2p_dev_addr()
386     addr2 = dev[2].p2p_dev_addr()
387     dev[1].p2p_listen()
388     dev[2].p2p_listen()
389     if not dev[0].discover_peer(addr1):
390         raise Exception("Device discovery timed out")
391     if not dev[0].discover_peer(addr2):
392         raise Exception("Device discovery timed out")
393     dev[0].p2p_stop_find()
394     dev[1].p2p_stop_find()
395     dev[2].p2p_stop_find()
396
397     res0 = dev[0].request("P2P_PEER FIRST")
398     peer = res0.splitlines()[0]
399     if peer not in [ addr1, addr2 ]:
400         raise Exception("Unexpected P2P_PEER FIRST address")
401     res1 = dev[0].request("P2P_PEER NEXT-" + peer)
402     peer2 = res1.splitlines()[0]
403     if peer2 not in [ addr1, addr2 ] or peer == peer2:
404         raise Exception("Unexpected P2P_PEER NEXT address")
405
406     if "FAIL" not in dev[0].request("P2P_PEER NEXT-foo"):
407         raise Exception("Invalid P2P_PEER command accepted")
408     if "FAIL" not in dev[0].request("P2P_PEER foo"):
409         raise Exception("Invalid P2P_PEER command accepted")
410     if "FAIL" not in dev[0].request("P2P_PEER 00:11:22:33:44:55"):
411         raise Exception("P2P_PEER command for unknown peer accepted")
412
413 def test_p2p_listen_and_offchannel_tx(dev):
414     """P2P_LISTEN behavior with offchannel TX"""
415     addr0 = dev[0].p2p_dev_addr()
416     addr1 = dev[1].p2p_dev_addr()
417     addr2 = dev[2].p2p_dev_addr()
418
419     dev[1].p2p_listen()
420     if not dev[0].discover_peer(addr1):
421         raise Exception("Device discovery timed out")
422
423     dev[0].p2p_listen()
424     dev[0].global_request("P2P_PROV_DISC " + addr1 + " display")
425     ev = dev[0].wait_global_event(["P2P-PROV-DISC-ENTER-PIN"], timeout=15)
426     if ev is None:
427         raise Exception("No PD result reported")
428     dev[1].p2p_stop_find()
429
430     if not dev[2].discover_peer(addr0):
431         raise Exception("Device discovery timed out after PD exchange")
432     dev[2].p2p_stop_find()
433     dev[0].p2p_stop_find()
434
435 def test_p2p_listen_and_scan(dev):
436     """P2P_LISTEN and scan"""
437     dev[0].p2p_listen()
438     if "OK" not in dev[0].request("SCAN freq=2412"):
439         raise Exception("Failed to request a scan")
440     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 3)
441     if ev is not None:
442         raise Exception("Unexpected scan results")
443     dev[0].p2p_stop_find()
444     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15)
445     if ev is None:
446         raise Exception("Scan timed out")
447
448 def test_p2p_config_methods(dev):
449     """P2P and WPS config method update"""
450     addr0 = dev[0].p2p_dev_addr()
451     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
452     wpas.interface_add("wlan5")
453     addr1 = wpas.p2p_dev_addr()
454
455     if "OK" not in wpas.request("SET config_methods keypad virtual_push_button"):
456         raise Exception("Failed to set config_methods")
457
458     wpas.p2p_listen()
459     if not dev[0].discover_peer(addr1):
460         raise Exception("Device discovery timed out")
461     dev[0].p2p_stop_find()
462     peer = dev[0].get_peer(addr1)
463     if peer['config_methods'] != '0x180':
464         raise Exception("Unexpected peer config methods(1): " + peer['config_methods'])
465     dev[0].global_request("P2P_FLUSH")
466
467     if "OK" not in wpas.request("SET config_methods virtual_display"):
468         raise Exception("Failed to set config_methods")
469
470     if not dev[0].discover_peer(addr1):
471         raise Exception("Device discovery timed out")
472     dev[0].p2p_stop_find()
473     peer = dev[0].get_peer(addr1)
474     if peer['config_methods'] != '0x8':
475         raise Exception("Unexpected peer config methods(2): " + peer['config_methods'])
476
477     wpas.p2p_stop_find()