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