1# P2P services
2# Copyright (c) 2014-2015, Qualcomm Atheros, Inc.
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 time
11import random
12import re
13
14import hwsim_utils
15from wpasupplicant import WpaSupplicant
16import hostapd
17from p2p_utils import *
18from utils import HwsimSkip
19from hwsim import HWSimRadio
20
21# Dev[0] -> Advertiser
22# Dev[1] -> Seeker
23# ev0 -> Event generated at advertiser side
24# ev1 -> Event generated at Seeker side
25
26def p2ps_advertise(r_dev, r_role, svc_name, srv_info, rsp_info=None, cpt=None):
27    """P2PS Advertise function"""
28    adv_id = random.randrange(1, 0xFFFFFFFF)
29    advid = hex(adv_id)[2:]
30
31    cpt_param = (" cpt=" + cpt) if cpt is not None else ""
32
33    if rsp_info is not None and srv_info is not None:
34        if "OK" not in r_dev.global_request("P2P_SERVICE_ADD asp " + str(r_role) + " " + str(advid) + " 1 1108 " + svc_name + cpt_param + " svc_info='" + srv_info + "'" + " rsp_info=" + rsp_info + "'"):
35            raise Exception("P2P_SERVICE_ADD with response info and service info failed")
36
37    if rsp_info is None and srv_info is not None:
38        if "OK" not in r_dev.global_request("P2P_SERVICE_ADD asp " + str(r_role) + " " + str(advid) + " 1 1108 " + svc_name + cpt_param + " svc_info='" + srv_info + "'"):
39            raise Exception("P2P_SERVICE_ADD with service info failed")
40
41    if rsp_info is None and srv_info is None:
42        if "OK" not in r_dev.global_request("P2P_SERVICE_ADD asp " + str(r_role) + " " + str(advid) + " 1 1108 " + svc_name + cpt_param):
43            raise Exception("P2P_SERVICE_ADD without service info and without response info failed")
44
45    if rsp_info is not None and srv_info is None:
46        if "OK" not in r_dev.global_request("P2P_SERVICE_ADD asp " + str(r_role) + " " + str(adv_id) + " 1 1108 " + svc_name + cpt_param + " svc_info='" + " rsp_info=" + rsp_info + "'"):
47            raise Exception("P2P_SERVICE_ADD with response info failed")
48
49    r_dev.p2p_listen()
50    return advid
51
52def p2ps_exact_seek(i_dev, r_dev, svc_name, srv_info=None,
53                    single_peer_expected=True):
54    """P2PS exact service seek request"""
55    if srv_info is not None:
56        ev1 = i_dev.global_request("P2P_SERV_DISC_REQ 00:00:00:00:00:00 asp 1 " + svc_name + " '" + srv_info + "'")
57        if ev1 is None:
58            raise Exception("Failed to add Service Discovery request for exact seek request")
59
60    if "OK" not in i_dev.global_request("P2P_FIND 10 type=social seek=" + svc_name):
61        raise Exception("Failed to initiate seek operation")
62
63    timeout = time.time() + 10
64    ev1 = i_dev.wait_global_event(["P2P-DEVICE-FOUND"], timeout=10)
65    while ev1 is not None and not single_peer_expected:
66        if r_dev.p2p_dev_addr() in ev1 and "adv_id=" in ev1:
67            break
68        ev1 = i_dev.wait_global_event(["P2P-DEVICE-FOUND"], timeout=10)
69
70        if timeout < time.time():
71            raise Exception("Device not found")
72
73    if ev1 is None:
74        raise Exception("P2P-DEVICE-FOUND timeout on seeker side")
75    if r_dev.p2p_dev_addr() not in ev1:
76        raise Exception("Unexpected peer")
77
78    if srv_info is None:
79        adv_id = ev1.split("adv_id=")[1].split(" ")[0]
80        rcvd_svc_name = ev1.split("asp_svc=")[1].split(" ")[0]
81        if rcvd_svc_name != svc_name:
82            raise Exception("service name not matching")
83    else:
84        ev1 = i_dev.wait_global_event(["P2P-SERV-ASP-RESP"], timeout=10)
85        if ev1 is None:
86            raise Exception("Failed to receive Service Discovery Response")
87        if r_dev.p2p_dev_addr() not in ev1:
88            raise Exception("Service Discovery response from Unknown Peer")
89        if srv_info is not None and srv_info not in ev1:
90            raise Exception("service info not available in Service Discovery response")
91        adv_id = ev1.split(" ")[3]
92        rcvd_svc_name = ev1.split(" ")[6]
93        if rcvd_svc_name != svc_name:
94            raise Exception("service name not matching")
95
96    i_dev.p2p_stop_find()
97    return [adv_id, rcvd_svc_name]
98
99def p2ps_nonexact_seek(i_dev, r_dev, svc_name, srv_info=None, adv_num=None):
100    """P2PS nonexact service seek request"""
101    if adv_num is None:
102       adv_num = 1
103    if srv_info is not None:
104        ev1 = i_dev.global_request("P2P_SERV_DISC_REQ 00:00:00:00:00:00 asp 1 " + svc_name + " '" + srv_info + "'")
105    else:
106        ev1 = i_dev.global_request("P2P_SERV_DISC_REQ 00:00:00:00:00:00 asp 1 " + svc_name + " '")
107    if ev1 is None:
108        raise Exception("Failed to add Service Discovery request for nonexact seek request")
109    if "OK" not in i_dev.global_request("P2P_FIND 10 type=social seek="):
110        raise Exception("Failed to initiate seek")
111    ev1 = i_dev.wait_global_event(["P2P-DEVICE-FOUND"], timeout=10)
112    if ev1 is None:
113        raise Exception("P2P-DEVICE-FOUND timeout on seeker side")
114    if r_dev.p2p_dev_addr() not in ev1:
115        raise Exception("Unexpected peer")
116    ev_list = []
117    for i in range(0, adv_num):
118        ev1 = i_dev.wait_global_event(["P2P-SERV-ASP-RESP"], timeout=10)
119        if ev1 is None:
120            raise Exception("Failed to receive Service Discovery Response")
121        if r_dev.p2p_dev_addr() not in ev1:
122            raise Exception("Service Discovery response from Unknown Peer")
123        if srv_info is not None and srv_info not in ev1:
124            raise Exception("service info not available in Service Discovery response")
125        adv_id = ev1.split(" ")[3]
126        rcvd_svc_name = ev1.split(" ")[6]
127        ev_list.append(''.join([adv_id, ' ', rcvd_svc_name]))
128
129    i_dev.p2p_stop_find()
130    return ev_list
131
132def p2ps_parse_event(ev, *args):
133    ret = ()
134    for arg in args:
135        m = re.search(r"\s+" + arg + r"=(\S+)", ev)
136        ret += (m.group(1) if m is not None else None,)
137    return ret
138
139def p2ps_provision(seeker, advertiser, adv_id, auto_accept=True, method="1000",
140                   adv_cpt=None, seeker_cpt=None, handler=None, adv_role=None,
141                   seeker_role=None):
142    addr0 = seeker.p2p_dev_addr()
143    addr1 = advertiser.p2p_dev_addr()
144
145    seeker.asp_provision(addr1, adv_id=str(adv_id), adv_mac=addr1, session_id=1,
146                         session_mac=addr0, method=method, cpt=seeker_cpt,
147                         role=seeker_role)
148
149    if not auto_accept or method == "100":
150        pin = None
151        ev_pd_start = advertiser.wait_global_event(["P2PS-PROV-START"],
152                                                   timeout=10)
153        if ev_pd_start is None:
154            raise Exception("P2PS-PROV-START timeout on Advertiser side")
155        peer = ev_pd_start.split()[1]
156        advert_id, advert_mac, session, session_mac =\
157            p2ps_parse_event(ev_pd_start, "adv_id", "adv_mac", "session", "mac")
158
159        ev = seeker.wait_global_event(["P2P-PROV-DISC-FAILURE"], timeout=10)
160        if ev is None:
161            raise Exception("P2P-PROV-DISC-FAILURE timeout on seeker side")
162
163        if handler:
164            handler(seeker, advertiser)
165
166        # Put seeker into a listen state, since we expect the deferred flow to
167        # continue.
168        seeker.p2p_ext_listen(500, 500)
169
170        if method == "100":
171            ev = advertiser.wait_global_event(["P2P-PROV-DISC-ENTER-PIN"],
172                                              timeout=10)
173            if ev is None:
174                raise Exception("P2P-PROV-DISC-ENTER-PIN timeout on advertiser side")
175            if addr0 not in ev:
176                raise Exception("Unknown peer " + addr0)
177            ev = seeker.wait_global_event(["P2P-PROV-DISC-SHOW-PIN"],
178                                          timeout=10)
179            if ev is None:
180                raise Exception("P2P-PROV-DISC-SHOW-PIN timeout on seeker side")
181            if addr1 not in ev:
182                raise Exception("Unknown peer " + addr1)
183            pin = ev.split()[2]
184        elif method == "8":
185            ev = advertiser.wait_global_event(["P2P-PROV-DISC-SHOW-PIN"],
186                                              timeout=10)
187            if ev is None:
188                raise Exception("P2P-PROV-DISC-SHOW-PIN timeout on advertiser side")
189            if addr0 not in ev:
190                raise Exception("Unknown peer " + addr0)
191            pin = ev.split()[2]
192
193        # Stop P2P_LISTEN before issuing P2P_ASP_PROVISION_RESP to avoid
194        # excessive delay and test case timeouts if it takes large number of
195        # retries to find the peer awake on its Listen channel.
196        advertiser.p2p_stop_find()
197
198        advertiser.asp_provision(peer, adv_id=advert_id, adv_mac=advert_mac,
199                                 session_id=int(session, 0),
200                                 session_mac=session_mac, status=12,
201                                 cpt=adv_cpt, role=adv_role)
202
203        ev1 = seeker.wait_global_event(["P2PS-PROV-DONE"], timeout=10)
204        if ev1 is None:
205            raise Exception("P2PS-PROV-DONE timeout on seeker side")
206
207        ev2 = advertiser.wait_global_event(["P2PS-PROV-DONE"], timeout=10)
208        if ev2 is None:
209            raise Exception("P2PS-PROV-DONE timeout on advertiser side")
210
211        if method == "8":
212            ev = seeker.wait_global_event(["P2P-PROV-DISC-ENTER-PIN"],
213                                          timeout=10)
214            if ev is None:
215                raise Exception("P2P-PROV-DISC-ENTER-PIN failed on seeker side")
216            if addr1 not in ev:
217                raise Exception("Unknown peer " + addr1)
218
219        seeker.p2p_cancel_ext_listen()
220        if pin is not None:
221            return ev1, ev2, pin
222        return ev1, ev2
223
224    # Auto-accept is true and the method is either P2PS or advertiser is DISPLAY
225    ev1 = seeker.wait_global_event(["P2PS-PROV-DONE"], timeout=10)
226    if ev1 is None:
227        raise Exception("P2PS-PROV-DONE timeout on seeker side")
228
229    ev2 = advertiser.wait_global_event(["P2PS-PROV-DONE"], timeout=10)
230    if ev2 is None:
231        raise Exception("P2PS-PROV-DONE timeout on advertiser side")
232
233    if method == "8":
234        ev = seeker.wait_global_event(["P2P-PROV-DISC-ENTER-PIN"], timeout=10)
235        if ev is None:
236            raise Exception("P2P-PROV-DISC-ENTER-PIN timeout on seeker side")
237        if addr1 not in ev:
238            raise Exception("Unknown peer " + addr1)
239        ev = advertiser.wait_global_event(["P2P-PROV-DISC-SHOW-PIN"],
240                                          timeout=10)
241        if ev is None:
242            raise Exception("P2P-PROV-DISC-SHOW-PIN timeout on advertiser side")
243        if addr0 not in ev:
244            raise Exception("Unknown peer " + addr0)
245        pin = ev.split()[2]
246        return ev1, ev2, pin
247
248    return ev1, ev2
249
250def p2ps_connect_pd(dev0, dev1, ev0, ev1, pin=None, join_extra="", go_ev=None):
251    conf_methods_map = {"8": "p2ps", "1": "display", "5": "keypad"}
252    peer0 = ev0.split()[1]
253    peer1 = ev1.split()[1]
254    status0, conncap0, adv_id0, adv_mac0, mac0, session0, dev_passwd_id0, go0, join0, feature_cap0, persist0, group_ssid0 =\
255        p2ps_parse_event(ev0, "status", "conncap", "adv_id", "adv_mac", "mac", "session", "dev_passwd_id", "go", "join", "feature_cap", "persist", "group_ssid")
256    status1, conncap1, adv_id1, adv_mac1, mac1, session1, dev_passwd_id1, go1, join1, feature_cap1, persist1, group_ssid1 =\
257        p2ps_parse_event(ev1, "status", "conncap", "adv_id", "adv_mac", "mac", "session", "dev_passwd_id", "go", "join", "feature_cap", "persist", "group_ssid")
258
259    if status0 != "0" and status0 != "12":
260        raise Exception("PD failed on " + dev0.p2p_dev_addr())
261
262    if status1 != "0" and status1 != "12":
263        raise Exception("PD failed on " + dev1.p2p_dev_addr())
264
265    if status0 == "12" and status1 == "12":
266        raise Exception("Both sides have status 12 which doesn't make sense")
267
268    if adv_id0 != adv_id1 or adv_id0 is None:
269        raise Exception("Adv. IDs don't match")
270
271    if adv_mac0 != adv_mac1 or adv_mac0 is None:
272        raise Exception("Adv. MACs don't match")
273
274    if session0 != session1 or session0 is None:
275        raise Exception("Session IDs don't match")
276
277    if mac0 != mac1 or mac0 is None:
278        raise Exception("Session MACs don't match")
279
280    #TODO: Validate feature capability
281
282    if bool(persist0) != bool(persist1):
283        raise Exception("Only one peer has persistent group")
284
285    if persist0 is None and not all([conncap0, conncap1, dev_passwd_id0,
286                                     dev_passwd_id1]):
287        raise Exception("Persistent group not used but conncap/dev_passwd_id are missing")
288
289    if persist0 is not None and any([conncap0, conncap1, dev_passwd_id0,
290                                     dev_passwd_id1]):
291        raise Exception("Persistent group is used but conncap/dev_passwd_id are present")
292
293    # Persistent Connection (todo: handle frequency)
294    if persist0 is not None:
295        dev0.p2p_stop_find()
296        if "OK" not in dev0.global_request("P2P_GROUP_ADD persistent=" + persist0 + " freq=2412"):
297            raise Exception("Could not re-start persistent group")
298        ev0 = dev0.wait_global_event(["P2P-GROUP-STARTED"], timeout=10)
299        if ev0 is None:
300            raise Exception("P2P-GROUP-STARTED timeout on " + dev0.p2p_dev_addr())
301        dev0.group_form_result(ev0)
302
303        if "OK" not in dev1.global_request("P2P_GROUP_ADD persistent=" + persist1 + " freq=2412"):
304            raise Exception("Could not re-start persistent group")
305        ev1 = dev1.wait_global_event(["P2P-GROUP-STARTED"], timeout=10)
306        if ev1 is None:
307            raise Exception("P2P-GROUP-STARTED timeout on " + dev1.p2p_dev_addr())
308        dev1.group_form_result(ev1)
309        if "GO" in ev0:
310            ev = dev0.wait_global_event(["AP-STA-CONNECTED"], timeout=10)
311            if ev is None:
312                raise Exception("AP-STA-CONNECTED timeout on " + dev0.p2p_dev_addr())
313        else:
314            ev = dev1.wait_global_event(["AP-STA-CONNECTED"], timeout=10)
315            if ev is None:
316                raise Exception("AP-STA-CONNECTED timeout on " + dev1.p2p_dev_addr())
317    else:
318        try:
319            method0 = conf_methods_map[dev_passwd_id0]
320            method1 = conf_methods_map[dev_passwd_id1]
321        except KeyError:
322            raise Exception("Unsupported method")
323
324        if method0 == "p2ps":
325            pin = "12345670"
326        if pin is None:
327            raise Exception("Pin is not provided")
328
329        if conncap0 == "1" and conncap1 == "1": # NEW/NEW - GON
330            if any([join0, join1, go0, go1]):
331                raise Exception("Unexpected join/go PD attributes")
332            dev0.p2p_listen()
333            if "OK" not in dev0.global_request("P2P_CONNECT " + peer0 + " " + pin + " " + method0 + " persistent auth"):
334                raise Exception("P2P_CONNECT fails on " + dev0.p2p_dev_addr())
335            if "OK" not in dev1.global_request("P2P_CONNECT " + peer1 + " " + pin + " " + method1 + " persistent"):
336                raise Exception("P2P_CONNECT fails on " + dev1.p2p_dev_addr())
337            ev = dev0.wait_global_event(["P2P-GO-NEG-SUCCESS"], timeout=10)
338            if ev is None:
339                raise Exception("GO Neg did not succeed on " + dev0.p2p_dev_addr())
340            ev = dev1.wait_global_event(["P2P-GO-NEG-SUCCESS"], timeout=10)
341            if ev is None:
342                raise Exception("GO Neg did not succeed on " + dev1.p2p_dev_addr())
343            ev = dev0.wait_global_event(["P2P-GROUP-STARTED"], timeout=10)
344            if ev is None:
345                raise Exception("P2P-GROUP-STARTED timeout on " + dev0.p2p_dev_addr())
346            dev0.group_form_result(ev)
347            ev = dev1.wait_global_event(["P2P-GROUP-STARTED"], timeout=10)
348            if ev is None:
349                raise Exception("P2P-GROUP-STARTED timeout on " + dev1.p2p_dev_addr())
350            dev1.group_form_result(ev)
351        else:
352            if conncap0 == "2" and conncap1 == "4":  # dev0 CLI, dev1 GO
353                dev_cli, dev_go, go_if, join_address, go_method, cli_method, join_ssid = dev0, dev1, go1, join0, method1, method0, group_ssid0
354            elif conncap0 == "4" and conncap1 == "2":  # dev0 GO, dev1 CLI
355                dev_cli, dev_go, go_if, join_address, go_method, cli_method, join_ssid = dev1, dev0, go0, join1, method0, method1, group_ssid1
356            else:
357                raise Exception("Bad connection capabilities")
358
359            if go_if is None:
360                raise Exception("Device " + dev_go.p2p_dev_addr() + " failed to become GO")
361            if join_address is None:
362                raise Exception("Device " + dev_cli.p2p_dev_addr() + " failed to become CLI")
363
364            if not dev_go.get_group_ifname().startswith('p2p-'):
365                if go_ev:
366                    ev = go_ev
367                else:
368                    ev = dev_go.wait_global_event(["P2P-GROUP-STARTED"],
369                                                  timeout=10)
370                if ev is None:
371                    raise Exception("P2P-GROUP-STARTED timeout on " + dev_go.p2p_dev_addr())
372                dev_go.group_form_result(ev)
373
374            if go_method != "p2ps":
375                ev = dev_go.group_request("WPS_PIN any " + pin)
376                if ev is None:
377                    raise Exception("Failed to initiate pin authorization on registrar side")
378            if join_ssid:
379                group_ssid_txt = " ssid=" + join_ssid
380            else:
381                group_ssid_txt = ""
382            if "OK" not in dev_cli.global_request("P2P_CONNECT " + join_address + " " + pin + " " + cli_method + join_extra + " persistent join" + group_ssid_txt):
383                raise Exception("P2P_CONNECT failed on " + dev_cli.p2p_dev_addr())
384            ev = dev_cli.wait_global_event(["P2P-GROUP-STARTED"], timeout=10)
385            if ev is None:
386                raise Exception("P2P-GROUP-STARTED timeout on " + dev_cli.p2p_dev_addr())
387            dev_cli.group_form_result(ev)
388            ev = dev_go.wait_global_event(["AP-STA-CONNECTED"], timeout=10)
389            if ev is None:
390                raise Exception("AP-STA-CONNECTED timeout on " + dev_go.p2p_dev_addr())
391
392    hwsim_utils.test_connectivity_p2p(dev0, dev1)
393
394def set_no_group_iface(dev, enable):
395    if enable:
396        res = dev.get_driver_status()
397        if (int(res['capa.flags'], 0) & 0x20000000):
398            raise HwsimSkip("P2P Device used. Cannot set enable no_group_iface")
399        dev.global_request("SET p2p_no_group_iface 1")
400    else:
401        dev.global_request("SET p2p_no_group_iface 0")
402
403@remote_compatible
404def test_p2ps_exact_search(dev):
405    """P2PS exact service request"""
406    p2ps_advertise(r_dev=dev[0], r_role='1', svc_name='org.wi-fi.wfds.send.rx',
407                   srv_info='I can receive files upto size 2 GB')
408    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
409                                              svc_name='org.wi-fi.wfds.send.rx')
410
411    ev0 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
412    if ev0 is None:
413        raise Exception("Unable to remove the advertisement instance")
414
415@remote_compatible
416def test_p2ps_exact_search_srvinfo(dev):
417    """P2PS exact service request with service info"""
418    p2ps_advertise(r_dev=dev[0], r_role='0', svc_name='org.wi-fi.wfds.send.rx',
419                   srv_info='I can receive files upto size 2 GB')
420    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
421                                              svc_name='org.wi-fi.wfds.send.rx',
422                                              srv_info='2 GB')
423
424    ev0 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
425    if ev0 is None:
426        raise Exception("Unable to remove the advertisement instance")
427
428@remote_compatible
429def test_p2ps_nonexact_search(dev):
430    """P2PS nonexact seek request"""
431    p2ps_advertise(r_dev=dev[0], r_role='0', svc_name='org.wi-fi.wfds.play.rx',
432                   srv_info='I support Miracast Mode ')
433    ev_list = p2ps_nonexact_seek(i_dev=dev[1], r_dev=dev[0],
434                                 svc_name='org.wi-fi.wfds.play*')
435    adv_id = ev_list[0].split()[0]
436
437    ev0 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
438    if ev0 is None:
439        raise Exception("Unable to remove the advertisement instance")
440
441@remote_compatible
442def test_p2ps_nonexact_search_srvinfo(dev):
443    """P2PS nonexact seek request with service info"""
444    p2ps_advertise(r_dev=dev[0], r_role='0', svc_name='org.wi-fi.wfds.send.rx',
445                   srv_info='I can receive files upto size 2 GB')
446    ev_list = p2ps_nonexact_seek(i_dev=dev[1], r_dev=dev[0],
447                                 svc_name='org.wi-fi.wfds.send*',
448                                 srv_info='2 GB')
449    adv_id = ev_list[0].split()[0]
450    ev0 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
451    if ev0 is None:
452        raise Exception("Unable to remove the advertisement instance")
453
454@remote_compatible
455def test_p2ps_connect_p2ps_method_nonautoaccept(dev):
456    """P2PS connect for non-auto-accept and P2PS config method"""
457    p2ps_advertise(r_dev=dev[0], r_role='0', svc_name='org.wi-fi.wfds.send.rx',
458                   srv_info='I can receive files upto size 2 GB')
459    ev_list = p2ps_nonexact_seek(i_dev=dev[1], r_dev=dev[0],
460                                 svc_name='org.wi-fi.wfds.send*',
461                                 srv_info='2 GB')
462    adv_id = ev_list[0].split()[0]
463    ev1, ev0 = p2ps_provision(dev[1], dev[0], adv_id, auto_accept=False)
464    p2ps_connect_pd(dev[0], dev[1], ev0, ev1)
465
466    ev0 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
467    if ev0 is None:
468        raise Exception("Unable to remove the advertisement instance")
469    remove_group(dev[0], dev[1])
470
471@remote_compatible
472def test_p2ps_connect_p2ps_method_autoaccept(dev):
473    """P2PS connection with P2PS default config method and auto-accept"""
474    p2ps_advertise(r_dev=dev[0], r_role='1', svc_name='org.wi-fi.wfds.send.rx',
475                   srv_info='I can receive files upto size 2 GB')
476    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
477                                              svc_name='org.wi-fi.wfds.send.rx',
478                                              srv_info='2 GB')
479
480    ev1, ev0 = p2ps_provision(dev[1], dev[0], adv_id)
481    p2ps_connect_pd(dev[0], dev[1], ev0, ev1)
482
483    ev0 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
484    if ev0 is None:
485        raise Exception("Unable to remove the advertisement instance")
486    remove_group(dev[0], dev[1])
487
488@remote_compatible
489def test_p2ps_connect_keypad_method_nonautoaccept(dev):
490    """P2PS Connection with non-auto-accept and seeker having keypad method"""
491    p2ps_advertise(r_dev=dev[0], r_role='0', svc_name='org.wi-fi.wfds.send.rx',
492                   srv_info='I can receive files upto size 2 GB')
493    ev_list = p2ps_nonexact_seek(i_dev=dev[1], r_dev=dev[0],
494                                 svc_name='org.wi-fi.wfds.send*',
495                                 srv_info='2 GB')
496    adv_id = ev_list[0].split()[0]
497
498    ev1, ev0, pin = p2ps_provision(dev[1], dev[0], adv_id, auto_accept=False, method="8")
499    p2ps_connect_pd(dev[0], dev[1], ev0, ev1, pin)
500
501    ev0 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
502    if ev0 is None:
503        raise Exception("Unable to remove the advertisement instance")
504    remove_group(dev[0], dev[1])
505
506@remote_compatible
507def test_p2ps_connect_display_method_nonautoaccept(dev):
508    """P2PS connection with non-auto-accept and seeker having display method"""
509    p2ps_advertise(r_dev=dev[0], r_role='0', svc_name='org.wi-fi.wfds.send.rx',
510                   srv_info='I can receive files upto size 2 GB')
511    ev_list = p2ps_nonexact_seek(i_dev=dev[1], r_dev=dev[0],
512                                 svc_name='org.wi-fi.wfds*', srv_info='2 GB')
513    adv_id = ev_list[0].split()[0]
514
515    ev1, ev0, pin = p2ps_provision(dev[1], dev[0], adv_id, auto_accept=False, method="100")
516    p2ps_connect_pd(dev[0], dev[1], ev0, ev1, pin)
517
518    ev0 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
519    if ev0 is None:
520        raise Exception("Unable to remove the advertisement instance")
521    remove_group(dev[0], dev[1])
522
523@remote_compatible
524def test_p2ps_connect_keypad_method_autoaccept(dev):
525    """P2PS connection with auto-accept and keypad method on seeker side"""
526    p2ps_advertise(r_dev=dev[0], r_role='1', svc_name='org.wi-fi.wfds.send.rx',
527                   srv_info='I can receive files upto size 2 GB')
528    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
529                                              svc_name='org.wi-fi.wfds.send.rx',
530                                              srv_info='2 GB')
531
532    ev1, ev0, pin = p2ps_provision(dev[1], dev[0], adv_id, method="8")
533    p2ps_connect_pd(dev[0], dev[1], ev0, ev1, pin)
534
535    ev0 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
536    if ev0 is None:
537        raise Exception("Unable to remove the advertisement instance")
538    remove_group(dev[0], dev[1])
539
540@remote_compatible
541def test_p2ps_connect_display_method_autoaccept(dev):
542    """P2PS connection with auto-accept and display method on seeker side"""
543    p2ps_advertise(r_dev=dev[0], r_role='1', svc_name='org.wi-fi.wfds.send.rx',
544                   srv_info='I can receive files upto size 2 GB')
545    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
546                                              svc_name='org.wi-fi.wfds.send.rx',
547                                              srv_info='2 GB')
548
549    ev1, ev0, pin = p2ps_provision(dev[1], dev[0], adv_id, method="100")
550    p2ps_connect_pd(dev[0], dev[1], ev0, ev1, pin)
551
552    ev0 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
553    if ev0 is None:
554        raise Exception("Unable to remove the advertisement instance")
555    remove_group(dev[0], dev[1])
556
557@remote_compatible
558def test_p2ps_connect_adv_go_p2ps_method(dev):
559    """P2PS auto-accept connection with advertisement as GO and P2PS method"""
560    p2ps_advertise(r_dev=dev[0], r_role='4', svc_name='org.wi-fi.wfds.send.rx',
561                   srv_info='I can receive files upto size 2 GB')
562    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
563                                              svc_name='org.wi-fi.wfds.send.rx',
564                                              srv_info='2 GB')
565
566    ev1, ev0 = p2ps_provision(dev[1], dev[0], adv_id)
567    p2ps_connect_pd(dev[0], dev[1], ev0, ev1)
568
569    ev0 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
570    if ev0 is None:
571        raise Exception("Unable to remove the advertisement instance")
572    remove_group(dev[0], dev[1])
573
574@remote_compatible
575def test_p2ps_connect_adv_go_p2ps_method_group_iface(dev):
576    """P2PS auto-accept connection with advertisement as GO and P2PS method using separate group interface"""
577    set_no_group_iface(dev[0], 0)
578    set_no_group_iface(dev[1], 0)
579    p2ps_advertise(r_dev=dev[0], r_role='4', svc_name='org.wi-fi.wfds.send.rx',
580                   srv_info='I can receive files upto size 2 GB')
581    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
582                                              svc_name='org.wi-fi.wfds.send.rx',
583                                              srv_info='2 GB')
584
585    ev1, ev0 = p2ps_provision(dev[1], dev[0], adv_id)
586    p2ps_connect_pd(dev[0], dev[1], ev0, ev1)
587
588    ev0 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
589    if ev0 is None:
590        raise Exception("Unable to remove the advertisement instance")
591    remove_group(dev[0], dev[1])
592
593@remote_compatible
594def test_p2ps_connect_adv_client_p2ps_method(dev):
595    """P2PS auto-accept connection with advertisement as Client and P2PS method"""
596    p2ps_advertise(r_dev=dev[0], r_role='2', svc_name='org.wi-fi.wfds.send.rx',
597                   srv_info='I can receive files upto size 2 GB')
598    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
599                                              svc_name='org.wi-fi.wfds.send.rx',
600                                              srv_info='2 GB')
601
602    ev1, ev0 = p2ps_provision(dev[1], dev[0], adv_id)
603    p2ps_connect_pd(dev[0], dev[1], ev0, ev1)
604
605    ev0 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
606    if ev0 is None:
607        raise Exception("Unable to remove the advertisement instance")
608    remove_group(dev[0], dev[1])
609
610def p2ps_connect_adv_go_pin_method(dev, keep_group=False):
611    p2ps_advertise(r_dev=dev[0], r_role='4', svc_name='org.wi-fi.wfds.send.rx',
612                   srv_info='I can receive files upto size 2 GB')
613    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
614                                              svc_name='org.wi-fi.wfds.send.rx',
615                                              srv_info='2 GB')
616    ev1, ev0, pin = p2ps_provision(dev[1], dev[0], adv_id, method="8")
617    p2ps_connect_pd(dev[0], dev[1], ev0, ev1, pin)
618
619    if not keep_group:
620        ev0 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
621        if ev0 is None:
622            raise Exception("Unable to remove the advertisement instance")
623        remove_group(dev[0], dev[1])
624
625@remote_compatible
626def test_p2ps_connect_adv_go_pin_method(dev):
627    """P2PS advertiser as GO with keypad config method on seeker side and auto-accept"""
628    p2ps_connect_adv_go_pin_method(dev)
629
630@remote_compatible
631def test_p2ps_connect_adv_client_pin_method(dev):
632    """P2PS advertiser as client with keypad config method on seeker side and auto-accept"""
633    dev[0].flush_scan_cache()
634    p2ps_advertise(r_dev=dev[0], r_role='2', svc_name='org.wi-fi.wfds.send.rx',
635                   srv_info='I can receive files upto size 2 GB')
636    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
637                                              svc_name='org.wi-fi.wfds.send.rx',
638                                              srv_info='2 GB')
639
640    ev1, ev0, pin = p2ps_provision(dev[1], dev[0], adv_id, method="8")
641    p2ps_connect_pd(dev[0], dev[1], ev0, ev1, pin)
642
643    ev0 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
644    if ev0 is None:
645        raise Exception("Unable to remove the advertisement instance")
646    remove_group(dev[0], dev[1])
647
648def test_p2ps_service_discovery_multiple_queries(dev):
649    """P2P service discovery with multiple queries"""
650    addr0 = dev[0].p2p_dev_addr()
651    addr1 = dev[1].p2p_dev_addr()
652    adv_id1 = p2ps_advertise(r_dev=dev[0], r_role='0',
653                             svc_name='org.wi-fi.wfds.send.tx',
654                             srv_info='I can transfer files upto size of 2 GB')
655    adv_id2 = p2ps_advertise(r_dev=dev[0], r_role='0',
656                             svc_name='org.wi-fi.wfds.send.rx',
657                             srv_info='I can receive files upto size of 2 GB')
658    adv_id3 = p2ps_advertise(r_dev=dev[0], r_role='1',
659                             svc_name='org.wi-fi.wfds.display.tx',
660                             srv_info='Miracast Mode')
661    adv_id4 = p2ps_advertise(r_dev=dev[0], r_role='1',
662                             svc_name='org.wi-fi.wfds.display.rx',
663                             srv_info='Miracast Mode')
664
665    dev[1].global_request("P2P_SERV_DISC_REQ " + addr0 + " asp 1 org.wi-fi.wfds.display.tx 'Miracast Mode'")
666    dev[1].global_request("P2P_FIND 10 type=social seek=org.wi-fi.wfds.display.tx")
667    dev[1].global_request("P2P_SERV_DISC_REQ " + addr0 + " asp 2 org.wi-fi.wfds.send* 'size of 2 GB'")
668    dev[1].p2p_stop_find()
669    dev[1].global_request("P2P_FIND 10 type=social seek=")
670    ev = dev[1].wait_global_event(["P2P-DEVICE-FOUND"], timeout=10)
671    if ev is None:
672        raise Exception("P2P Device Found timed out")
673    if addr0 not in ev:
674        raise Exception("Unexpected service discovery request source")
675    ev_list = []
676    for i in range(0, 3):
677        ev = dev[1].wait_global_event(["P2P-SERV-ASP-RESP"], timeout=10)
678        if ev is None:
679            raise Exception("P2P Service discovery timed out")
680        if addr0 in ev:
681            ev_list.append(ev)
682            if len(ev_list) == 3:
683                break
684    dev[1].p2p_stop_find()
685
686    for test in [("seek=org.wi-fi.wfds.display.TX",
687                  "asp_svc=org.wi-fi.wfds.display.tx"),
688                 ("seek=foo seek=org.wi-fi.wfds.display.tx seek=bar",
689                  "asp_svc=org.wi-fi.wfds.display.tx"),
690                 ("seek=1 seek=2 seek=3 seek=org.wi-fi.wfds.display.tx seek=4 seek=5 seek=6",
691                  "asp_svc=org.wi-fi.wfds.display.tx"),
692                 ("seek=not-found", None),
693                 ("seek=org.wi-fi.wfds", "asp_svc=org.wi-fi.wfds")]:
694        dev[2].global_request("P2P_FIND 10 type=social " + test[0])
695        if test[1] is None:
696            ev = dev[2].wait_global_event(["P2P-DEVICE-FOUND"], timeout=1)
697            if ev is not None:
698                raise Exception("Unexpected device found: " + ev)
699            continue
700        ev = dev[2].wait_global_event(["P2P-DEVICE-FOUND"], timeout=10)
701        if ev is None:
702            raise Exception("P2P device discovery timed out (dev2)")
703            if test[1] not in ev:
704                raise Exception("Expected asp_svc not reported: " + ev)
705        dev[2].p2p_stop_find()
706        dev[2].request("P2P_FLUSH")
707
708    dev[0].p2p_stop_find()
709
710    ev1 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id1))
711    if ev1 is None:
712        raise Exception("Unable to remove the advertisement instance")
713    ev2 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id2))
714    if ev2 is None:
715        raise Exception("Unable to remove the advertisement instance")
716    ev3 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id3))
717    if ev3 is None:
718        raise Exception("Unable to remove the advertisement instance")
719    ev4 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id4))
720    if ev4 is None:
721        raise Exception("Unable to remove the advertisement instance")
722
723    if "OK" not in dev[0].global_request("P2P_SERVICE_ADD asp 1 12345678 1 1108 org.wi-fi.wfds.foobar svc_info='Test'"):
724        raise Exception("P2P_SERVICE_ADD failed")
725    if "OK" not in dev[0].global_request("P2P_SERVICE_DEL asp all"):
726        raise Exception("P2P_SERVICE_DEL asp all failed")
727    if "OK" not in dev[0].global_request("P2P_SERVICE_ADD asp 1 12345678 1 1108 org.wi-fi.wfds.foobar svc_info='Test'"):
728        raise Exception("P2P_SERVICE_ADD failed")
729    if "OK" not in dev[0].global_request("P2P_SERVICE_REP asp 1 12345678 1 1108 org.wi-fi.wfds.foobar svc_info='Test'"):
730        raise Exception("P2P_SERVICE_REP failed")
731    if "FAIL" not in dev[0].global_request("P2P_SERVICE_REP asp 1 12345678 1 1108 org.wi-fi.wfds.Foo svc_info='Test'"):
732        raise Exception("Invalid P2P_SERVICE_REP accepted")
733    if "OK" not in dev[0].global_request("P2P_SERVICE_ADD asp 1 a2345678 1 1108 org.wi-fi.wfds.something svc_info='Test'"):
734        raise Exception("P2P_SERVICE_ADD failed")
735    if "OK" not in dev[0].global_request("P2P_SERVICE_ADD asp 1 a2345679 1 1108 org.wi-fi.wfds.Foo svc_info='Test'"):
736        raise Exception("P2P_SERVICE_ADD failed")
737
738def get_ifnames():
739    with open('/proc/net/dev', 'r') as f:
740        data = f.read()
741    ifnames = []
742    for line in data.splitlines():
743        ifname = line.strip().split(' ')[0]
744        if ':' not in ifname:
745            continue
746        ifname = ifname.split(':')[0]
747        ifnames.append(ifname)
748    return ifnames
749
750def p2ps_connect_p2ps_method(dev, keep_group=False, join_extra="", flush=True):
751    if flush:
752        dev[0].flush_scan_cache()
753        dev[1].flush_scan_cache()
754    p2ps_advertise(r_dev=dev[0], r_role='2', svc_name='org.wi-fi.wfds.send.rx',
755                   srv_info='I can receive files upto size 2 GB')
756    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
757                                              svc_name='org.wi-fi.wfds.send.rx',
758                                              srv_info='2 GB')
759    ev1, ev0 = p2ps_provision(dev[1], dev[0], adv_id)
760    go_ev = None
761    if "join=" in ev0 and "go=" in ev1:
762        # dev[1] started GO and dev[0] is about to join it.
763        # Parse P2P-GROUP-STARTED from the GO to learn the operating frequency.
764        go_ev = dev[1].wait_global_event(["P2P-GROUP-STARTED"], timeout=10)
765        if go_ev is None:
766            raise Exception("P2P-GROUP-STARTED timeout on dev1")
767        res = dev[1].group_form_result(go_ev)
768        if join_extra == "":
769            join_extra = " freq=" + res['freq']
770
771    ifnames = get_ifnames()
772    p2ps_connect_pd(dev[0], dev[1], ev0, ev1, join_extra=join_extra,
773                    go_ev=go_ev)
774
775    grp_ifname0 = dev[0].get_group_ifname()
776    grp_ifname1 = dev[1].get_group_ifname()
777    if not keep_group:
778        ev0 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
779        if ev0 is None:
780            raise Exception("Unable to remove the advertisement instance")
781        ifnames = ifnames + get_ifnames()
782        remove_group(dev[0], dev[1])
783        ifnames = ifnames + get_ifnames()
784
785    return grp_ifname0, grp_ifname1, ifnames
786
787def has_string_prefix(vals, prefix):
788    for val in vals:
789        if val.startswith(prefix):
790            return True
791    return False
792
793def test_p2ps_connect_p2ps_method_1(dev):
794    """P2PS connection with P2PS method - no group interface"""
795    set_no_group_iface(dev[0], 1)
796    set_no_group_iface(dev[1], 1)
797
798    (grp_ifname0, grp_ifname1, ifnames) = p2ps_connect_p2ps_method(dev)
799    if grp_ifname0 != dev[0].ifname:
800        raise Exception("unexpected dev0 group ifname: " + grp_ifname0)
801    if grp_ifname1 != dev[1].ifname:
802        raise Exception("unexpected dev1 group ifname: " + grp_ifname1)
803    if has_string_prefix(ifnames, 'p2p-' + grp_ifname0):
804        raise Exception("dev0 group interface unexpectedly present")
805    if has_string_prefix(ifnames, 'p2p-' + grp_ifname1):
806        raise Exception("dev1 group interface unexpectedly present")
807
808def test_p2ps_connect_p2ps_method_2(dev):
809    """P2PS connection with P2PS method - group interface on dev0"""
810    set_no_group_iface(dev[0], 0)
811    set_no_group_iface(dev[1], 1)
812
813    (grp_ifname0, grp_ifname1, ifnames) = p2ps_connect_p2ps_method(dev)
814    if not grp_ifname0.startswith('p2p-' + dev[0].ifname + '-'):
815        raise Exception("unexpected dev0 group ifname: " + grp_ifname0)
816    if grp_ifname1 != dev[1].ifname:
817        raise Exception("unexpected dev1 group ifname: " + grp_ifname1)
818    if has_string_prefix(ifnames, 'p2p-' + grp_ifname0):
819        raise Exception("dev0 group interface unexpectedly present")
820
821def test_p2ps_connect_p2ps_method_3(dev):
822    """P2PS connection with P2PS method - group interface on dev1"""
823    set_no_group_iface(dev[0], 1)
824    set_no_group_iface(dev[1], 0)
825
826    (grp_ifname0, grp_ifname1, ifnames) = p2ps_connect_p2ps_method(dev)
827    if grp_ifname0 != dev[0].ifname:
828        raise Exception("unexpected dev0 group ifname: " + grp_ifname0)
829    if not grp_ifname1.startswith('p2p-' + dev[1].ifname + '-'):
830        raise Exception("unexpected dev1 group ifname: " + grp_ifname1)
831    if has_string_prefix(ifnames, 'p2p-' + grp_ifname0):
832        raise Exception("dev0 group interface unexpectedly present")
833
834def test_p2ps_connect_p2ps_method_4(dev):
835    """P2PS connection with P2PS method - group interface on both"""
836    set_no_group_iface(dev[0], 0)
837    set_no_group_iface(dev[1], 0)
838
839    (grp_ifname0, grp_ifname1, ifnames) = p2ps_connect_p2ps_method(dev)
840    if not grp_ifname0.startswith('p2p-' + dev[0].ifname + '-'):
841        raise Exception("unexpected dev0 group ifname: " + grp_ifname0)
842    if not grp_ifname1.startswith('p2p-' + dev[1].ifname + '-'):
843        raise Exception("unexpected dev1 group ifname: " + grp_ifname1)
844
845def test_p2ps_connect_adv_go_persistent(dev):
846    """P2PS auto-accept connection with advertisement as GO and having persistent group"""
847    go_neg_pin_authorized_persistent(i_dev=dev[0], i_intent=15,
848                                     r_dev=dev[1], r_intent=0)
849    dev[0].remove_group()
850    dev[1].wait_go_ending_session()
851
852    p2ps_advertise(r_dev=dev[0], r_role='4', svc_name='org.wi-fi.wfds.send.rx',
853                   srv_info='I can receive files upto size 2 GB')
854    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
855                                              svc_name='org.wi-fi.wfds.send.rx',
856                                              srv_info='2 GB')
857    ev1, ev0 = p2ps_provision(dev[1], dev[0], adv_id)
858    if "persist=" not in ev0 or "persist=" not in ev1:
859        raise Exception("Persistent group isn't used by peers")
860
861    p2ps_connect_pd(dev[0], dev[1], ev0, ev1)
862    remove_group(dev[0], dev[1])
863
864def test_p2ps_stale_group_removal(dev):
865    """P2PS stale group removal"""
866    ssid_1 = go_neg_pin_authorized_persistent(i_dev=dev[0], i_intent=15,
867                                              r_dev=dev[1], r_intent=0)[0]['ssid']
868    dev[0].remove_group()
869    dev[1].wait_go_ending_session()
870
871    # Drop the first persistent group on dev[1] and form new persistent groups
872    # on both devices.
873    dev[1].p2pdev_request("FLUSH")
874    ssid_2 = go_neg_pin_authorized_persistent(i_dev=dev[0], i_intent=15,
875                                              r_dev=dev[1], r_intent=0)[0]['ssid']
876    dev[0].remove_group()
877    dev[1].wait_go_ending_session()
878
879    # The GO now has a stale persistent group as the first entry. Try to go
880    # through P2PS sequence to hit stale group removal.
881    # Only a single entry in the unlikely event that the SSIDs are equal
882    if len(dev[0].list_networks(p2p=True)) != 2 if ssid_1 != ssid_2 else 1:
883        raise Exception("Unexpected number of networks on dev[0]")
884    if len(dev[1].list_networks(p2p=True)) != 1:
885        raise Exception("Unexpected number of networks on dev[1]")
886
887    p2ps_advertise(r_dev=dev[0], r_role='4', svc_name='org.wi-fi.wfds.send.rx',
888                   srv_info='I can receive files upto size 2 GB')
889    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
890                                              svc_name='org.wi-fi.wfds.send.rx',
891                                              srv_info='2 GB')
892    ev1, ev0 = p2ps_provision(dev[1], dev[0], adv_id)
893    if "persist=" not in ev0 or "persist=" not in ev1:
894        raise Exception("Persistent group isn't used by peers")
895
896    p2ps_connect_pd(dev[0], dev[1], ev0, ev1)
897    remove_group(dev[0], dev[1])
898
899    if len(dev[0].list_networks(p2p=True)) != 1:
900        raise Exception("Unexpected number of networks on dev[0] (2)")
901    if len(dev[1].list_networks(p2p=True)) != 1:
902        raise Exception("Unexpected number of networks on dev[1] (2)")
903
904def test_p2ps_stale_group_removal2(dev):
905    """P2PS stale group removal (2)"""
906    ssid_1 = go_neg_pin_authorized_persistent(i_dev=dev[0], i_intent=0,
907                                              r_dev=dev[1], r_intent=15)[0]['ssid']
908    dev[1].remove_group()
909    dev[0].wait_go_ending_session()
910
911    # Drop the first persistent group on dev[1] and form new persistent groups
912    # on both devices.
913    dev[1].p2pdev_request("FLUSH")
914    ssid_2 = go_neg_pin_authorized_persistent(i_dev=dev[0], i_intent=0,
915                                              r_dev=dev[1], r_intent=15)[0]['ssid']
916    dev[1].remove_group()
917    dev[0].wait_go_ending_session()
918
919    # The P2P Client now has a stale persistent group as the first entry. Try
920    # to go through P2PS sequence to hit stale group removal.
921    # Only a single entry in the unlikely event that the SSIDs are equal
922    if len(dev[0].list_networks(p2p=True)) != 2 if ssid_1 != ssid_2 else 1:
923        raise Exception("Unexpected number of networks on dev[0]")
924    if len(dev[1].list_networks(p2p=True)) != 1:
925        raise Exception("Unexpected number of networks on dev[1]")
926
927    p2ps_advertise(r_dev=dev[1], r_role='4', svc_name='org.wi-fi.wfds.send.rx',
928                   srv_info='I can receive files upto size 2 GB')
929    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[0], r_dev=dev[1],
930                                              svc_name='org.wi-fi.wfds.send.rx',
931                                              srv_info='2 GB')
932    ev0, ev1 = p2ps_provision(dev[0], dev[1], adv_id)
933    # This hits persistent group removal on dev[0] (P2P Client)
934
935def test_p2ps_stale_group_removal3(dev):
936    """P2PS stale group removal (3)"""
937    dev[0].p2p_start_go(persistent=True)
938    dev[0].remove_group()
939    if len(dev[0].list_networks(p2p=True)) != 1:
940        raise Exception("Unexpected number of networks on dev[0]")
941
942    go_neg_pin_authorized_persistent(i_dev=dev[0], i_intent=15,
943                                     r_dev=dev[1], r_intent=0)
944    dev[0].remove_group()
945    dev[1].wait_go_ending_session()
946
947    # The GO now has a stale persistent group as the first entry. Try to go
948    # through P2PS sequence to hit stale group removal.
949    if len(dev[0].list_networks(p2p=True)) != 2:
950        raise Exception("Unexpected number of networks on dev[0] (2)")
951    if len(dev[1].list_networks(p2p=True)) != 1:
952        raise Exception("Unexpected number of networks on dev[1] (2)")
953
954    p2ps_advertise(r_dev=dev[0], r_role='4', svc_name='org.wi-fi.wfds.send.rx',
955                   srv_info='I can receive files upto size 2 GB')
956    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
957                                              svc_name='org.wi-fi.wfds.send.rx',
958                                              srv_info='2 GB')
959    ev1, ev0 = p2ps_provision(dev[1], dev[0], adv_id)
960    if "persist=" not in ev0 or "persist=" not in ev1:
961        raise Exception("Persistent group isn't used by peers")
962
963    p2ps_connect_pd(dev[0], dev[1], ev0, ev1)
964    remove_group(dev[0], dev[1])
965
966    if len(dev[0].list_networks(p2p=True)) != 1:
967        raise Exception("Unexpected number of networks on dev[0] (3)")
968    if len(dev[1].list_networks(p2p=True)) != 1:
969        raise Exception("Unexpected number of networks on dev[1] (3)")
970
971@remote_compatible
972def test_p2ps_adv_go_persistent_no_peer_entry(dev):
973    """P2PS advertisement as GO having persistent group (no peer entry)"""
974    go_neg_pin_authorized_persistent(i_dev=dev[0], i_intent=15,
975                                     r_dev=dev[1], r_intent=0)
976    dev[0].remove_group()
977    dev[1].wait_go_ending_session()
978
979    p2ps_advertise(r_dev=dev[0], r_role='4', svc_name='org.wi-fi.wfds.send.rx',
980                   srv_info='I can receive files upto size 2 GB')
981    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
982                                              svc_name='org.wi-fi.wfds.send.rx',
983                                              srv_info='2 GB')
984    dev[0].global_request("P2P_FLUSH")
985    dev[0].p2p_listen()
986    ev1, ev0 = p2ps_provision(dev[1], dev[0], adv_id)
987    if "persist=" not in ev0 or "persist=" not in ev1:
988        raise Exception("Persistent group isn't used by peers")
989
990@remote_compatible
991def test_p2ps_pd_follow_on_status_failure(dev):
992    """P2PS PD follow on request with status 11"""
993    addr0 = dev[0].p2p_dev_addr()
994    addr1 = dev[1].p2p_dev_addr()
995
996    p2ps_advertise(r_dev=dev[0], r_role='0', svc_name='org.wi-fi.wfds.send.rx',
997                   srv_info='I can receive files upto size 2 GB')
998    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
999                                              svc_name='org.wi-fi.wfds.send.rx',
1000                                              srv_info='2 GB')
1001    dev[1].asp_provision(addr0, adv_id=str(adv_id), adv_mac=addr0,
1002                         session_id=1, session_mac=addr1)
1003    ev_pd_start = dev[0].wait_global_event(["P2PS-PROV-START"], timeout=10)
1004    if ev_pd_start is None:
1005        raise Exception("P2PS-PROV-START timeout on Advertiser side")
1006    ev = dev[1].wait_global_event(["P2P-PROV-DISC-FAILURE"], timeout=10)
1007    if ev is None:
1008        raise Exception("P2P-PROV-DISC-FAILURE timeout on seeker side")
1009    dev[1].p2p_ext_listen(500, 500)
1010    dev[0].p2p_stop_find()
1011    dev[0].asp_provision(addr1, adv_id=str(adv_id), adv_mac=addr0, session_id=1,
1012                         session_mac=addr1, status=11, method=0)
1013
1014    ev = dev[1].wait_global_event(["P2PS-PROV-DONE"], timeout=10)
1015    if ev is None:
1016        raise Exception("P2P-PROV-DONE timeout on seeker side")
1017    if adv_id not in ev:
1018        raise Exception("P2P-PROV-DONE without adv_id on seeker side")
1019    if "status=11" not in ev:
1020        raise Exception("P2P-PROV-DONE without status on seeker side")
1021
1022    ev = dev[0].wait_global_event(["P2PS-PROV-DONE"], timeout=10)
1023    if ev is None:
1024        raise Exception("P2P-PROV-DONE timeout on advertiser side")
1025    if adv_id not in ev:
1026        raise Exception("P2P-PROV-DONE without adv_id on advertiser side")
1027    if "status=11" not in ev:
1028        raise Exception("P2P-PROV-DONE without status on advertiser side")
1029
1030def test_p2ps_client_probe(dev):
1031    """P2PS CLI discoverability on operating channel"""
1032    cli_probe = dev[0].global_request("SET p2p_cli_probe 1")
1033    p2ps_connect_p2ps_method(dev, keep_group=True)
1034    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[2], r_dev=dev[0],
1035                                              svc_name='org.wi-fi.wfds.send.rx',
1036                                              single_peer_expected=False)
1037    dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
1038    remove_group(dev[0], dev[1])
1039
1040def test_p2ps_go_probe(dev):
1041    """P2PS GO discoverability on operating channel"""
1042    p2ps_connect_adv_go_pin_method(dev, keep_group=True)
1043    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[2], r_dev=dev[0],
1044                                              svc_name='org.wi-fi.wfds.send.rx',
1045                                              single_peer_expected=False)
1046    dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
1047    remove_group(dev[0], dev[1])
1048
1049@remote_compatible
1050def test_p2ps_wildcard_p2ps(dev):
1051    """P2PS wildcard SD Probe Request/Response"""
1052    p2ps_wildcard = "org.wi-fi.wfds"
1053
1054    adv_id = p2ps_advertise(r_dev=dev[0], r_role='1',
1055                            svc_name='org.foo.service',
1056                            srv_info='I can do stuff')
1057    adv_id2 = p2ps_advertise(r_dev=dev[0], r_role='1',
1058                             svc_name='org.wi-fi.wfds.send.rx',
1059                             srv_info='I can receive files upto size 2 GB')
1060
1061    if "OK" not in dev[1].global_request("P2P_FIND 10 type=social seek=org.foo.service seek=" + p2ps_wildcard):
1062        raise Exception("Failed on P2P_FIND command")
1063
1064    ev1 = dev[1].wait_global_event(["P2P-DEVICE-FOUND"], timeout=10)
1065    if ev1 is None:
1066        raise Exception("P2P-DEVICE-FOUND timeout on seeker side")
1067    if dev[0].p2p_dev_addr() not in ev1:
1068        raise Exception("Unexpected peer")
1069
1070    ev2 = dev[1].wait_global_event(["P2P-DEVICE-FOUND"], timeout=10)
1071    if ev2 is None:
1072        raise Exception("P2P-DEVICE-FOUND timeout on seeker side (2)")
1073    if dev[0].p2p_dev_addr() not in ev2:
1074        raise Exception("Unexpected peer (2)")
1075
1076    if p2ps_wildcard not in ev1 + ev2:
1077        raise Exception("P2PS Wildcard name not found in P2P-DEVICE-FOUND event")
1078    if "org.foo.service" not in ev1 + ev2:
1079        raise Exception("Vendor specific service name not found in P2P-DEVICE-FOUND event")
1080
1081    if "OK" not in dev[1].global_request("P2P_STOP_FIND"):
1082        raise Exception("P2P_STOP_FIND failed")
1083    dev[1].dump_monitor()
1084
1085    res = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
1086    if res is None:
1087        raise Exception("Unable to remove the advertisement instance")
1088
1089    if "OK" not in dev[1].global_request("P2P_FIND 10 type=social seek=" + p2ps_wildcard):
1090        raise Exception("Failed on P2P_FIND command")
1091
1092    ev1 = dev[1].wait_global_event(["P2P-DEVICE-FOUND"], timeout=10)
1093    if ev1 is None:
1094        raise Exception("P2P-DEVICE-FOUND timeout on seeker side")
1095    if dev[0].p2p_dev_addr() not in ev1:
1096        raise Exception("Unexpected peer")
1097    if p2ps_wildcard not in ev1:
1098        raise Exception("P2PS Wildcard name not found in P2P-DEVICE-FOUND event (2)")
1099    dev[1].dump_monitor()
1100
1101    res = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id2))
1102    if res is None:
1103        raise Exception("Unable to remove the advertisement instance 2")
1104
1105    dev[1].p2p_stop_find()
1106    time.sleep(0.1)
1107    if "OK" not in dev[1].global_request("P2P_FIND 10 type=social seek=" + p2ps_wildcard):
1108        raise Exception("Failed on P2P_FIND command")
1109
1110    ev1 = dev[1].wait_global_event(["P2P-DEVICE-FOUND"], timeout=2)
1111    if ev1 is not None:
1112        raise Exception("Unexpected P2P-DEVICE-FOUND event on seeker side")
1113    dev[1].p2p_stop_find()
1114    dev[1].dump_monitor()
1115
1116def test_p2ps_many_services_in_probe(dev):
1117    """P2PS with large number of services in Probe Request/Response"""
1118    long1 = 'org.example.0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.a'
1119    long2 = 'org.example.0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.b'
1120    long3 = 'org.example.0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.c'
1121    long4 = 'org.example.0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.d'
1122    long5 = 'org.example.0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.e'
1123    for name in [long1, long2, long3, long4, long5]:
1124        p2ps_advertise(r_dev=dev[0], r_role='1',
1125                       svc_name=name,
1126                       srv_info='I can do stuff')
1127
1128    if "OK" not in dev[1].global_request("P2P_FIND 10 type=social seek=%s seek=%s seek=%s seek=%s seek=%s" % (long1, long2, long3, long4, long5)):
1129        raise Exception("Failed on P2P_FIND command")
1130
1131    events = ""
1132    # Note: Require only four events since all the services do not fit within
1133    # the length limit.
1134    for i in range(4):
1135        ev = dev[1].wait_global_event(["P2P-DEVICE-FOUND"], timeout=10)
1136        if ev is None:
1137            raise Exception("Missing P2P-DEVICE-FOUND")
1138        events = events + ev
1139    dev[1].p2p_stop_find()
1140    dev[1].dump_monitor()
1141    for name in [long2, long3, long4, long5]:
1142        if name not in events:
1143            raise Exception("Service missing from peer events")
1144
1145def p2ps_test_feature_capability_cpt(dev, adv_cpt, seeker_cpt, adv_role,
1146                                     result):
1147    p2ps_advertise(r_dev=dev[0], r_role=adv_role,
1148                   svc_name='org.wi-fi.wfds.send.rx',
1149                   srv_info='I can receive files upto size 2 GB', cpt=adv_cpt)
1150    [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
1151                                              svc_name='org.wi-fi.wfds.send.rx',
1152                                              srv_info='2 GB')
1153    auto_accept = adv_role != "0"
1154    ev1, ev0, pin = p2ps_provision(dev[1], dev[0], adv_id,
1155                                   auto_accept=auto_accept, adv_cpt=adv_cpt,
1156                                   seeker_cpt=seeker_cpt, method="8")
1157
1158    status0, fcap0 = p2ps_parse_event(ev0, "status", "feature_cap")
1159    status1, fcap1 = p2ps_parse_event(ev0, "status", "feature_cap")
1160
1161    if fcap0 is None:
1162        raise Exception("Bad feature capability on Seeker side")
1163    if fcap1 is None:
1164        raise Exception("Bad feature capability on Advertiser side")
1165    if fcap0 != fcap1:
1166        raise Exception("Incompatible feature capability values")
1167
1168    if status0 not in ("0", "12") or status1 not in ("0", "12"):
1169        raise Exception("Unexpected PD result status")
1170
1171    if result == "UDP" and fcap0[1] != "1":
1172        raise Exception("Unexpected CPT feature capability value (expected: UDP)")
1173    elif result == "MAC" and fcap0[1] != "2":
1174        raise Exception("Unexpected CPT feature capability value (expected: MAC)")
1175
1176    ev = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
1177    if ev is None:
1178        raise Exception("Unable to remove the advertisement instance")
1179
1180@remote_compatible
1181def test_p2ps_feature_capability_mac_autoaccept(dev):
1182    """P2PS PD Feature Capability CPT: advertiser MAC, seeker UDP:MAC, autoaccept"""
1183    p2ps_test_feature_capability_cpt(dev, adv_cpt="MAC", seeker_cpt="UDP:MAC",
1184                                     adv_role="4", result="MAC")
1185
1186@remote_compatible
1187def test_p2ps_feature_capability_mac_nonautoaccept(dev):
1188    """P2PS PD Feature Capability CPT: advertiser:MAC, seeker UDP:MAC, nonautoaccept"""
1189    p2ps_test_feature_capability_cpt(dev, adv_cpt="MAC", seeker_cpt="UDP:MAC",
1190                                     adv_role="0", result="MAC")
1191
1192@remote_compatible
1193def test_p2ps_feature_capability_mac_udp_autoaccept(dev):
1194    """P2PS PD Feature Capability CPT: advertiser MAC:UDP, seeker UDP:MAC, autoaccept"""
1195    p2ps_test_feature_capability_cpt(dev, adv_cpt="MAC:UDP",
1196                                     seeker_cpt="UDP:MAC", adv_role="2",
1197                                     result="MAC")
1198
1199@remote_compatible
1200def test_p2ps_feature_capability_mac_udp_nonautoaccept(dev):
1201    """P2PS PD Feature Capability CPT: advertiser MAC:UDP, seeker UDP:MAC, nonautoaccept"""
1202    p2ps_test_feature_capability_cpt(dev, adv_cpt="MAC:UDP",
1203                                     seeker_cpt="UDP:MAC", adv_role="0",
1204                                     result="UDP")
1205
1206@remote_compatible
1207def test_p2ps_feature_capability_udp_mac_autoaccept(dev):
1208    """P2PS PD Feature Capability CPT: advertiser UDP:MAC, seeker MAC:UDP, autoaccept"""
1209    p2ps_test_feature_capability_cpt(dev, adv_cpt="UDP:MAC",
1210                                     seeker_cpt="MAC:UDP", adv_role="2",
1211                                     result="UDP")
1212
1213@remote_compatible
1214def test_p2ps_feature_capability_udp_mac_nonautoaccept(dev):
1215    """P2PS PD Feature Capability CPT: advertiser UDP:MAC, seeker MAC:UDP,  nonautoaccept"""
1216    p2ps_test_feature_capability_cpt(dev, adv_cpt="UDP:MAC",
1217                                     seeker_cpt="MAC:UDP", adv_role="0",
1218                                     result="MAC")
1219
1220def test_p2ps_channel_one_connected(dev, apdev):
1221    """P2PS connection with P2PS method - one of the stations connected"""
1222    set_no_group_iface(dev[0], 0)
1223    set_no_group_iface(dev[1], 0)
1224
1225    try:
1226        hapd = hostapd.add_ap(apdev[0],
1227                              {"ssid": 'bss-2.4ghz', "channel": '7'})
1228        dev[1].connect("bss-2.4ghz", key_mgmt="NONE", scan_freq="2442")
1229
1230        (grp_ifname0, grp_ifname1, ifnames) = p2ps_connect_p2ps_method(dev, keep_group=True, join_extra=" freq=2442")
1231        freq = dev[0].get_group_status_field('freq')
1232
1233        if freq != '2442':
1234            raise Exception('Unexpected frequency for group 2442 != ' + freq)
1235    finally:
1236        dev[0].global_request("P2P_SERVICE_DEL asp all")
1237        remove_group(dev[0], dev[1])
1238
1239def set_random_listen_chan(dev):
1240    chan = random.randrange(0, 3) * 5 + 1
1241    dev.global_request("P2P_SET listen_channel %d" % chan)
1242
1243def test_p2ps_channel_both_connected_same(dev, apdev):
1244    """P2PS connection with P2PS method - stations connected on same channel"""
1245    set_no_group_iface(dev[2], 0)
1246    set_no_group_iface(dev[1], 0)
1247
1248    dev[2].global_request("P2P_SET listen_channel 6")
1249    dev[1].global_request("P2P_SET listen_channel 6")
1250
1251    dev[1].flush_scan_cache()
1252    dev[2].flush_scan_cache()
1253
1254    try:
1255        hapd = hostapd.add_ap(apdev[0],
1256                              {"ssid": 'bss-2.4ghz', "channel": '6'})
1257
1258        dev[2].connect("bss-2.4ghz", key_mgmt="NONE", scan_freq="2437")
1259        dev[1].connect("bss-2.4ghz", key_mgmt="NONE", scan_freq="2437")
1260
1261        tmpdev = [dev[2], dev[1]]
1262        (grp_ifname0, grp_ifname1, ifnames) = p2ps_connect_p2ps_method(tmpdev, keep_group=True, join_extra=" freq=2437", flush=False)
1263        freq = dev[2].get_group_status_field('freq')
1264
1265        if freq != '2437':
1266            raise Exception('Unexpected frequency for group 2437 != ' + freq)
1267    finally:
1268        dev[2].global_request("P2P_SERVICE_DEL asp all")
1269        for i in range(1, 3):
1270            set_random_listen_chan(dev[i])
1271        remove_group(dev[2], dev[1])
1272
1273def disconnect_handler(seeker, advertiser):
1274    advertiser.request("DISCONNECT")
1275    advertiser.wait_disconnected(timeout=1)
1276
1277def test_p2ps_channel_both_connected_different(dev, apdev):
1278    """P2PS connection with P2PS method - stations connected on different channel"""
1279    if dev[0].get_mcc() > 1:
1280        raise HwsimSkip('Skip due to MCC being enabled')
1281
1282    set_no_group_iface(dev[0], 0)
1283    set_no_group_iface(dev[1], 0)
1284
1285    try:
1286        hapd1 = hostapd.add_ap(apdev[0],
1287                               {"ssid": 'bss-channel-3', "channel": '3'})
1288
1289        hapd2 = hostapd.add_ap(apdev[1],
1290                               {"ssid": 'bss-channel-10', "channel": '10'})
1291
1292        dev[0].connect("bss-channel-3", key_mgmt="NONE", scan_freq="2422")
1293        dev[1].connect("bss-channel-10", key_mgmt="NONE", scan_freq="2457")
1294
1295        p2ps_advertise(r_dev=dev[0], r_role='2',
1296                       svc_name='org.wi-fi.wfds.send.rx',
1297                       srv_info='I can receive files upto size 2 GB')
1298        [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
1299                                                  svc_name='org.wi-fi.wfds.send.rx',
1300                                                  srv_info='2 GB')
1301
1302        ev1, ev0 = p2ps_provision(dev[1], dev[0], adv_id, auto_accept=False,
1303                                  handler=disconnect_handler)
1304        p2ps_connect_pd(dev[0], dev[1], ev0, ev1)
1305        freq = dev[0].get_group_status_field('freq')
1306        if freq != '2457':
1307            raise Exception('Unexpected frequency for group 2457 != ' + freq)
1308    finally:
1309        dev[0].global_request("P2P_SERVICE_DEL asp all")
1310        remove_group(dev[0], dev[1])
1311
1312def test_p2ps_channel_both_connected_different_mcc(dev, apdev):
1313    """P2PS connection with P2PS method - stations connected on different channels with mcc"""
1314    with HWSimRadio(n_channels=2) as (radio, iface):
1315        wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1316        wpas.interface_add(iface)
1317
1318        set_no_group_iface(wpas, 0)
1319        set_no_group_iface(dev[1], 0)
1320
1321        try:
1322            hapd1 = hostapd.add_ap(apdev[0],
1323                                   {"ssid": 'bss-channel-3', "channel": '3'})
1324
1325            hapd2 = hostapd.add_ap(apdev[1],
1326                                   {"ssid": 'bss-channel-10', "channel": '10'})
1327
1328            wpas.connect("bss-channel-3", key_mgmt="NONE", scan_freq="2422")
1329            dev[1].connect("bss-channel-10", key_mgmt="NONE", scan_freq="2457")
1330
1331            (grp_ifname0, grp_ifname1, ifnames) = p2ps_connect_p2ps_method([wpas, dev[1]], keep_group=True)
1332            freq = wpas.get_group_status_field('freq')
1333
1334            if freq != '2422' and freq != '2457':
1335                raise Exception('Unexpected frequency for group =' + freq)
1336        finally:
1337            wpas.global_request("P2P_SERVICE_DEL asp all")
1338            remove_group(wpas, dev[1])
1339
1340def clear_disallow_handler(seeker, advertiser):
1341    advertiser.global_request("P2P_SET disallow_freq ")
1342
1343@remote_compatible
1344def test_p2ps_channel_disallow_freq(dev, apdev):
1345    """P2PS connection with P2PS method - disallow freqs"""
1346    set_no_group_iface(dev[0], 0)
1347    set_no_group_iface(dev[1], 0)
1348
1349    try:
1350        dev[0].global_request("P2P_SET disallow_freq 2412-2457")
1351        dev[1].global_request("P2P_SET disallow_freq 2417-2462")
1352
1353        p2ps_advertise(r_dev=dev[0], r_role='2',
1354                       svc_name='org.wi-fi.wfds.send.rx',
1355                       srv_info='I can receive files upto size 2 GB')
1356
1357        [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
1358                                                  svc_name='org.wi-fi.wfds.send.rx',
1359                                                  srv_info='2 GB')
1360
1361        ev1, ev0 = p2ps_provision(dev[1], dev[0], adv_id, auto_accept=False,
1362                                  handler=clear_disallow_handler)
1363        p2ps_connect_pd(dev[0], dev[1], ev0, ev1)
1364
1365        freq = dev[0].get_group_status_field('freq')
1366        if freq != '2412':
1367            raise Exception('Unexpected frequency for group 2412 != ' + freq)
1368    finally:
1369        dev[0].global_request("P2P_SERVICE_DEL asp all")
1370        dev[0].global_request("P2P_SET disallow_freq ")
1371        dev[1].global_request("P2P_SET disallow_freq ")
1372        remove_group(dev[0], dev[1])
1373
1374def test_p2ps_channel_sta_connected_disallow_freq(dev, apdev):
1375    """P2PS connection with P2PS method - one station and disallow freqs"""
1376    if dev[0].get_mcc() > 1:
1377        raise HwsimSkip('Skip due to MCC being enabled')
1378
1379    set_no_group_iface(dev[0], 0)
1380    set_no_group_iface(dev[1], 0)
1381
1382    try:
1383        dev[0].global_request("P2P_SET disallow_freq 2437")
1384        hapd = hostapd.add_ap(apdev[0],
1385                              {"ssid": 'bss-channel-6', "channel": '6'})
1386
1387        dev[1].connect("bss-channel-6", key_mgmt="NONE", scan_freq="2437")
1388
1389        p2ps_advertise(r_dev=dev[0], r_role='2',
1390                       svc_name='org.wi-fi.wfds.send.rx',
1391                       srv_info='I can receive files upto size 2 GB')
1392        [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
1393                                                  svc_name='org.wi-fi.wfds.send.rx',
1394                                                  srv_info='2 GB')
1395
1396        ev1, ev0 = p2ps_provision(dev[1], dev[0], adv_id, auto_accept=False,
1397                                  handler=clear_disallow_handler)
1398        p2ps_connect_pd(dev[0], dev[1], ev0, ev1)
1399
1400        freq = dev[0].get_group_status_field('freq')
1401        if freq != '2437':
1402            raise Exception('Unexpected frequency for group 2437 != ' + freq)
1403    finally:
1404        dev[0].global_request("P2P_SET disallow_freq ")
1405        dev[0].global_request("P2P_SERVICE_DEL asp all")
1406        remove_group(dev[0], dev[1])
1407
1408def test_p2ps_channel_sta_connected_disallow_freq_mcc(dev, apdev):
1409    """P2PS connection with P2PS method - one station and disallow freqs with mcc"""
1410    with HWSimRadio(n_channels=2) as (radio, iface):
1411        wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1412        wpas.interface_add(iface)
1413
1414        if wpas.get_mcc() < 2:
1415            raise Exception("New radio does not support MCC")
1416
1417        set_no_group_iface(dev[0], 0)
1418        set_no_group_iface(wpas, 0)
1419
1420        try:
1421            dev[0].global_request("P2P_SET disallow_freq 2437")
1422            hapd1 = hostapd.add_ap(apdev[0],
1423                                   {"ssid": 'bss-channel-6', "channel": '6'})
1424
1425            wpas.connect("bss-channel-6", key_mgmt="NONE", scan_freq="2437")
1426
1427            tmpdev = [dev[0], wpas]
1428            (grp_ifname0, grp_ifname1, ifnames) = p2ps_connect_p2ps_method(tmpdev, keep_group=True)
1429
1430            freq = dev[0].get_group_status_field('freq')
1431            if freq == '2437':
1432                raise Exception('Unexpected frequency=2437')
1433        finally:
1434            dev[0].global_request("P2P_SET disallow_freq ")
1435            dev[0].global_request("P2P_SERVICE_DEL asp all")
1436            remove_group(dev[0], wpas)
1437
1438@remote_compatible
1439def test_p2ps_active_go_adv(dev, apdev):
1440    """P2PS connection with P2PS method - active GO on advertiser"""
1441    set_no_group_iface(dev[0], 0)
1442    set_no_group_iface(dev[1], 0)
1443
1444    try:
1445        # Add a P2P GO
1446        dev[0].global_request("P2P_GROUP_ADD persistent")
1447        ev = dev[0].wait_global_event(["P2P-GROUP-STARTED"], timeout=10)
1448        if ev is None:
1449            raise Exception("P2P-GROUP-STARTED timeout on " + dev[0].p2p_dev_addr())
1450
1451        dev[0].group_form_result(ev)
1452
1453        p2ps_advertise(r_dev=dev[0], r_role='4',
1454                       svc_name='org.wi-fi.wfds.send.rx',
1455                       srv_info='I can receive files upto size 2 GB')
1456        [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
1457                                                  svc_name='org.wi-fi.wfds.send.rx',
1458                                                  single_peer_expected=False)
1459
1460        ev1, ev0 = p2ps_provision(dev[1], dev[0], adv_id)
1461
1462        # explicitly stop find/listen as otherwise the long listen started by
1463        # the advertiser would prevent the seeker to connect with the P2P GO
1464        dev[0].p2p_stop_find()
1465        p2ps_connect_pd(dev[0], dev[1], ev0, ev1)
1466    finally:
1467        dev[0].global_request("P2P_SERVICE_DEL asp all")
1468        remove_group(dev[0], dev[1])
1469
1470@remote_compatible
1471def test_p2ps_active_go_seeker(dev, apdev):
1472    """P2PS connection with P2PS method - active GO on seeker"""
1473    set_no_group_iface(dev[0], 0)
1474    set_no_group_iface(dev[1], 0)
1475
1476    try:
1477        # Add a P2P GO on the seeker
1478        dev[1].global_request("P2P_GROUP_ADD persistent")
1479        ev = dev[1].wait_global_event(["P2P-GROUP-STARTED"], timeout=10)
1480        if ev is None:
1481            raise Exception("P2P-GROUP-STARTED timeout on " + dev[1].p2p_dev_addr())
1482
1483        res = dev[1].group_form_result(ev)
1484
1485        p2ps_advertise(r_dev=dev[0], r_role='2',
1486                       svc_name='org.wi-fi.wfds.send.rx',
1487                       srv_info='I can receive files upto size 2 GB')
1488        [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
1489                                                  svc_name='org.wi-fi.wfds.send.rx',
1490                                                  srv_info='2 GB')
1491
1492        ev1, ev0 = p2ps_provision(dev[1], dev[0], adv_id)
1493        p2ps_connect_pd(dev[0], dev[1], ev0, ev1,
1494                        join_extra=" freq=" + res['freq'])
1495    finally:
1496        dev[0].global_request("P2P_SERVICE_DEL asp all")
1497        remove_group(dev[0], dev[1])
1498
1499def test_p2ps_channel_active_go_and_station_same(dev, apdev):
1500    """P2PS connection, active P2P GO and station on channel"""
1501    set_no_group_iface(dev[2], 0)
1502    set_no_group_iface(dev[1], 0)
1503
1504    dev[2].global_request("P2P_SET listen_channel 11")
1505    dev[1].global_request("P2P_SET listen_channel 11")
1506    try:
1507        hapd = hostapd.add_ap(apdev[0],
1508                              {"ssid": 'bss-channel-11', "channel": '11'})
1509
1510        dev[2].connect("bss-channel-11", key_mgmt="NONE", scan_freq="2462")
1511
1512        # Add a P2P GO on the seeker
1513        dev[1].global_request("P2P_GROUP_ADD freq=2462 persistent")
1514        ev = dev[1].wait_global_event(["P2P-GROUP-STARTED"], timeout=10)
1515        if ev is None:
1516            raise Exception("P2P-GROUP-STARTED timeout on " + dev[1].p2p_dev_addr())
1517
1518        dev[1].group_form_result(ev)
1519
1520        p2ps_advertise(r_dev=dev[2], r_role='2',
1521                       svc_name='org.wi-fi.wfds.send.rx',
1522                       srv_info='I can receive files upto size 2 GB')
1523        [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[2],
1524                                                  svc_name='org.wi-fi.wfds.send.rx',
1525                                                  srv_info='2 GB')
1526
1527        ev1, ev0 = p2ps_provision(dev[1], dev[2], adv_id)
1528        p2ps_connect_pd(dev[2], dev[1], ev0, ev1, join_extra=" freq=2462")
1529    finally:
1530        dev[2].global_request("P2P_SERVICE_DEL asp all")
1531        for i in range(1, 3):
1532            set_random_listen_chan(dev[i])
1533        remove_group(dev[2], dev[1])
1534
1535def test_p2ps_channel_active_go_and_station_different(dev, apdev):
1536    """P2PS connection, active P2P GO and station on channel"""
1537    if dev[0].get_mcc() > 1:
1538        raise HwsimSkip('Skip due to MCC being enabled')
1539
1540    set_no_group_iface(dev[0], 0)
1541    set_no_group_iface(dev[1], 0)
1542
1543    try:
1544        hapd = hostapd.add_ap(apdev[0],
1545                              {"ssid": 'bss-channel-2', "channel": '2'})
1546
1547        dev[0].connect("bss-channel-2", key_mgmt="NONE", scan_freq="2417")
1548
1549        # Add a P2P GO on the seeker. Force the listen channel to be the same,
1550        # as extended listen will not kick as long as P2P GO is waiting for
1551        # initial connection.
1552        dev[1].global_request("P2P_SET listen_channel 11")
1553        dev[1].global_request("P2P_GROUP_ADD freq=2462 persistent")
1554        ev = dev[1].wait_global_event(["P2P-GROUP-STARTED"], timeout=10)
1555        if ev is None:
1556            raise Exception("P2P-GROUP-STARTED timeout on " + dev[1].p2p_dev_addr())
1557
1558        dev[1].group_form_result(ev)
1559
1560        p2ps_advertise(r_dev=dev[0], r_role='2',
1561                       svc_name='org.wi-fi.wfds.send.rx',
1562                       srv_info='I can receive files upto size 2 GB')
1563        [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=dev[0],
1564                                                  svc_name='org.wi-fi.wfds.send.rx',
1565                                                  srv_info='2 GB')
1566
1567        ev1, ev0 = p2ps_provision(dev[1], dev[0], adv_id, auto_accept=False,
1568                                  handler=disconnect_handler, adv_role='2',
1569                                  seeker_role='4')
1570        p2ps_connect_pd(dev[0], dev[1], ev0, ev1)
1571        freq = dev[0].get_group_status_field('freq')
1572        if freq != '2462':
1573            raise Exception('Unexpected frequency for group 2462!=' + freq)
1574    finally:
1575        dev[0].global_request("P2P_SERVICE_DEL asp all")
1576        set_random_listen_chan(dev[1])
1577
1578@remote_compatible
1579def test_p2ps_channel_active_go_and_station_different_mcc(dev, apdev):
1580    """P2PS connection, active P2P GO and station on channel"""
1581    with HWSimRadio(n_channels=2) as (radio, iface):
1582        wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1583        wpas.interface_add(iface)
1584
1585        set_no_group_iface(wpas, 0)
1586        set_no_group_iface(dev[1], 0)
1587
1588        try:
1589            hapd = hostapd.add_ap(apdev[0],
1590                                  {"ssid": 'bss-channel-6', "channel": '6'})
1591
1592            wpas.global_request("P2P_SET listen_channel 1")
1593            wpas.connect("bss-channel-6", key_mgmt="NONE", scan_freq="2437")
1594
1595            # Add a P2P GO on the seeker
1596            dev[1].global_request("P2P_SET listen_channel 1")
1597            dev[1].global_request("P2P_GROUP_ADD freq=2462 persistent")
1598            ev = dev[1].wait_global_event(["P2P-GROUP-STARTED"], timeout=10)
1599            if ev is None:
1600                raise Exception("P2P-GROUP-STARTED timeout on " + dev[1].p2p_dev_addr())
1601
1602            dev[1].group_form_result(ev)
1603
1604            p2ps_advertise(r_dev=wpas, r_role='2',
1605                           svc_name='org.wi-fi.wfds.send.rx',
1606                           srv_info='I can receive files upto size 2 GB')
1607            [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[1], r_dev=wpas,
1608                                                      svc_name='org.wi-fi.wfds.send.rx',
1609                                                      srv_info='2 GB')
1610
1611            ev1, ev0 = p2ps_provision(dev[1], wpas, adv_id)
1612            p2ps_connect_pd(wpas, dev[1], ev0, ev1)
1613        finally:
1614            set_random_listen_chan(dev[1])
1615            set_random_listen_chan(wpas)
1616            wpas.request("DISCONNECT")
1617            hapd.disable()
1618            wpas.global_request("P2P_SERVICE_DEL asp all")
1619            remove_group(wpas, dev[1], allow_failure=True)
1620
1621def test_p2ps_connect_p2p_device(dev):
1622    """P2PS connection using cfg80211 P2P Device"""
1623    run_p2ps_connect_p2p_device(dev, 0)
1624
1625def test_p2ps_connect_p2p_device_no_group_iface(dev):
1626    """P2PS connection using cfg80211 P2P Device (no separate group interface)"""
1627    run_p2ps_connect_p2p_device(dev, 1)
1628
1629def run_p2ps_connect_p2p_device(dev, no_group_iface):
1630    with HWSimRadio(use_p2p_device=True) as (radio, iface):
1631        wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1632        wpas.interface_add(iface)
1633        wpas.global_request("SET p2p_no_group_iface %d" % no_group_iface)
1634
1635        p2ps_advertise(r_dev=dev[0], r_role='1',
1636                       svc_name='org.wi-fi.wfds.send.rx',
1637                       srv_info='I can receive files upto size 2 GB')
1638        [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=wpas, r_dev=dev[0],
1639                                                  svc_name='org.wi-fi.wfds.send.rx',
1640                                                  srv_info='2 GB')
1641
1642        ev1, ev0 = p2ps_provision(wpas, dev[0], adv_id)
1643        p2ps_connect_pd(dev[0], wpas, ev0, ev1)
1644
1645        ev0 = dev[0].global_request("P2P_SERVICE_DEL asp " + str(adv_id))
1646        if ev0 is None:
1647            raise Exception("Unable to remove the advertisement instance")
1648        remove_group(dev[0], wpas)
1649
1650def test_p2ps_connect_p2p_device2(dev):
1651    """P2PS connection using cfg80211 P2P Device (reverse)"""
1652    run_p2ps_connect_p2p_device2(dev, 0)
1653
1654def test_p2ps_connect_p2p_device2_no_group_iface(dev):
1655    """P2PS connection using cfg80211 P2P Device (reverse) (no separate group interface)"""
1656    run_p2ps_connect_p2p_device2(dev, 1)
1657
1658def run_p2ps_connect_p2p_device2(dev, no_group_iface):
1659    with HWSimRadio(use_p2p_device=True) as (radio, iface):
1660        wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1661        wpas.interface_add(iface)
1662        wpas.global_request("SET p2p_no_group_iface %d" % no_group_iface)
1663
1664        p2ps_advertise(r_dev=wpas, r_role='1',
1665                       svc_name='org.wi-fi.wfds.send.rx',
1666                       srv_info='I can receive files upto size 2 GB')
1667        [adv_id, rcvd_svc_name] = p2ps_exact_seek(i_dev=dev[0], r_dev=wpas,
1668                                                  svc_name='org.wi-fi.wfds.send.rx',
1669                                                  srv_info='2 GB')
1670
1671        ev1, ev0 = p2ps_provision(dev[0], wpas, adv_id)
1672        p2ps_connect_pd(wpas, dev[0], ev0, ev1)
1673
1674        ev0 = wpas.global_request("P2P_SERVICE_DEL asp " + str(adv_id))
1675        if ev0 is None:
1676            raise Exception("Unable to remove the advertisement instance")
1677        remove_group(wpas, dev[0])
1678
1679@remote_compatible
1680def test_p2ps_connect_p2ps_method_no_pin(dev):
1681    """P2P group formation using P2PS method without specifying PIN"""
1682    dev[0].p2p_listen()
1683    dev[1].p2p_go_neg_auth(dev[0].p2p_dev_addr(), None, "p2ps", go_intent=15)
1684    dev[1].p2p_listen()
1685    i_res = dev[0].p2p_go_neg_init(dev[1].p2p_dev_addr(), None, "p2ps",
1686                                   timeout=20, go_intent=0)
1687    r_res = dev[1].p2p_go_neg_auth_result()
1688    logger.debug("i_res: " + str(i_res))
1689    logger.debug("r_res: " + str(r_res))
1690    check_grpform_results(i_res, r_res)
1691    remove_group(dev[0], dev[1])
1692