1 # P2P service 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 from remotehost import remote_compatible
8 import logging
9 logger = logging.getLogger()
10 import os
11 import time
12 import uuid
13 
14 import hwsim_utils
15 
16 def add_bonjour_services(dev):
17     dev.global_request("P2P_SERVICE_ADD bonjour 0b5f6166706f766572746370c00c000c01 074578616d706c65c027")
18     dev.global_request("P2P_SERVICE_ADD bonjour 076578616d706c650b5f6166706f766572746370c00c001001 00")
19     dev.global_request("P2P_SERVICE_ADD bonjour 045f697070c00c000c01 094d795072696e746572c027")
20     dev.global_request("P2P_SERVICE_ADD bonjour 096d797072696e746572045f697070c00c001001 09747874766572733d311a70646c3d6170706c69636174696f6e2f706f7374736372797074")
21 
22 def add_upnp_services(dev):
23     dev.global_request("P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice")
24     dev.global_request("P2P_SERVICE_ADD upnp 10 uuid:5566d33e-9774-09ab-4822-333456785632::upnp:rootdevice")
25     dev.global_request("P2P_SERVICE_ADD upnp 10 uuid:1122de4e-8574-59ab-9322-333456789044::urn:schemas-upnp-org:service:ContentDirectory:2")
26     dev.global_request("P2P_SERVICE_ADD upnp 10 uuid:5566d33e-9774-09ab-4822-333456785632::urn:schemas-upnp-org:service:ContentDirectory:2")
27     dev.global_request("P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp-org:device:InternetGatewayDevice:1")
28 
29 def add_extra_services(dev):
30     for i in range(0, 100):
31         dev.global_request("P2P_SERVICE_ADD upnp 10 uuid:" + str(uuid.uuid4()) + "::upnp:rootdevice")
32 
33 def run_sd(dev, dst, query, exp_query=None, fragment=False, query2=None):
34     addr0 = dev[0].p2p_dev_addr()
35     addr1 = dev[1].p2p_dev_addr()
36     add_bonjour_services(dev[0])
37     add_upnp_services(dev[0])
38     if fragment:
39         add_extra_services(dev[0])
40     dev[0].p2p_listen()
41 
42     dev[1].global_request("P2P_FLUSH")
43     dev[1].global_request("P2P_SERV_DISC_REQ " + dst + " " + query)
44     if query2:
45         dev[1].global_request("P2P_SERV_DISC_REQ " + dst + " " + query2)
46     if not dev[1].discover_peer(addr0, social=True, force_find=True):
47         raise Exception("Peer " + addr0 + " not found")
48 
49     ev = dev[0].wait_global_event(["P2P-SERV-DISC-REQ"], timeout=10)
50     if ev is None:
51         raise Exception("Service discovery timed out (req)")
52     if addr1 not in ev:
53         raise Exception("Unexpected service discovery request source")
54     if exp_query is None:
55         exp_query = query
56     if exp_query not in ev and (query2 is None or query2 not in ev):
57         raise Exception("Unexpected service discovery request contents")
58 
59     if query2:
60         ev_list = []
61         for i in range(10):
62             ev = dev[1].wait_global_event(["P2P-SERV-DISC-RESP"], timeout=10)
63             if ev is None:
64                 if len(ev_list) < 2:
65                     raise Exception("Service discovery timed out (resp2)")
66                 break
67             if addr0 in ev:
68                 logger.debug("Add entry to ev_list")
69                 ev_list.append(ev)
70                 if len(ev_list) == 8:
71                     break
72         return ev_list
73 
74     for i in range(0, 2):
75         ev = dev[1].wait_global_event(["P2P-SERV-DISC-RESP"], timeout=10)
76         if ev is None:
77             raise Exception("Service discovery timed out (resp)")
78         if addr0 in ev:
79             break
80 
81     dev[0].p2p_stop_find()
82     dev[1].p2p_stop_find()
83 
84     if "OK" not in dev[0].global_request("P2P_SERVICE_DEL upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice"):
85         raise Exception("Failed to delete a UPnP service")
86     if "FAIL" not in dev[0].global_request("P2P_SERVICE_DEL upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice"):
87         raise Exception("Unexpected deletion success for UPnP service")
88     if "OK" not in dev[0].global_request("P2P_SERVICE_DEL bonjour 0b5f6166706f766572746370c00c000c01"):
89         raise Exception("Failed to delete a Bonjour service")
90     if "FAIL" not in dev[0].global_request("P2P_SERVICE_DEL bonjour 0b5f6166706f766572746370c00c000c01"):
91         raise Exception("Unexpected deletion success for Bonjour service")
92 
93     return ev
94 
95 @remote_compatible
96 def test_p2p_service_discovery(dev):
97     """P2P service discovery"""
98     addr0 = dev[0].p2p_dev_addr()
99     for dst in ["00:00:00:00:00:00", addr0]:
100         ev = run_sd(dev, dst, "02000001")
101         if "0b5f6166706f766572746370c00c000c01" not in ev:
102             raise Exception("Unexpected service discovery response contents (Bonjour)")
103         if "496e7465726e6574" not in ev:
104             raise Exception("Unexpected service discovery response contents (UPnP)")
105 
106     for req in ["foo 02000001",
107                 addr0,
108                 addr0 + " upnp qq urn:schemas-upnp-org:device:InternetGatewayDevice:1",
109                 addr0 + " upnp 10",
110                 addr0 + " 123",
111                 addr0 + " qq"]:
112         if "FAIL" not in dev[1].global_request("P2P_SERV_DISC_REQ " + req):
113             raise Exception("Invalid P2P_SERV_DISC_REQ accepted: " + req)
114 
115 def test_p2p_service_discovery2(dev):
116     """P2P service discovery with one peer having no services"""
117     dev[2].p2p_listen()
118     for dst in ["00:00:00:00:00:00", dev[0].p2p_dev_addr()]:
119         ev = run_sd(dev, dst, "02000001")
120         if "0b5f6166706f766572746370c00c000c01" not in ev:
121             raise Exception("Unexpected service discovery response contents (Bonjour)")
122         if "496e7465726e6574" not in ev:
123             raise Exception("Unexpected service discovery response contents (UPnP)")
124 
125 def test_p2p_service_discovery3(dev):
126     """P2P service discovery for Bonjour with one peer having no services"""
127     dev[2].p2p_listen()
128     for dst in ["00:00:00:00:00:00", dev[0].p2p_dev_addr()]:
129         ev = run_sd(dev, dst, "02000101")
130         if "0b5f6166706f766572746370c00c000c01" not in ev:
131             raise Exception("Unexpected service discovery response contents (Bonjour)")
132 
133 def test_p2p_service_discovery4(dev):
134     """P2P service discovery for UPnP with one peer having no services"""
135     dev[2].p2p_listen()
136     for dst in ["00:00:00:00:00:00", dev[0].p2p_dev_addr()]:
137         ev = run_sd(dev, dst, "02000201")
138         if "496e7465726e6574" not in ev:
139             raise Exception("Unexpected service discovery response contents (UPnP)")
140 
141 @remote_compatible
142 def test_p2p_service_discovery_multiple_queries(dev):
143     """P2P service discovery with multiple queries"""
144     for dst in ["00:00:00:00:00:00", dev[0].p2p_dev_addr()]:
145         ev = run_sd(dev, dst, "02000201", query2="02000101")
146         found = False
147         for e in ev:
148             if "0b5f6166706f766572746370c00c000c01" in e:
149                 found = True
150                 break
151         if not found:
152             raise Exception("Unexpected service discovery response contents (Bonjour)")
153         found = False
154         for e in ev:
155             if "496e7465726e6574" in e:
156                 found = True
157                 break
158         if not found:
159             raise Exception("Unexpected service discovery response contents (UPnP)")
160 
161 def test_p2p_service_discovery_multiple_queries2(dev):
162     """P2P service discovery with multiple queries with one peer having no services"""
163     dev[2].p2p_listen()
164     for dst in ["00:00:00:00:00:00", dev[0].p2p_dev_addr()]:
165         ev = run_sd(dev, dst, "02000201", query2="02000101")
166         found = False
167         for e in ev:
168             if "0b5f6166706f766572746370c00c000c01" in e:
169                 found = True
170                 break
171         if not found:
172             raise Exception("Unexpected service discovery response contents (Bonjour)")
173         found = False
174         for e in ev:
175             if "496e7465726e6574" in e:
176                 found = True
177                 break
178         if not found:
179             raise Exception("Unexpected service discovery response contents (UPnP)")
180 
181 def test_p2p_service_discovery_fragmentation(dev):
182     """P2P service discovery with fragmentation"""
183     for dst in ["00:00:00:00:00:00", dev[0].p2p_dev_addr()]:
184         ev = run_sd(dev, dst, "02000001", fragment=True)
185         if "long response" not in ev:
186             if "0b5f6166706f766572746370c00c000c01" not in ev:
187                 raise Exception("Unexpected service discovery response contents (Bonjour)")
188             if "496e7465726e6574" not in ev:
189                 raise Exception("Unexpected service discovery response contents (UPnP)")
190 
191 @remote_compatible
192 def test_p2p_service_discovery_bonjour(dev):
193     """P2P service discovery (Bonjour)"""
194     ev = run_sd(dev, "00:00:00:00:00:00", "02000101")
195     if "0b5f6166706f766572746370c00c000c01" not in ev:
196         raise Exception("Unexpected service discovery response contents (Bonjour)")
197     if "045f697070c00c000c01" not in ev:
198         raise Exception("Unexpected service discovery response contents (Bonjour)")
199     if "496e7465726e6574" in ev:
200         raise Exception("Unexpected service discovery response contents (UPnP not expected)")
201 
202 @remote_compatible
203 def test_p2p_service_discovery_bonjour2(dev):
204     """P2P service discovery (Bonjour AFS)"""
205     ev = run_sd(dev, "00:00:00:00:00:00", "130001010b5f6166706f766572746370c00c000c01")
206     if "0b5f6166706f766572746370c00c000c01" not in ev:
207         raise Exception("Unexpected service discovery response contents (Bonjour)")
208     if "045f697070c00c000c01" in ev:
209         raise Exception("Unexpected service discovery response contents (Bonjour mismatching)")
210     if "496e7465726e6574" in ev:
211         raise Exception("Unexpected service discovery response contents (UPnP not expected)")
212 
213 @remote_compatible
214 def test_p2p_service_discovery_bonjour3(dev):
215     """P2P service discovery (Bonjour AFS - no match)"""
216     ev = run_sd(dev, "00:00:00:00:00:00", "130001010b5f6166706f766572746370c00c000c02")
217     if "0300010102" not in ev:
218         raise Exception("Requested-info-not-available was not indicated")
219     if "0b5f6166706f766572746370c00c000c01" in ev:
220         raise Exception("Unexpected service discovery response contents (Bonjour)")
221     if "045f697070c00c000c01" in ev:
222         raise Exception("Unexpected service discovery response contents (Bonjour mismatching)")
223     if "496e7465726e6574" in ev:
224         raise Exception("Unexpected service discovery response contents (UPnP not expected)")
225 
226 @remote_compatible
227 def test_p2p_service_discovery_upnp(dev):
228     """P2P service discovery (UPnP)"""
229     ev = run_sd(dev, "00:00:00:00:00:00", "02000201")
230     if "0b5f6166706f766572746370c00c000c01" in ev:
231         raise Exception("Unexpected service discovery response contents (Bonjour not expected)")
232     if "496e7465726e6574" not in ev:
233         raise Exception("Unexpected service discovery response contents (UPnP)")
234 
235 @remote_compatible
236 def test_p2p_service_discovery_upnp2(dev):
237     """P2P service discovery (UPnP using request helper)"""
238     ev = run_sd(dev, "00:00:00:00:00:00", "upnp 10 ssdp:all", "0b00020110737364703a616c6c")
239     if "0b5f6166706f766572746370c00c000c01" in ev:
240         raise Exception("Unexpected service discovery response contents (Bonjour not expected)")
241     if "496e7465726e6574" not in ev:
242         raise Exception("Unexpected service discovery response contents (UPnP)")
243 
244 @remote_compatible
245 def test_p2p_service_discovery_upnp3(dev):
246     """P2P service discovery (UPnP using request helper - no match)"""
247     ev = run_sd(dev, "00:00:00:00:00:00", "upnp 10 ssdp:foo", "0b00020110737364703a666f6f")
248     if "0300020102" not in ev:
249         raise Exception("Requested-info-not-available was not indicated")
250     if "0b5f6166706f766572746370c00c000c01" in ev:
251         raise Exception("Unexpected service discovery response contents (Bonjour not expected)")
252     if "496e7465726e6574" in ev:
253         raise Exception("Unexpected service discovery response contents (UPnP)")
254 
255 @remote_compatible
256 def test_p2p_service_discovery_ws(dev):
257     """P2P service discovery (WS-Discovery)"""
258     ev = run_sd(dev, "00:00:00:00:00:00", "02000301")
259     if "0b5f6166706f766572746370c00c000c01" in ev:
260         raise Exception("Unexpected service discovery response contents (Bonjour not expected)")
261     if "496e7465726e6574" in ev:
262         raise Exception("Unexpected service discovery response contents (UPnP not expected)")
263     if "0300030101" not in ev:
264         raise Exception("Unexpected service discovery response contents (WS)")
265 
266 @remote_compatible
267 def test_p2p_service_discovery_wfd(dev):
268     """P2P service discovery (Wi-Fi Display)"""
269     dev[0].global_request("SET wifi_display 1")
270     ev = run_sd(dev, "00:00:00:00:00:00", "02000401")
271     if " 030004" in ev:
272         raise Exception("Unexpected response to invalid WFD SD query")
273     dev[0].global_request("SET wifi_display 0")
274     ev = run_sd(dev, "00:00:00:00:00:00", "0300040100")
275     if "0300040101" not in ev:
276         raise Exception("Unexpected response to WFD SD query (protocol was disabled)")
277 
278 @remote_compatible
279 def test_p2p_service_discovery_req_cancel(dev):
280     """Cancel a P2P service discovery request"""
281     if "FAIL" not in dev[0].global_request("P2P_SERV_DISC_CANCEL_REQ ab"):
282         raise Exception("Unexpected SD cancel success")
283     if "FAIL" not in dev[0].global_request("P2P_SERV_DISC_CANCEL_REQ qq"):
284         raise Exception("Unexpected SD cancel success")
285     query = dev[0].global_request("P2P_SERV_DISC_REQ " + dev[1].p2p_dev_addr() + " 02000001")
286     if "OK" not in dev[0].global_request("P2P_SERV_DISC_CANCEL_REQ " + query):
287         raise Exception("Unexpected SD cancel failure")
288     query1 = dev[0].global_request("P2P_SERV_DISC_REQ " + dev[1].p2p_dev_addr() + " 02000001")
289     query2 = dev[0].global_request("P2P_SERV_DISC_REQ " + dev[1].p2p_dev_addr() + " 02000002")
290     query3 = dev[0].global_request("P2P_SERV_DISC_REQ " + dev[1].p2p_dev_addr() + " 02000003")
291     if "OK" not in dev[0].global_request("P2P_SERV_DISC_CANCEL_REQ " + query2):
292         raise Exception("Unexpected SD cancel failure")
293     if "OK" not in dev[0].global_request("P2P_SERV_DISC_CANCEL_REQ " + query1):
294         raise Exception("Unexpected SD cancel failure")
295     if "OK" not in dev[0].global_request("P2P_SERV_DISC_CANCEL_REQ " + query3):
296         raise Exception("Unexpected SD cancel failure")
297 
298     query = dev[0].global_request("P2P_SERV_DISC_REQ 00:00:00:00:00:00 02000001")
299     if "OK" not in dev[0].global_request("P2P_SERV_DISC_CANCEL_REQ " + query):
300         raise Exception("Unexpected SD(broadcast) cancel failure")
301 
302 @remote_compatible
303 def test_p2p_service_discovery_from_go(dev):
304     """P2P service discovery initiated from a GO device"""
305     addr0 = dev[0].p2p_dev_addr()
306     addr1 = dev[1].p2p_dev_addr()
307 
308     dev[0].p2p_start_go(freq=2412)
309     dev[1].p2p_listen()
310 
311     dev[0].global_request("P2P_SERV_DISC_REQ "+ addr1 + " 02000001")
312     if not dev[0].discover_peer(addr1, social=True, force_find=True):
313         raise Exception("Peer " + addr1 + " not found")
314 
315     ev = dev[1].wait_global_event(["P2P-SERV-DISC-REQ"], timeout=10)
316     if ev is None:
317         raise Exception("Service discovery timed out")
318     if addr0 not in ev:
319         raise Exception("Unexpected service discovery request source")
320 
321     ev = dev[0].wait_global_event(["P2P-SERV-DISC-RESP"], timeout=10)
322     if ev is None:
323         raise Exception("Service discovery timed out")
324     if addr1 not in ev:
325         raise Exception("Unexpected service discovery response source")
326     dev[0].p2p_stop_find()
327 
328 @remote_compatible
329 def test_p2p_service_discovery_go(dev):
330     """P2P service discovery from GO"""
331     addr0 = dev[0].p2p_dev_addr()
332     addr1 = dev[1].p2p_dev_addr()
333 
334     add_bonjour_services(dev[0])
335     add_upnp_services(dev[0])
336 
337     dev[0].p2p_start_go(freq=2412)
338 
339     dev[1].global_request("P2P_FLUSH")
340     dev[1].global_request("P2P_SERV_DISC_REQ " + addr0 + " 02000001")
341     if not dev[1].discover_peer(addr0, social=True, force_find=True):
342         raise Exception("Peer " + addr0 + " not found")
343 
344     ev = dev[0].wait_global_event(["P2P-SERV-DISC-REQ"], timeout=10)
345     if ev is None:
346         raise Exception("Service discovery timed out")
347     if addr1 not in ev:
348         raise Exception("Unexpected service discovery request source")
349 
350     ev = dev[1].wait_global_event(["P2P-SERV-DISC-RESP"], timeout=10)
351     if ev is None:
352         raise Exception("Service discovery timed out")
353     if addr0 not in ev:
354         raise Exception("Unexpected service discovery response source")
355     if "0b5f6166706f766572746370c00c000c01" not in ev:
356         raise Exception("Unexpected service discovery response contents (Bonjour)")
357     if "496e7465726e6574" not in ev:
358         raise Exception("Unexpected service discovery response contents (UPnP)")
359     dev[1].p2p_stop_find()
360 
361     dev[0].global_request("P2P_SERVICE_FLUSH")
362 
363     dev[1].global_request("P2P_FLUSH")
364     dev[1].global_request("P2P_SERV_DISC_REQ " + addr0 + " 02000001")
365     if not dev[1].discover_peer(addr0, social=True, force_find=True):
366         raise Exception("Peer " + addr0 + " not found")
367     ev = dev[0].wait_global_event(["P2P-SERV-DISC-REQ"], timeout=10)
368     if ev is None:
369         raise Exception("Service discovery timed out")
370     if addr1 not in ev:
371         raise Exception("Unexpected service discovery request source")
372 
373     ev = dev[1].wait_global_event(["P2P-SERV-DISC-RESP"], timeout=10)
374     if ev is None:
375         raise Exception("Service discovery timed out")
376     if addr0 not in ev:
377         raise Exception("Unexpected service discovery response source")
378     if "0300000101" not in ev:
379         raise Exception("Unexpected service discovery response contents (Bonjour)")
380     dev[1].p2p_stop_find()
381 
382 def _test_p2p_service_discovery_external(dev):
383     addr0 = dev[0].p2p_dev_addr()
384     addr1 = dev[1].p2p_dev_addr()
385 
386     if "FAIL" not in dev[0].global_request("P2P_SERV_DISC_EXTERNAL 2"):
387         raise Exception("Invalid P2P_SERV_DISC_EXTERNAL accepted")
388     if "OK" not in dev[0].global_request("P2P_SERV_DISC_EXTERNAL 1"):
389         raise Exception("P2P_SERV_DISC_EXTERNAL failed")
390     dev[0].p2p_listen()
391     dev[1].global_request("P2P_FLUSH")
392     dev[1].global_request("P2P_SERV_DISC_REQ " + addr0 + " 02000001")
393     if not dev[1].discover_peer(addr0, social=True, force_find=True):
394         raise Exception("Peer " + addr0 + " not found")
395 
396     ev = dev[0].wait_global_event(["P2P-SERV-DISC-REQ"], timeout=10)
397     if ev is None:
398         raise Exception("Service discovery timed out")
399     if addr1 not in ev:
400         raise Exception("Unexpected service discovery request source")
401     arg = ev.split(' ')
402     resp = "0300000101"
403     if "OK" not in dev[0].global_request("P2P_SERV_DISC_RESP %s %s %s %s" % (arg[2], arg[3], arg[4], resp)):
404         raise Exception("P2P_SERV_DISC_RESP failed")
405 
406     ev = dev[1].wait_global_event(["P2P-SERV-DISC-RESP"], timeout=15)
407     if ev is None:
408         raise Exception("Service discovery timed out")
409     if addr0 not in ev:
410         raise Exception("Unexpected address in SD Response: " + ev)
411     if ev.split(' ')[4] != resp:
412         raise Exception("Unexpected response data SD Response: " + ev)
413     ver = ev.split(' ')[3]
414 
415     dev[0].global_request("P2P_SERVICE_UPDATE")
416 
417     dev[1].global_request("P2P_FLUSH")
418     dev[1].global_request("P2P_SERV_DISC_REQ " + addr0 + " 02000001")
419     if not dev[1].discover_peer(addr0, social=True, force_find=True):
420         raise Exception("Peer " + addr0 + " not found")
421 
422     ev = dev[0].wait_global_event(["P2P-SERV-DISC-REQ"], timeout=10)
423     if ev is None:
424         raise Exception("Service discovery timed out")
425     if addr1 not in ev:
426         raise Exception("Unexpected service discovery request source")
427     arg = ev.split(' ')
428     resp = "0300000101"
429     if "OK" not in dev[0].global_request("P2P_SERV_DISC_RESP %s %s %s %s" % (arg[2], arg[3], arg[4], resp)):
430         raise Exception("P2P_SERV_DISC_RESP failed")
431 
432     ev = dev[1].wait_global_event(["P2P-SERV-DISC-RESP"], timeout=15)
433     if ev is None:
434         raise Exception("Service discovery timed out")
435     if addr0 not in ev:
436         raise Exception("Unexpected address in SD Response: " + ev)
437     if ev.split(' ')[4] != resp:
438         raise Exception("Unexpected response data SD Response: " + ev)
439     ver2 = ev.split(' ')[3]
440     if ver == ver2:
441         raise Exception("Service list version did not change")
442 
443     for cmd in ["%s%s%s%s" % (arg[2], arg[3], arg[4], resp),
444                 "%s %s %s %s" % ("0", arg[3], arg[4], resp),
445                 "%s %s %s %s" % (arg[2], "foo", arg[4], resp),
446                 "%s %s%s%s" % (arg[2], arg[3], arg[4], resp),
447                 "%s %s %s%s" % (arg[2], arg[3], arg[4], resp),
448                 "%s %s %s %s" % (arg[2], arg[3], arg[4], "12345"),
449                 "%s %s %s %s" % (arg[2], arg[3], arg[4], "qq")]:
450         if "FAIL" not in dev[0].global_request("P2P_SERV_DISC_RESP " + cmd):
451             raise Exception("Invalid P2P_SERV_DISC_RESP accepted: " + cmd)
452 
453 @remote_compatible
454 def test_p2p_service_discovery_external(dev):
455     """P2P service discovery using external response"""
456     try:
457         _test_p2p_service_discovery_external(dev)
458     finally:
459         dev[0].global_request("P2P_SERV_DISC_EXTERNAL 0")
460 
461 @remote_compatible
462 def test_p2p_service_discovery_invalid_commands(dev):
463     """P2P service discovery invalid commands"""
464     for cmd in ["bonjour",
465                 "bonjour 12",
466                 "bonjour 123 12",
467                 "bonjour qq 12",
468                 "bonjour 12 123",
469                 "bonjour 12 qq",
470                 "upnp 10",
471                 "upnp qq uuid:",
472                 "foo bar"]:
473         if "FAIL" not in dev[0].global_request("P2P_SERVICE_ADD " + cmd):
474             raise Exception("Invalid P2P_SERVICE_ADD accepted: " + cmd)
475 
476     for cmd in ["bonjour",
477                 "bonjour 123",
478                 "bonjour qq",
479                 "upnp 10",
480                 "upnp  ",
481                 "upnp qq uuid:",
482                 "foo bar"]:
483         if "FAIL" not in dev[0].global_request("P2P_SERVICE_DEL " + cmd):
484             raise Exception("Invalid P2P_SERVICE_DEL accepted: " + cmd)
485 
486 def test_p2p_service_discovery_cancel_during_query(dev):
487     """P2P service discovery and cancel during query"""
488     for i in range(2):
489         add_bonjour_services(dev[i])
490         add_upnp_services(dev[i])
491         add_extra_services(dev[i])
492         dev[i].p2p_listen()
493 
494     dev[2].request("P2P_FLUSH")
495     id1 = dev[2].request("P2P_SERV_DISC_REQ 00:00:00:00:00:00 02000201")
496     id2 = dev[2].request("P2P_SERV_DISC_REQ 00:00:00:00:00:00 02000101")
497     dev[2].p2p_find(social=True)
498     ev = dev[2].wait_global_event(["P2P-DEVICE-FOUND"], timeout=15)
499     if ev is None:
500         raise Exception("Could not discover peer")
501     if "OK" not in dev[2].request("P2P_SERV_DISC_CANCEL_REQ " + id1):
502         raise Exception("Failed to cancel req1")
503     if "OK" not in dev[2].request("P2P_SERV_DISC_CANCEL_REQ " + id2):
504         raise Exception("Failed to cancel req2")
505     ev = dev[2].wait_global_event(["P2P-SERV-DISC-RESP"], timeout=3)
506     # we may or may not get a response depending on timing, so ignore the result
507     dev[2].p2p_stop_find()
508     dev[1].p2p_stop_find()
509     dev[0].p2p_stop_find()
510 
511 def get_p2p_state(dev):
512     res = dev.global_request("STATUS")
513     p2p_state = None
514     for line in res.splitlines():
515         if line.startswith("p2p_state="):
516             p2p_state = line.split('=')[1]
517             break
518     if p2p_state is None:
519         raise Exception("Could not get p2p_state")
520     return p2p_state
521 
522 @remote_compatible
523 def test_p2p_service_discovery_peer_not_listening(dev):
524     """P2P service discovery and peer not listening"""
525     addr0 = dev[0].p2p_dev_addr()
526     addr1 = dev[1].p2p_dev_addr()
527     add_bonjour_services(dev[0])
528     add_upnp_services(dev[0])
529     dev[0].p2p_listen()
530     dev[1].global_request("P2P_FIND 4 type=social")
531     ev = dev[1].wait_global_event(["P2P-DEVICE-FOUND"], timeout=4)
532     if ev is None:
533         raise Exception("Peer not found")
534     dev[0].p2p_stop_find()
535     ev = dev[1].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=1)
536     ev = dev[1].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=1)
537     time.sleep(0.03)
538     dev[1].request("P2P_SERV_DISC_REQ " + addr0 + " 02000001")
539     ev = dev[0].wait_global_event(["P2P-SERV-DISC-REQ"], timeout=1)
540     if ev is not None:
541         raise Exception("Service discovery request unexpectedly received")
542     ev = dev[1].wait_global_event(["P2P-FIND-STOPPED", "P2P-SERV-DISC-RESP"],
543                                   timeout=10)
544     if ev is None:
545         raise Exception("P2P-FIND-STOPPED event timed out")
546     if "P2P-SERV-DISC-RESP" in ev:
547         raise Exception("Unexpected SD response")
548     p2p_state = get_p2p_state(dev[1])
549     if p2p_state != "IDLE":
550         raise Exception("Unexpected p2p_state after P2P_FIND timeout: " + p2p_state)
551 
552 @remote_compatible
553 def test_p2p_service_discovery_peer_not_listening2(dev):
554     """P2P service discovery and peer not listening"""
555     addr0 = dev[0].p2p_dev_addr()
556     addr1 = dev[1].p2p_dev_addr()
557     add_bonjour_services(dev[0])
558     add_upnp_services(dev[0])
559     dev[0].p2p_listen()
560     dev[1].global_request("P2P_FIND type=social")
561     ev = dev[1].wait_global_event(["P2P-DEVICE-FOUND"], timeout=10)
562     if ev is None:
563         raise Exception("Peer not found")
564     dev[0].p2p_stop_find()
565     time.sleep(0.53)
566     dev[1].request("P2P_SERV_DISC_REQ " + addr0 + " 02000001")
567     ev = dev[0].wait_global_event(["P2P-SERV-DISC-REQ"], timeout=0.5)
568     if ev is not None:
569         raise Exception("Service discovery request unexpectedly received")
570     dev[1].p2p_stop_find()
571     ev = dev[1].wait_global_event(["P2P-FIND-STOPPED", "P2P-SERV-DISC-RESP"],
572                                   timeout=10)
573     if ev is None:
574         raise Exception("P2P-FIND-STOPPED event timed out")
575     if "P2P-SERV-DISC-RESP" in ev:
576         raise Exception("Unexpected SD response")
577     p2p_state = get_p2p_state(dev[1])
578     if p2p_state != "IDLE":
579         raise Exception("Unexpected p2p_state after P2P_FIND timeout: " + p2p_state)
580 
581 def test_p2p_service_discovery_restart(dev):
582     """P2P service discovery restarted immediately"""
583     try:
584         _test_p2p_service_discovery_restart(dev)
585     finally:
586         dev[1].global_request("P2P_SET disc_int 1 3 -1")
587 
588 def _test_p2p_service_discovery_restart(dev):
589     addr0 = dev[0].p2p_dev_addr()
590     addr1 = dev[1].p2p_dev_addr()
591 
592     # Use shorter listen interval to keep P2P_FIND loop shorter.
593     dev[1].global_request("P2P_SET disc_int 1 1 10")
594 
595     add_bonjour_services(dev[0])
596     #add_upnp_services(dev[0])
597     dev[0].p2p_listen()
598 
599     dev[1].global_request("P2P_FLUSH")
600     dev[1].global_request("P2P_SERV_DISC_REQ " + addr0 + " 02000001")
601     if not dev[1].discover_peer(addr0, social=True, force_find=True):
602         raise Exception("Peer " + addr0 + " not found")
603 
604     ev = dev[1].wait_global_event(["P2P-SERV-DISC-RESP"], timeout=10)
605     if ev is None:
606         raise Exception("Service discovery timed out")
607 
608     # The following P2P_LISTEN operation used to get delayed due to the last
609     # Action frame TX operation in SD Response using wait_time of 200 ms. It is
610     # somewhat difficult to test for this automatically, but the debug log can
611     # be verified to see that the remain-on-channel event for operation arrives
612     # immediately instead of getting delayed 200 ms. We can use a maximum
613     # acceptable time for the SD Response, but need to keep the limit somewhat
614     # high to avoid making this fail under heavy load. Still, it is apparently
615     # possible for this to take about the same amount of time with fixed
616     # implementation every now and then, so run this multiple time and pass the
617     # test if any attempt is fast enough.
618 
619     for i in range(20):
620         dev[1].p2p_stop_find()
621         dev[0].p2p_stop_find()
622         time.sleep(0.01)
623         dev[0].p2p_listen()
624 
625         dev[1].global_request("P2P_SERV_DISC_REQ " + addr0 + " 02000001")
626         dev[1].p2p_find(social=True)
627         start = os.times()[4]
628         ev = dev[1].wait_global_event(["P2P-SERV-DISC-RESP"], timeout=10)
629         if ev is None:
630             raise Exception("Service discovery timed out")
631         end = os.times()[4]
632         logger.info("Second SD Response in " + str(end - start) + " seconds")
633         if end - start < 0.8:
634             break
635 
636     dev[0].p2p_stop_find()
637     dev[1].p2p_stop_find()
638 
639     if end - start > 0.8:
640         raise Exception("Unexpectedly slow second SD Response: " + str(end - start) + " seconds")
641